"memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "aho-corasick"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "alloc"
version = "0.0.0"
dependencies = [
- "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"core 0.0.0",
"rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_xorshift 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-std-workspace-core 1.0.0",
]
"toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "bstr"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "bufstream"
version = "0.1.4"
"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.25.0",
- "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-utils 0.6.5 (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.21 (registry+https://github.com/rust-lang/crates.io-index)",
"curl-sys 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)",
"glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"home 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "ignore 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ignore 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"im-rc 12.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"jobserver 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"compiletest_rs 0.3.22 (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.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-workspace-hack 1.0.0",
"rustc_tools_util 0.1.1",
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"pulldown-cmark 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex-syntax 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
[[package]]
name = "compiler_builtins"
-version = "0.1.12"
+version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
dependencies = [
"diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rustfix 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rustfix 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
[[package]]
name = "crossbeam-channel"
-version = "0.3.4"
+version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "crossbeam-epoch 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-epoch 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
dependencies = [
"arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
[[package]]
name = "crossbeam-utils"
-version = "0.6.2"
+version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-std-workspace-core 1.0.0",
]
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)",
"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)",
"atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"humantime 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)",
- "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
"atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"humantime 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)",
- "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-std-workspace-core 1.0.0",
]
[[package]]
name = "globset"
-version = "0.4.2"
+version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "aho-corasick 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bstr 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
"pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"pest_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
"quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
]
"pest 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pest_derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-std-workspace-alloc 1.0.0",
"rustc-std-workspace-core 1.0.0",
]
[[package]]
name = "ignore"
-version = "0.4.6"
+version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "crossbeam-channel 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "globset 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "globset 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
"memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)",
"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)",
name = "panic_abort"
version = "0.0.0"
dependencies = [
- "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"core 0.0.0",
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
]
version = "0.0.0"
dependencies = [
"alloc 0.0.0",
- "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"core 0.0.0",
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
"unwind 0.0.0",
version = "0.0.0"
dependencies = [
"cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"core 0.0.0",
]
"rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_chacha 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_xorshift 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex-syntax 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rusty-fork 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex"
-version = "1.1.0"
+version = "1.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "aho-corasick 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex-syntax 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex-syntax"
-version = "0.6.4"
+version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"cargo 0.37.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)",
+ "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"racer 2.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rls-analysis 0.17.0 (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.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-std-workspace-core 1.0.0",
]
"alloc 0.0.0",
"build_helper 0.1.0",
"cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"core 0.0.0",
]
"alloc 0.0.0",
"build_helper 0.1.0",
"cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"core 0.0.0",
]
"alloc 0.0.0",
"build_helper 0.1.0",
"cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"core 0.0.0",
]
"alloc 0.0.0",
"build_helper 0.1.0",
"cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"core 0.0.0",
]
"env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)",
- "ignore 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ignore 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-ap-rustc_target 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-ap-syntax 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-ap-syntax_pos 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
"alloc 0.0.0",
"backtrace-sys 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"core 0.0.0",
"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)",
name = "tidy"
version = "0.1.0"
dependencies = [
- "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
]
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
]
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "crossbeam-channel 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"is-match 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
version = "0.0.0"
dependencies = [
"cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiler_builtins 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"core 0.0.0",
"libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
]
dependencies = [
"same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
[[package]]
name = "winapi-util"
-version = "0.1.1"
+version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
[metadata]
"checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c"
"checksum aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9a933f4e58658d7b12defcf96dc5c720f20832deebe3e0a19efd3b6aaeeb9e"
+"checksum aho-corasick 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e6f484ae0c99fec2e858eb6134949117399f222608d84cadb3f58c1f97c2364c"
"checksum ammonia 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fd4c682378117e4186a492b2252b9537990e1617f44aed9788b9a1149de45477"
"checksum annotate-snippets 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e8bcdcd5b291ce85a78f2b9d082a8de9676c12b1840d386d67bc5eea6f9d2b4e"
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
"checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400"
"checksum block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab"
+"checksum bstr 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "853b090ce0f45d0265902666bf88039ea3da825e33796716c511a1ec9c170036"
"checksum bufstream 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "40e38929add23cdf8a366df9b0e088953150724bcbe5fc330b0d8eb3b328eec8"
"checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39"
"checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
"checksum colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b0aa3473e85a3161b59845d6096b289bb577874cafeaf75ea1b1beaa6572c7fc"
"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.12 (registry+https://github.com/rust-lang/crates.io-index)" = "6549720ae78db799196d4af8f719facb4c7946710b4b64148482553e54b56d15"
+"checksum compiler_builtins 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "e3f235c329e5cb9fa3d2ca2cc36256ba9a7f23fa76e0f4db6f68c23b73b2ac69"
"checksum compiletest_rs 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "f40ecc9332b68270998995c00f8051ee856121764a0d3230e64c9efd059d27b6"
"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"
"checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb"
"checksum crc32fast 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e91d5240c6975ef33aeb5f148f35275c25eda8e8a5f95abe421978b05b8bf192"
-"checksum crossbeam-channel 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5b2a9ea8f77c7f9efd317a8a5645f515d903a2d86ee14d2337a5facd1bd52c12"
+"checksum crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0f0ed1a4de2235cabda8558ff5840bffb97fcb64c97827f354a451307df5f72b"
"checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3"
"checksum crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "05e44b8cf3e1a625844d1750e1f7820da46044ff6d28f4d43e455ba3e5bb2c13"
"checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150"
"checksum crossbeam-epoch 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f10a4f8f409aaac4b16a5474fb233624238fcdeefb9ba50d5ea059aab63ba31c"
"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
-"checksum crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e07fc155212827475223f0bcfae57e945e694fc90950ddf3f6695bbfd5555c72"
+"checksum crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c"
"checksum crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "09de9ee0fc255ace04c7fa0763c9395a945c37c8292bb554f8d48361d1dcf1b4"
"checksum curl 0.4.21 (registry+https://github.com/rust-lang/crates.io-index)" = "a85f2f95f2bd277d316d1aa8a477687ab4a6942258c7db7c89c187534669979c"
"checksum curl-sys 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)" = "9d91a0052d5b982887d8e829bee0faffc7218ea3c6ebd3d6c2c8f678a93c9a42"
"checksum git2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7339329bfa14a00223244311560d11f8f489b453fb90092af97f267a6090ab0"
"checksum git2-curl 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d58551e903ed7e2d6fe3a2f3c7efa3a784ec29b19d0fbb035aaf0497c183fbdd"
"checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
-"checksum globset 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4743617a7464bbda3c8aec8558ff2f9429047e025771037df561d383337ff865"
+"checksum globset 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ef4feaabe24a0a658fd9cf4a9acf6ed284f045c77df0f49020ba3245cfb7b454"
"checksum handlebars 0.32.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d89ec99d1594f285d4590fc32bac5f75cdab383f1123d504d27862c644a807dd"
"checksum handlebars 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d82e5750d8027a97b9640e3fefa66bbaf852a35228e1c90790efd13c4b09c166"
"checksum hashbrown 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "570178d5e4952010d138b0f1d581271ff3a02406d990f887d1e87e3d6e43b0ac"
"checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114"
"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
"checksum if_chain 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4bac95d9aa0624e7b78187d6fb8ab012b41d9f6f54b1bcb61e61c4845f8357ec"
-"checksum ignore 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ad03ca67dc12474ecd91fdb94d758cbd20cb4e7a78ebe831df26a9b7511e1162"
+"checksum ignore 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8dc57fa12805f367736a38541ac1a9fc6a52812a0ca959b1d4d4b640a89eb002"
"checksum im-rc 12.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9460397452f537fd51808056ff209f4c4c4c9d20d42ae952f517708726284972"
"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08"
"checksum is-match 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7e5b386aef33a1c677be65237cb9d32c3f3ef56bd035949710c4bb13083eb053"
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
"checksum redox_users 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "214a97e49be64fd2c86f568dd0cb2c757d2cc53de95b273b6ad0a1c908482f26"
"checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384"
-"checksum regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37e7cbbd370869ce2e8dff25c7018702d10b21a20ef7135316f8daecd6c25b7f"
+"checksum regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8f0a0bcab2fd7d1d7c54fa9eae6f43eddeb9ce2e7352f8518a814a4f65d60c58"
"checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7"
-"checksum regex-syntax 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4e47a2ed29da7a9e1960e1639e7a982e6edc6d49be308a3b02daf511504a16d1"
+"checksum regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "dcfd8681eebe297b81d98498869d4aae052137651ad7b96822f09ceb690d0a96"
"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"
"checksum rls-analysis 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d53d49a28f75da9d02790d9256fecf6c0481e0871374326023c7a33131295579"
"checksum rls-blacklist 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b8ce1fdac03e138c4617ff87b194e1ff57a39bb985a044ccbd8673d30701e411"
"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
-"checksum winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "afc5508759c5bf4285e61feb862b6083c8480aec864fa17a81fdec6f69b461ab"
+"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
"checksum wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "561ed901ae465d6185fa7864d63fbd5720d0ef718366c9a4dc83cf6170d7e9ba"
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
+Version 1.35.0 (2019-05-23)
+==========================
+
+Language
+--------
+- [`FnOnce`, `FnMut`, and the `Fn` traits are now implemented for `Box<FnOnce>`,
+ `Box<FnMut>`, and `Box<Fn>` respectively.][59500]
+- [You can now coerce closures into unsafe function pointers.][59580] e.g.
+ ```rust
+ unsafe fn call_unsafe(func: unsafe fn()) {
+ func()
+ }
+
+ pub fn main() {
+ unsafe { call_unsafe(|| {}); }
+ }
+ ```
+
+
+Compiler
+--------
+- [Added the `armv6-unknown-freebsd-gnueabihf` and
+ `armv7-unknown-freebsd-gnueabihf` targets.][58080]
+- [Added the `wasm32-unknown-wasi` target.][59464]
+
+
+Libraries
+---------
+- [`Thread` will now show its ID in `Debug` output.][59460]
+- [`StdinLock`, `StdoutLock`, and `StderrLock` now implement `AsRawFd`.][59512]
+- [`alloc::System` now implements `Default`.][59451]
+- [Expanded `Debug` output (`{:#?}`) for structs now has a trailing comma on the
+ last field.][59076]
+- [`char::{ToLowercase, ToUppercase}` now
+ implement `ExactSizeIterator`.][58778]
+- [All `NonZero` numeric types now implement `FromStr`.][58717]
+- [Removed the `Read` trait bounds
+ on the `BufReader::{get_ref, get_mut, into_inner}` methods.][58423]
+- [You can now call the `dbg!` macro without any parameters to print the file
+ and line where it is called.][57847]
+- [In place ASCII case conversions are now up to 4× faster.][59283]
+ e.g. `str::make_ascii_lowercase`
+- [`hash_map::{OccupiedEntry, VacantEntry}` now implement `Sync`
+ and `Send`.][58369]
+
+Stabilized APIs
+---------------
+- [`f32::copysign`]
+- [`f64::copysign`]
+- [`RefCell::replace_with`]
+- [`RefCell::map_split`]
+- [`ptr::hash`]
+- [`Range::contains`]
+- [`RangeFrom::contains`]
+- [`RangeTo::contains`]
+- [`RangeInclusive::contains`]
+- [`RangeToInclusive::contains`]
+- [`Option::copied`]
+
+Cargo
+-----
+- [You can now set `cargo:rustc-cdylib-link-arg` at build time to pass custom
+ linker arguments when building a `cdylib`.][cargo/6298] Its usage is highly
+ platform specific.
+
+Misc
+----
+- [The Rust toolchain is now available natively for musl based distros.][58575]
+
+[59460]: https://github.com/rust-lang/rust/pull/59460/
+[59464]: https://github.com/rust-lang/rust/pull/59464/
+[59500]: https://github.com/rust-lang/rust/pull/59500/
+[59512]: https://github.com/rust-lang/rust/pull/59512/
+[59580]: https://github.com/rust-lang/rust/pull/59580/
+[59283]: https://github.com/rust-lang/rust/pull/59283/
+[59451]: https://github.com/rust-lang/rust/pull/59451/
+[59076]: https://github.com/rust-lang/rust/pull/59076/
+[58778]: https://github.com/rust-lang/rust/pull/58778/
+[58717]: https://github.com/rust-lang/rust/pull/58717/
+[58369]: https://github.com/rust-lang/rust/pull/58369/
+[58423]: https://github.com/rust-lang/rust/pull/58423/
+[58080]: https://github.com/rust-lang/rust/pull/58080/
+[57847]: https://github.com/rust-lang/rust/pull/57847/
+[58575]: https://github.com/rust-lang/rust/pull/58575
+[cargo/6298]: https://github.com/rust-lang/cargo/pull/6298/
+[`f32::copysign`]: https://doc.rust-lang.org/stable/std/primitive.f32.html#method.copysign
+[`f64::copysign`]: https://doc.rust-lang.org/stable/std/primitive.f64.html#method.copysign
+[`RefCell::replace_with`]: https://doc.rust-lang.org/stable/std/cell/struct.RefCell.html#method.replace_with
+[`RefCell::map_split`]: https://doc.rust-lang.org/stable/std/cell/struct.RefCell.html#method.map_split
+[`ptr::hash`]: https://doc.rust-lang.org/stable/std/ptr/fn.hash.html
+[`Range::contains`]: https://doc.rust-lang.org/std/ops/struct.Range.html#method.contains
+[`RangeFrom::contains`]: https://doc.rust-lang.org/std/ops/struct.RangeFrom.html#method.contains
+[`RangeTo::contains`]: https://doc.rust-lang.org/std/ops/struct.RangeTo.html#method.contains
+[`RangeInclusive::contains`]: https://doc.rust-lang.org/std/ops/struct.RangeInclusive.html#method.contains
+[`RangeToInclusive::contains`]: https://doc.rust-lang.org/std/ops/struct.RangeToInclusive.html#method.contains
+[`Option::copied`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.copied
+
Version 1.34.2 (2019-05-14)
===========================
* [Destabilize the `Error::type_id` function due to a security
- vulnerability][60785]
+ vulnerability][60785] ([CVE-2019-12083])
[60785]: https://github.com/rust-lang/rust/pull/60785
+[CVE-2019-12083]: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-12083
Version 1.34.1 (2019-04-25)
===========================
.arg("--manifest-path")
.arg(builder.src.join("src/liballoc/Cargo.toml"))
.arg("--features")
- .arg("compiler-builtins-mem");
+ .arg("compiler-builtins-mem compiler-builtins-c");
} else {
let features = builder.std_features();
target: self.target,
mode: "ui",
suite: "rustdoc-ui",
- path: None,
+ path: Some("src/test/rustdoc-ui"),
compare_mode: None,
})
}
check_dispatch $1 beta nomicon src/doc/nomicon
check_dispatch $1 beta reference src/doc/reference
check_dispatch $1 beta rust-by-example src/doc/rust-by-example
- check_dispatch $1 beta edition-guide src/doc/edition-guide
+ # Temporarily disabled until
+ # https://github.com/rust-lang/rust/issues/60459 is fixed.
+ # check_dispatch $1 beta edition-guide src/doc/edition-guide
check_dispatch $1 beta rls src/tools/rls
check_dispatch $1 beta rustfmt src/tools/rustfmt
check_dispatch $1 beta clippy-driver src/tools/clippy
-Subproject commit db919bc6bb9071566e9c4f05053672133eaac33e
+Subproject commit 29fe982990e43b9367be0ff47abc82fb2123fd03
-Subproject commit c413d42a207bd082f801ec0137c31b71e4bfed4c
+Subproject commit 581c6cccfaf995394ea9dcac362dc8e731c18558
-Subproject commit de3d55f521e657863df45260ebbca1b10527f662
+Subproject commit 9858872bd1b7dbba5ec27dc30d34eba00acd7ef9
-Subproject commit fb29b147be4d9a1f8e24aba753a7e1de537abf61
+Subproject commit c656171b749b7307f21371dd0d3278efee5573b8
-Subproject commit 2a2de9ce095979978ad7b582daecf94e4070b916
+Subproject commit 862b669c395822bb0938781d74f860e5762ad4fb
-Subproject commit 1ff0f8e018838a710ebc0cc1a7bf74ebe73ad9f1
+Subproject commit 811c697b232c611ed754d279ed20643a0c4096f6
-Subproject commit 99e1b1d53656be08654df399fc200584aebb50e4
+Subproject commit 3cb727b62b953d59b4360d39aa68b6dc8f157655
| edition-2018 | Lints that will be turned into errors in Rust 2018 | tyvar-behind-raw-pointer |
| rust-2018-idioms | Lints to nudge you toward idiomatic features of Rust 2018 | bare-trait-object, unreachable-pub |
| unused | These lints detect things being declared but not used | unused-imports, unused-variables, unused-assignments, dead-code, unused-mut, unreachable-code, unreachable-patterns, unused-must-use, unused-unsafe, path-statements, unused-attributes, unused-macros, unused-allocation, unused-doc-comment, unused-extern-crates, unused-features, unused-parens |
-| future-incompatible | Lints that detect code that has future-compatibility problems | private-in-public, pub-use-of-private-extern-crate, patterns-in-fns-without-body, safe-extern-statics, invalid-type-param-default, legacy-directory-ownership, legacy-imports, legacy-constructor-visibility, missing-fragment-specifier, illegal-floating-point-literal-pattern, anonymous-parameters, parenthesized-params-in-types-and-modules, late-bound-lifetime-arguments, safe-packed-borrows, incoherent-fundamental-impls, tyvar-behind-raw-pointer, unstable-name-collision |
+| future-incompatible | Lints that detect code that has future-compatibility problems | private-in-public, pub-use-of-private-extern-crate, patterns-in-fns-without-body, safe-extern-statics, invalid-type-param-default, legacy-directory-ownership, legacy-imports, legacy-constructor-visibility, missing-fragment-specifier, illegal-floating-point-literal-pattern, anonymous-parameters, parenthesized-params-in-types-and-modules, late-bound-lifetime-arguments, safe-packed-borrows, tyvar-behind-raw-pointer, unstable-name-collision |
Additionally, there's a `bad-style` lint group that's a deprecated alias for `nonstandard-style`.
Finally, you can also see the table above by invoking `rustc -W help`. This will give you the exact values for the specific
-compiler you have installed.
\ No newline at end of file
+compiler you have installed.
| ^^^^^^^^^^^^^^^^^^^^
|
```
-
-## incoherent-fundamental-impls
-
-This lint detects potentially-conflicting impls that were erroneously allowed. Some
-example code that triggers this lint:
-
-```rust,ignore
-pub trait Trait1<X> {
- type Output;
-}
-
-pub trait Trait2<X> {}
-
-pub struct A;
-
-impl<X, T> Trait1<X> for T where T: Trait2<X> {
- type Output = ();
-}
-
-impl<X> Trait1<Box<X>> for A {
- type Output = i32;
-}
-```
-
-This will produce:
-
-```text
-error: conflicting implementations of trait `Trait1<std::boxed::Box<_>>` for type `A`: (E0119)
- --> src/main.rs:13:1
- |
-9 | impl<X, T> Trait1<X> for T where T: Trait2<X> {
- | --------------------------------------------- first implementation here
-...
-13 | impl<X> Trait1<Box<X>> for A {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `A`
- |
- = note: #[deny(incoherent_fundamental_impls)] on by default
- = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
- = note: for more information, see issue #46205 <https://github.com/rust-lang/rust/issues/46205>
- = note: downstream crates may implement trait `Trait2<std::boxed::Box<_>>` for type `A`
-```
#![doc(issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/")]
```
+### `html_root_url`
+
+The `#[doc(html_root_url = "…")]` attribute value indicates the URL for
+generating links to external crates. When rustdoc needs to generate a link to
+an item in an external crate, it will first check if the extern crate has been
+documented locally on-disk, and if so link directly to it. Failing that, it
+will use the URL given by the `--extern-html-root-url` command-line flag if
+available. If that is not available, then it will use the `html_root_url`
+value in the extern crate if it is available. If that is not available, then
+the extern items will not be linked.
+
+```rust,ignore
+#![doc(html_root_url = "https://docs.rs/serde/1.0")]
+```
+
### `html_no_source`
By default, `rustdoc` will include the source code of your program, with links
`rustdoc` can also generate HTML from standalone Markdown files. Let's
give it a try: create a `README.md` file with these contents:
-```text
- # Docs
+````text
+# Docs
- This is a project to test out `rustdoc`.
+This is a project to test out `rustdoc`.
- [Here is a link!](https://www.rust-lang.org)
+[Here is a link!](https://www.rust-lang.org)
- ## Subheading
+## Subheading
- ```rust
- fn foo() -> i32 {
- 1 + 1
- }
- ```
+```rust
+fn foo() -> i32 {
+ 1 + 1
+}
```
+````
And call `rustdoc` on it:
<Item Name="[capacity]" ExcludeView="simple">buf.cap</Item>
<ArrayItems>
<Size>len</Size>
- <ValuePointer>buf.ptr.pointer.__0</ValuePointer>
+ <ValuePointer>buf.ptr.pointer</ValuePointer>
</ArrayItems>
</Expand>
</Type>
- <Type Name="alloc::vec_deque::VecDeque<*>">
+ <Type Name="alloc::collections::vec_deque::VecDeque<*>">
<DisplayString>{{ size={tail <= head ? head - tail : buf.cap - tail + head} }}</DisplayString>
<Expand>
<Item Name="[size]" ExcludeView="simple">tail <= head ? head - tail : buf.cap - tail + head</Item>
<If Condition="i == head">
<Break/>
</If>
- <Item>buf.ptr.pointer.__0 + i</Item>
+ <Item>buf.ptr.pointer[i]</Item>
<Exec>i = (i + 1 == buf.cap ? 0 : i + 1)</Exec>
</Loop>
</CustomListItems>
</Expand>
</Type>
- <Type Name="alloc::linked_list::LinkedList<*>">
+ <Type Name="alloc::collections::linked_list::LinkedList<*>">
<DisplayString>{{ size={len} }}</DisplayString>
<Expand>
<LinkedListItems>
<Size>len</Size>
- <HeadPointer>*(alloc::linked_list::Node<$T1> **)&head</HeadPointer>
- <NextPointer>*(alloc::linked_list::Node<$T1> **)&next</NextPointer>
+ <HeadPointer>*(alloc::collections::linked_list::Node<$T1> **)&head</HeadPointer>
+ <NextPointer>*(alloc::collections::linked_list::Node<$T1> **)&next</NextPointer>
<ValueNode>element</ValueNode>
</LinkedListItems>
</Expand>
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="core::ptr::Unique<*>">
- <DisplayString>{{ Unique {*pointer.__0} }}</DisplayString>
+ <DisplayString>{{ Unique {pointer} }}</DisplayString>
<Expand>
- <Item Name="[ptr]">pointer.__0</Item>
+ <Item Name="[ptr]">pointer</Item>
</Expand>
</Type>
<Type Name="core::ptr::Shared<*>">
- <DisplayString>{{ Shared {*pointer.__0} }}</DisplayString>
+ <DisplayString>{{ Shared {pointer} }}</DisplayString>
<Expand>
- <Item Name="[ptr]">pointer.__0</Item>
+ <Item Name="[ptr]">pointer</Item>
</Expand>
</Type>
<Type Name="core::option::Option<*>">
[features]
compiler-builtins-mem = ['compiler_builtins/mem']
+compiler-builtins-c = ["compiler_builtins/c"]
///
/// Note: while this type is unstable, the functionality it provides can be
/// accessed through the [free functions in `alloc`](index.html#functions).
+///
+/// [`Alloc`]: trait.Alloc.html
#[unstable(feature = "allocator_api", issue = "32838")]
#[derive(Copy, Clone, Default, Debug)]
pub struct Global;
///
/// See [`GlobalAlloc::alloc`].
///
+/// [`Global`]: struct.Global.html
+/// [`Alloc`]: trait.Alloc.html
+/// [`GlobalAlloc::alloc`]: trait.GlobalAlloc.html#tymethod.alloc
+///
/// # Examples
///
/// ```
/// # Safety
///
/// See [`GlobalAlloc::dealloc`].
+///
+/// [`Global`]: struct.Global.html
+/// [`Alloc`]: trait.Alloc.html
+/// [`GlobalAlloc::dealloc`]: trait.GlobalAlloc.html#tymethod.dealloc
#[stable(feature = "global_alloc", since = "1.28.0")]
#[inline]
pub unsafe fn dealloc(ptr: *mut u8, layout: Layout) {
/// # Safety
///
/// See [`GlobalAlloc::realloc`].
+///
+/// [`Global`]: struct.Global.html
+/// [`Alloc`]: trait.Alloc.html
+/// [`GlobalAlloc::realloc`]: trait.GlobalAlloc.html#method.realloc
#[stable(feature = "global_alloc", since = "1.28.0")]
#[inline]
pub unsafe fn realloc(ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
///
/// See [`GlobalAlloc::alloc_zeroed`].
///
+/// [`Global`]: struct.Global.html
+/// [`Alloc`]: trait.Alloc.html
+/// [`GlobalAlloc::alloc_zeroed`]: trait.GlobalAlloc.html#method.alloc_zeroed
+///
/// # Examples
///
/// ```
//! heap allocation in Rust. Boxes provide ownership for this allocation, and
//! drop their contents when they go out of scope.
//!
-//! For non-zero-sized values, a [`Box`] will use the [`Global`] allocator for
-//! its allocation. It is valid to convert both ways between a [`Box`] and a
-//! raw pointer allocated with the [`Global`] allocator, given that the
-//! [`Layout`] used with the allocator is correct for the type. More precisely,
-//! a `value: *mut T` that has been allocated with the [`Global`] allocator
-//! with `Layout::for_value(&*value)` may be converted into a box using
-//! `Box::<T>::from_raw(value)`. Conversely, the memory backing a `value: *mut
-//! T` obtained from `Box::<T>::into_raw` may be deallocated using the
-//! [`Global`] allocator with `Layout::for_value(&*value)`.
-//!
//! # Examples
//!
//! Move a value from the stack to the heap by creating a [`Box`]:
//! for a `Cons`. By introducing a `Box`, which has a defined size, we know how
//! big `Cons` needs to be.
//!
+//! # Memory layout
+//!
+//! For non-zero-sized values, a [`Box`] will use the [`Global`] allocator for
+//! its allocation. It is valid to convert both ways between a [`Box`] and a
+//! raw pointer allocated with the [`Global`] allocator, given that the
+//! [`Layout`] used with the allocator is correct for the type. More precisely,
+//! a `value: *mut T` that has been allocated with the [`Global`] allocator
+//! with `Layout::for_value(&*value)` may be converted into a box using
+//! `Box::<T>::from_raw(value)`. Conversely, the memory backing a `value: *mut
+//! T` obtained from `Box::<T>::into_raw` may be deallocated using the
+//! [`Global`] allocator with `Layout::for_value(&*value)`.
+//!
+//!
//! [dereferencing]: ../../std/ops/trait.Deref.html
//! [`Box`]: struct.Box.html
//! [`Global`]: ../alloc/struct.Global.html
///
/// After calling this function, the raw pointer is owned by the
/// resulting `Box`. Specifically, the `Box` destructor will call
- /// the destructor of `T` and free the allocated memory. Since the
- /// way `Box` allocates and releases memory is unspecified, the
- /// only valid pointer to pass to this function is the one taken
- /// from another `Box` via the [`Box::into_raw`] function.
+ /// the destructor of `T` and free the allocated memory. For this
+ /// to be safe, the memory must have been allocated in accordance
+ /// with the [memory layout] used by `Box` .
+ ///
+ /// # Safety
///
/// This function is unsafe because improper use may lead to
/// memory problems. For example, a double-free may occur if the
/// function is called twice on the same raw pointer.
///
- /// [`Box::into_raw`]: struct.Box.html#method.into_raw
- ///
/// # Examples
- ///
+ /// Recreate a `Box` which was previously converted to a raw pointer
+ /// using [`Box::into_raw`]:
/// ```
/// let x = Box::new(5);
/// let ptr = Box::into_raw(x);
/// let x = unsafe { Box::from_raw(ptr) };
/// ```
+ /// Manually create a `Box` from scratch by using the global allocator:
+ /// ```
+ /// use std::alloc::{alloc, Layout};
+ ///
+ /// unsafe {
+ /// let ptr = alloc(Layout::new::<i32>()) as *mut i32;
+ /// *ptr = 5;
+ /// let x = Box::from_raw(ptr);
+ /// }
+ /// ```
+ ///
+ /// [memory layout]: index.html#memory-layout
+ /// [`Layout`]: ../alloc/struct.Layout.html
+ /// [`Box::into_raw`]: struct.Box.html#method.into_raw
#[stable(feature = "box_raw", since = "1.4.0")]
#[inline]
pub unsafe fn from_raw(raw: *mut T) -> Self {
///
/// After calling this function, the caller is responsible for the
/// memory previously managed by the `Box`. In particular, the
- /// caller should properly destroy `T` and release the memory. The
- /// proper way to do so is to convert the raw pointer back into a
- /// `Box` with the [`Box::from_raw`] function.
+ /// caller should properly destroy `T` and release the memory, taking
+ /// into account the [memory layout] used by `Box`. The easiest way to
+ /// do this is to convert the raw pointer back into a `Box` with the
+ /// [`Box::from_raw`] function, allowing the `Box` destructor to perform
+ /// the cleanup.
///
/// Note: this is an associated function, which means that you have
/// to call it as `Box::into_raw(b)` instead of `b.into_raw()`. This
/// is so that there is no conflict with a method on the inner type.
///
- /// [`Box::from_raw`]: struct.Box.html#method.from_raw
- ///
/// # Examples
- ///
+ /// Converting the raw pointer back into a `Box` with [`Box::from_raw`]
+ /// for automatic cleanup:
/// ```
- /// let x = Box::new(5);
+ /// let x = Box::new(String::from("Hello"));
/// let ptr = Box::into_raw(x);
+ /// let x = unsafe { Box::from_raw(ptr) };
+ /// ```
+ /// Manual cleanup by explicitly running the destructor and deallocating
+ /// the memory:
/// ```
+ /// use std::alloc::{dealloc, Layout};
+ /// use std::ptr;
+ ///
+ /// let x = Box::new(String::from("Hello"));
+ /// let p = Box::into_raw(x);
+ /// unsafe {
+ /// ptr::drop_in_place(p);
+ /// dealloc(p as *mut u8, Layout::new::<String>());
+ /// }
+ /// ```
+ ///
+ /// [memory layout]: index.html#memory-layout
+ /// [`Box::from_raw`]: struct.Box.html#method.from_raw
#[stable(feature = "box_raw", since = "1.4.0")]
#[inline]
pub fn into_raw(b: Box<T>) -> *mut T {
/// After calling this function, the caller is responsible for the
/// memory previously managed by the `Box`. In particular, the
/// caller should properly destroy `T` and release the memory. The
- /// proper way to do so is to convert the `NonNull<T>` pointer
+ /// easiest way to do so is to convert the `NonNull<T>` pointer
/// into a raw pointer and back into a `Box` with the [`Box::from_raw`]
/// function.
///
/// fn main() {
/// let x = Box::new(5);
/// let ptr = Box::into_raw_non_null(x);
+ ///
+ /// // Clean up the memory by converting the NonNull pointer back
+ /// // into a Box and letting the Box be dropped.
+ /// let x = unsafe { Box::from_raw(ptr.as_ptr()) };
/// }
/// ```
#[unstable(feature = "box_into_raw_non_null", issue = "47336")]
/// assert_eq!(heap.pop(), Some(Reverse(5)));
/// assert_eq!(heap.pop(), None);
/// ```
+///
+/// # Time complexity
+///
+/// | [push] | [pop] | [peek]/[peek\_mut] |
+/// |--------|----------|--------------------|
+/// | O(1)~ | O(log n) | O(1) |
+///
+/// The value for `push` is an expected cost; the method documentation gives a
+/// more detailed analysis.
+///
+/// [push]: #method.push
+/// [pop]: #method.pop
+/// [peek]: #method.peek
+/// [peek\_mut]: #method.peek_mut
#[stable(feature = "rust1", since = "1.0.0")]
pub struct BinaryHeap<T> {
data: Vec<T>,
/// }
/// assert_eq!(heap.peek(), Some(&2));
/// ```
+ ///
+ /// # Time complexity
+ ///
+ /// Cost is O(1) in the worst case.
#[stable(feature = "binary_heap_peek_mut", since = "1.12.0")]
pub fn peek_mut(&mut self) -> Option<PeekMut<'_, T>> {
if self.is_empty() {
/// assert_eq!(heap.pop(), Some(1));
/// assert_eq!(heap.pop(), None);
/// ```
+ ///
+ /// # Time complexity
+ ///
+ /// The worst case cost of `pop` on a heap containing *n* elements is O(log
+ /// n).
#[stable(feature = "rust1", since = "1.0.0")]
pub fn pop(&mut self) -> Option<T> {
self.data.pop().map(|mut item| {
/// assert_eq!(heap.len(), 3);
/// assert_eq!(heap.peek(), Some(&5));
/// ```
+ ///
+ /// # Time complexity
+ ///
+ /// The expected cost of `push`, averaged over every possible ordering of
+ /// the elements being pushed, and over a sufficiently large number of
+ /// pushes, is O(1). This is the most meaningful cost metric when pushing
+ /// elements that are *not* already in any sorted pattern.
+ ///
+ /// The time complexity degrades if elements are pushed in predominantly
+ /// ascending order. In the worst case, elements are pushed in ascending
+ /// sorted order and the amortized cost per push is O(log n) against a heap
+ /// containing *n* elements.
+ ///
+ /// The worst case cost of a *single* call to `push` is O(n). The worst case
+ /// occurs when capacity is exhausted and needs a resize. The resize cost
+ /// has been amortized in the previous figures.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn push(&mut self, item: T) {
let old_len = self.len();
/// assert_eq!(heap.peek(), Some(&5));
///
/// ```
+ ///
+ /// # Time complexity
+ ///
+ /// Cost is O(1) in the worst case.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn peek(&self) -> Option<&T> {
self.data.get(0)
/// # Examples
///
/// ```
- /// #![feature(vecdeque_rotate)]
- ///
/// use std::collections::VecDeque;
///
/// let mut buf: VecDeque<_> = (0..10).collect();
/// }
/// assert_eq!(buf, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
/// ```
- #[unstable(feature = "vecdeque_rotate", issue = "56686")]
+ #[stable(feature = "vecdeque_rotate", since = "1.36.0")]
pub fn rotate_left(&mut self, mid: usize) {
assert!(mid <= self.len());
let k = self.len() - mid;
/// # Examples
///
/// ```
- /// #![feature(vecdeque_rotate)]
- ///
/// use std::collections::VecDeque;
///
/// let mut buf: VecDeque<_> = (0..10).collect();
/// }
/// assert_eq!(buf, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
/// ```
- #[unstable(feature = "vecdeque_rotate", issue = "56686")]
+ #[stable(feature = "vecdeque_rotate", since = "1.36.0")]
pub fn rotate_right(&mut self, k: usize) {
assert!(k <= self.len());
let mid = self.len() - k;
#![feature(rustc_const_unstable)]
#![feature(const_vec_new)]
#![feature(slice_partition_dedup)]
-#![feature(maybe_uninit, maybe_uninit_slice, maybe_uninit_array)]
+#![feature(maybe_uninit_extra, maybe_uninit_slice, maybe_uninit_array)]
#![feature(alloc_layout_extra)]
#![feature(try_trait)]
#![feature(iter_nth_back)]
#[test]
// Only tests the simple function definition with respect to intersection
fn test_is_disjoint() {
- let one = [1].into_iter().collect::<BTreeSet<_>>();
- let two = [2].into_iter().collect::<BTreeSet<_>>();
+ let one = [1].iter().collect::<BTreeSet<_>>();
+ let two = [2].iter().collect::<BTreeSet<_>>();
assert!(one.is_disjoint(&two));
}
#![feature(repeat_generic_slice)]
#![feature(try_reserve)]
#![feature(unboxed_closures)]
-#![feature(vecdeque_rotate)]
#![deny(rust_2018_idioms)]
use std::hash::{Hash, Hasher};
/// [`Layout::from_size_align`](#method.from_size_align).
#[stable(feature = "alloc_layout", since = "1.28.0")]
#[inline]
- pub unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self {
+ pub const unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self {
Layout { size_: size, align_: NonZeroUsize::new_unchecked(align) }
}
/// this allocator,
///
/// * `layout` must be the same layout that was used
- /// to allocated that block of memory,
+ /// to allocate that block of memory,
#[stable(feature = "global_alloc", since = "1.28.0")]
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout);
/// * `ptr` must be currently allocated via this allocator,
///
/// * `layout` must be the same layout that was used
- /// to allocated that block of memory,
+ /// to allocate that block of memory,
///
/// * `new_size` must be greater than zero.
///
///
/// # Examples
///
-/// Basic usage with `i32`:
+/// Basic usage with `f64`:
///
/// ```
/// let x = 42.0; // 42.0 is '4.2e1' in scientific notation
///
/// # Examples
///
-/// Basic usage with `f32`:
+/// Basic usage with `f64`:
///
/// ```
/// let x = 42.0; // 42.0 is '4.2E1' in scientific notation
///
/// ```
/// let a = [0, 1, 2, 3, 4, 5];
- /// let mut iter = a.into_iter().step_by(2);
+ /// let mut iter = a.iter().step_by(2);
///
/// assert_eq!(iter.next(), Some(&0));
/// assert_eq!(iter.next(), Some(&2));
/// ```
/// let a = [1, 2, 3];
///
- /// let mut iter = a.into_iter().map(|x| 2 * x);
+ /// let mut iter = a.iter().map(|x| 2 * x);
///
/// assert_eq!(iter.next(), Some(2));
/// assert_eq!(iter.next(), Some(4));
/// ```
/// let a = [0i32, 1, 2];
///
- /// let mut iter = a.into_iter().filter(|x| x.is_positive());
+ /// let mut iter = a.iter().filter(|x| x.is_positive());
///
/// assert_eq!(iter.next(), Some(&1));
/// assert_eq!(iter.next(), Some(&2));
/// ```
/// let a = [0, 1, 2];
///
- /// let mut iter = a.into_iter().filter(|x| **x > 1); // need two *s!
+ /// let mut iter = a.iter().filter(|x| **x > 1); // need two *s!
///
/// assert_eq!(iter.next(), Some(&2));
/// assert_eq!(iter.next(), None);
/// ```
/// let a = [0, 1, 2];
///
- /// let mut iter = a.into_iter().filter(|&x| *x > 1); // both & and *
+ /// let mut iter = a.iter().filter(|&x| *x > 1); // both & and *
///
/// assert_eq!(iter.next(), Some(&2));
/// assert_eq!(iter.next(), None);
/// ```
/// let a = [0, 1, 2];
///
- /// let mut iter = a.into_iter().filter(|&&x| x > 1); // two &s
+ /// let mut iter = a.iter().filter(|&&x| x > 1); // two &s
///
/// assert_eq!(iter.next(), Some(&2));
/// assert_eq!(iter.next(), None);
/// ```
/// let a = [-1i32, 0, 1];
///
- /// let mut iter = a.into_iter().skip_while(|x| x.is_negative());
+ /// let mut iter = a.iter().skip_while(|x| x.is_negative());
///
/// assert_eq!(iter.next(), Some(&0));
/// assert_eq!(iter.next(), Some(&1));
/// ```
/// let a = [-1, 0, 1];
///
- /// let mut iter = a.into_iter().skip_while(|x| **x < 0); // need two *s!
+ /// let mut iter = a.iter().skip_while(|x| **x < 0); // need two *s!
///
/// assert_eq!(iter.next(), Some(&0));
/// assert_eq!(iter.next(), Some(&1));
/// ```
/// let a = [-1, 0, 1, -2];
///
- /// let mut iter = a.into_iter().skip_while(|x| **x < 0);
+ /// let mut iter = a.iter().skip_while(|x| **x < 0);
///
/// assert_eq!(iter.next(), Some(&0));
/// assert_eq!(iter.next(), Some(&1));
/// ```
/// let a = [-1i32, 0, 1];
///
- /// let mut iter = a.into_iter().take_while(|x| x.is_negative());
+ /// let mut iter = a.iter().take_while(|x| x.is_negative());
///
/// assert_eq!(iter.next(), Some(&-1));
/// assert_eq!(iter.next(), None);
/// ```
/// let a = [-1, 0, 1];
///
- /// let mut iter = a.into_iter().take_while(|x| **x < 0); // need two *s!
+ /// let mut iter = a.iter().take_while(|x| **x < 0); // need two *s!
///
/// assert_eq!(iter.next(), Some(&-1));
/// assert_eq!(iter.next(), None);
/// ```
/// let a = [-1, 0, 1, -2];
///
- /// let mut iter = a.into_iter().take_while(|x| **x < 0);
+ /// let mut iter = a.iter().take_while(|x| **x < 0);
///
/// assert_eq!(iter.next(), Some(&-1));
///
///
/// ```
/// let a = [1, 2, 3, 4];
- /// let mut iter = a.into_iter();
+ /// let mut iter = a.iter();
///
/// let result: Vec<i32> = iter.by_ref()
/// .take_while(|n| **n != 3)
/// ```
/// let a = [1, 2, 3];
///
- /// let iter = a.into_iter();
+ /// let iter = a.iter();
///
/// let sum: i32 = iter.take(5).fold(0, |acc, i| acc + i );
///
/// // let's try that again
/// let a = [1, 2, 3];
///
- /// let mut iter = a.into_iter();
+ /// let mut iter = a.iter();
///
/// // instead, we add in a .by_ref()
/// let sum: i32 = iter.by_ref().take(2).fold(0, |acc, i| acc + i );
/// let a = [1, 2, 3];
///
/// let (even, odd): (Vec<i32>, Vec<i32>) = a
- /// .into_iter()
+ /// .iter()
/// .partition(|&n| n % 2 == 0);
///
/// assert_eq!(even, vec![2]);
#![feature(structural_match)]
#![feature(abi_unadjusted)]
#![feature(adx_target_feature)]
-#![feature(maybe_uninit, maybe_uninit_slice, maybe_uninit_array)]
+#![feature(maybe_uninit_slice, maybe_uninit_array)]
#![feature(external_doc)]
#[prelude_import]
/// The practical use cases for `forget` are rather specialized and mainly come
/// up in unsafe or FFI code.
///
-/// ## Use case 1
-///
-/// You have created an uninitialized value using [`mem::uninitialized`][uninit].
-/// You must either initialize or `forget` it on every computation path before
-/// Rust drops it automatically, like at the end of a scope or after a panic.
-/// Running the destructor on an uninitialized value would be [undefined behavior][ub].
-///
-/// ```
-/// use std::mem;
-/// use std::ptr;
-///
-/// # let some_condition = false;
-/// unsafe {
-/// let mut uninit_vec: Vec<u32> = mem::uninitialized();
-///
-/// if some_condition {
-/// // Initialize the variable.
-/// ptr::write(&mut uninit_vec, Vec::new());
-/// } else {
-/// // Forget the uninitialized value so its destructor doesn't run.
-/// mem::forget(uninit_vec);
-/// }
-/// }
-/// ```
-///
-/// ## Use case 2
-///
-/// You have duplicated the bytes making up a value, without doing a proper
-/// [`Clone`][clone]. You need the value's destructor to run only once,
-/// because a double `free` is undefined behavior.
-///
-/// An example is a possible implementation of [`mem::swap`][swap]:
-///
-/// ```
-/// use std::mem;
-/// use std::ptr;
-///
-/// # #[allow(dead_code)]
-/// fn swap<T>(x: &mut T, y: &mut T) {
-/// unsafe {
-/// // Give ourselves some scratch space to work with
-/// let mut t: T = mem::uninitialized();
-///
-/// // Perform the swap, `&mut` pointers never alias
-/// ptr::copy_nonoverlapping(&*x, &mut t, 1);
-/// ptr::copy_nonoverlapping(&*y, x, 1);
-/// ptr::copy_nonoverlapping(&t, y, 1);
-///
-/// // y and t now point to the same thing, but we need to completely
-/// // forget `t` because we do not want to run the destructor for `T`
-/// // on its value, which is still owned somewhere outside this function.
-/// mem::forget(t);
-/// }
-/// }
-/// ```
-///
/// [drop]: fn.drop.html
/// [uninit]: fn.uninitialized.html
/// [clone]: ../clone/trait.Clone.html
/// Creates a value whose bytes are all zero.
///
-/// This has the same effect as allocating space with
-/// [`mem::uninitialized`][uninit] and then zeroing it out. It is useful for
-/// FFI sometimes, but should generally be avoided.
+/// This has the same effect as [`MaybeUninit::zeroed().assume_init()`][zeroed].
+/// It is useful for FFI sometimes, but should generally be avoided.
///
/// There is no guarantee that an all-zero byte-pattern represents a valid value of
-/// some type `T`. If `T` has a destructor and the value is destroyed (due to
-/// a panic or the end of a scope) before being initialized, then the destructor
-/// will run on zeroed data, likely leading to [undefined behavior][ub].
-///
-/// See also the documentation for [`mem::uninitialized`][uninit], which has
-/// many of the same caveats.
+/// some type `T`. For example, the all-zero byte-pattern is not a valid value
+/// for reference types (`&T` and `&mut T`). Using `zeroed` on such types
+/// causes immediate [undefined behavior][ub] because [the Rust compiler assumes][inv]
+/// that there always is a valid value in a variable it considers initialized.
///
-/// [uninit]: fn.uninitialized.html
+/// [zeroed]: union.MaybeUninit.html#method.zeroed
/// [ub]: ../../reference/behavior-considered-undefined.html
+/// [inv]: union.MaybeUninit.html#initialization-invariant
///
/// # Examples
///
+/// Correct usage of this function: initializing an integer with zero.
+///
/// ```
/// use std::mem;
///
/// let x: i32 = unsafe { mem::zeroed() };
/// assert_eq!(0, x);
/// ```
+///
+/// *Incorrect* usage of this function: initializing a reference with zero.
+///
+/// ```no_run
+/// use std::mem;
+///
+/// let _x: &i32 = unsafe { mem::zeroed() }; // Undefined behavior!
+/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn zeroed<T>() -> T {
/// Bypasses Rust's normal memory-initialization checks by pretending to
/// produce a value of type `T`, while doing nothing at all.
///
-/// **This is incredibly dangerous and should not be done lightly. Deeply
-/// consider initializing your memory with a default value instead.**
-///
-/// This is useful for FFI functions and initializing arrays sometimes,
-/// but should generally be avoided.
-///
-/// # Undefined behavior
-///
-/// It is [undefined behavior][ub] to read uninitialized memory, even just an
-/// uninitialized boolean. For instance, if you branch on the value of such
-/// a boolean, your program may take one, both, or neither of the branches.
-///
-/// Writing to the uninitialized value is similarly dangerous. Rust believes the
-/// value is initialized, and will therefore try to [`Drop`] the uninitialized
-/// value and its fields if you try to overwrite it in a normal manner. The only way
-/// to safely initialize an uninitialized value is with [`ptr::write`][write],
-/// [`ptr::copy`][copy], or [`ptr::copy_nonoverlapping`][copy_no].
-///
-/// If the value does implement [`Drop`], it must be initialized before
-/// it goes out of scope (and therefore would be dropped). Note that this
-/// includes a `panic` occurring and unwinding the stack suddenly.
+/// **This functon is deprecated.** Use [`MaybeUninit<T>`] instead.
///
-/// If you partially initialize an array, you may need to use
-/// [`ptr::drop_in_place`][drop_in_place] to remove the elements you have fully
-/// initialized followed by [`mem::forget`][mem_forget] to prevent drop running
-/// on the array. If a partially allocated array is dropped this will lead to
-/// undefined behaviour.
-///
-/// # Examples
-///
-/// Here's how to safely initialize an array of [`Vec`]s.
-///
-/// ```
-/// use std::mem;
-/// use std::ptr;
-///
-/// // Only declare the array. This safely leaves it
-/// // uninitialized in a way that Rust will track for us.
-/// // However we can't initialize it element-by-element
-/// // safely, and we can't use the `[value; 1000]`
-/// // constructor because it only works with `Copy` data.
-/// let mut data: [Vec<u32>; 1000];
-///
-/// unsafe {
-/// // So we need to do this to initialize it.
-/// data = mem::uninitialized();
-///
-/// // DANGER ZONE: if anything panics or otherwise
-/// // incorrectly reads the array here, we will have
-/// // Undefined Behavior.
-///
-/// // It's ok to mutably iterate the data, since this
-/// // doesn't involve reading it at all.
-/// // (ptr and len are statically known for arrays)
-/// for elem in &mut data[..] {
-/// // *elem = Vec::new() would try to drop the
-/// // uninitialized memory at `elem` -- bad!
-/// //
-/// // Vec::new doesn't allocate or do really
-/// // anything. It's only safe to call here
-/// // because we know it won't panic.
-/// ptr::write(elem, Vec::new());
-/// }
-///
-/// // SAFE ZONE: everything is initialized.
-/// }
-///
-/// println!("{:?}", &data[0]);
-/// ```
-///
-/// This example emphasizes exactly how delicate and dangerous using `mem::uninitialized`
-/// can be. Note that the [`vec!`] macro *does* let you initialize every element with a
-/// value that is only [`Clone`], so the following is semantically equivalent and
-/// vastly less dangerous, as long as you can live with an extra heap
-/// allocation:
-///
-/// ```
-/// let data: Vec<Vec<u32>> = vec![Vec::new(); 1000];
-/// println!("{:?}", &data[0]);
-/// ```
-///
-/// This example shows how to handle partially initialized arrays, which could
-/// be found in low-level datastructures.
-///
-/// ```
-/// use std::mem;
-/// use std::ptr;
-///
-/// // Count the number of elements we have assigned.
-/// let mut data_len: usize = 0;
-/// let mut data: [String; 1000];
-///
-/// unsafe {
-/// data = mem::uninitialized();
-///
-/// for elem in &mut data[0..500] {
-/// ptr::write(elem, String::from("hello"));
-/// data_len += 1;
-/// }
-///
-/// // For each item in the array, drop if we allocated it.
-/// for i in &mut data[0..data_len] {
-/// ptr::drop_in_place(i);
-/// }
-/// }
-/// // Forget the data. If this is allowed to drop, you may see a crash such as:
-/// // 'mem_uninit_test(2457,0x7fffb55dd380) malloc: *** error for object
-/// // 0x7ff3b8402920: pointer being freed was not allocated'
-/// mem::forget(data);
-/// ```
+/// The reason for deprecation is that the function basically cannot be used
+/// correctly: [the Rust compiler assumes][inv] that values are properly initialized.
+/// As a consequence, calling e.g. `mem::uninitialized::<bool>()` causes immediate
+/// undefined behavior for returning a `bool` that is not definitely either `true`
+/// or `false`. Worse, truly uninitialized memory like what gets returned here
+/// 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.
+/// (Notice that the rules around uninitialized integers are not finalized yet, but
+/// until they are, it is advisable to avoid them.)
///
-/// [`Vec`]: ../../std/vec/struct.Vec.html
-/// [`vec!`]: ../../std/macro.vec.html
-/// [`Clone`]: ../../std/clone/trait.Clone.html
-/// [ub]: ../../reference/behavior-considered-undefined.html
-/// [write]: ../ptr/fn.write.html
-/// [drop_in_place]: ../ptr/fn.drop_in_place.html
-/// [mem_zeroed]: fn.zeroed.html
-/// [mem_forget]: fn.forget.html
-/// [copy]: ../intrinsics/fn.copy.html
-/// [copy_no]: ../intrinsics/fn.copy_nonoverlapping.html
-/// [`Drop`]: ../ops/trait.Drop.html
+/// [`MaybeUninit<T>`]: union.MaybeUninit.html
+/// [inv]: union.MaybeUninit.html#initialization-invariant
#[inline]
-#[rustc_deprecated(since = "2.0.0", reason = "use `mem::MaybeUninit::uninit` instead")]
+#[rustc_deprecated(since = "1.40.0", reason = "use `mem::MaybeUninit` instead")]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn uninitialized<T>() -> T {
intrinsics::panic_if_uninhabited::<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.
/// 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.
+/// If you need to handle uninitialized data, use [`MaybeUninit<T>`] instead.
///
/// # Examples
///
/// ```
///
/// [`mem::zeroed`]: fn.zeroed.html
+/// [`MaybeUninit<T>`]: union.MaybeUninit.html
#[stable(feature = "manually_drop", since = "1.20.0")]
#[lang = "manually_drop"]
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
}
}
-/// A wrapper to construct uninitialized instances of `T`.
+/// A wrapper type to construct uninitialized instances of `T`.
+///
+/// # Initialization invariant
///
/// The compiler, in general, assumes that variables are properly initialized
/// at their respective type. For example, a variable of reference type must
/// be aligned and non-NULL. This is an invariant that must *always* be upheld,
/// even in unsafe code. As a consequence, zero-initializing a variable of reference
-/// type causes instantaneous undefined behavior, no matter whether that reference
+/// type causes instantaneous [undefined behavior][ub], no matter whether that reference
/// ever gets used to access memory:
///
/// ```rust,no_run
-/// #![feature(maybe_uninit)]
/// use std::mem::{self, MaybeUninit};
///
/// let x: &i32 = unsafe { mem::zeroed() }; // undefined behavior!
/// 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!
/// 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:
+/// which otherwise can hold any *fixed* bit pattern:
///
/// ```rust,no_run
-/// #![feature(maybe_uninit)]
/// use std::mem::{self, MaybeUninit};
///
/// let x: i32 = unsafe { mem::uninitialized() }; // undefined behavior!
/// (Notice that the rules around uninitialized integers are not finalized yet, but
/// until they are, it is advisable to avoid them.)
///
+/// On top of that, remember that most types have additional invariants beyond merely
+/// being considered initialized at the type level. For example, a `1`-initialized [`Vec<T>`]
+/// is considered initialized because the only requirement the compiler knows about it
+/// is that the data pointer must be non-null. Creating such a `Vec<T>` does not cause
+/// *immediate* undefined behavior, but will cause undefined behavior with most
+/// safe operations (including dropping it).
+///
+/// [`Vec<T>`]: ../../std/vec/struct.Vec.html
+///
+/// # Examples
+///
/// `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
-/// #![feature(maybe_uninit)]
/// use std::mem::MaybeUninit;
///
/// // Create an explicitly uninitialized reference. The compiler knows that data inside
/// // a `MaybeUninit<T>` may be invalid, and hence this is not UB:
/// let mut x = MaybeUninit::<&i32>::uninit();
/// // Set it to a valid value.
-/// x.write(&0);
+/// unsafe { x.as_mut_ptr().write(&0); }
/// // Extract the initialized data -- this is only allowed *after* properly
/// // initializing `x`!
/// let x = unsafe { x.assume_init() };
/// ```
///
/// 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.
+///
+/// ## out-pointers
+///
+/// You can use `MaybeUninit<T>` to implement "out-pointers": instead of returning data
+/// from a function, pass it a pointer to some (uninitialized) memory to put the
+/// result into. This can be useful when it is important for the caller to control
+/// how the memory the result is stored in gets allocated, and you want to avoid
+/// unnecessary moves.
+///
+/// ```
+/// use std::mem::MaybeUninit;
+///
+/// unsafe fn make_vec(out: *mut Vec<i32>) {
+/// // `write` does not drop the old contents, which is important.
+/// out.write(vec![1, 2, 3]);
+/// }
+///
+/// let mut v: MaybeUninit<Vec<i32>> = MaybeUninit::uninit();
+/// unsafe { make_vec(v.as_mut_ptr()); }
+/// // Now we know `v` is initialized! This also makes sure the vector gets
+/// // properly dropped.
+/// let v = unsafe { v.assume_init() };
+/// assert_eq!(&v, &[1, 2, 3]);
+/// ```
+///
+/// ## Initializing an array element-by-element
+///
+/// `MaybeUninit<T>` can be used to initialize a large array element-by-element:
+///
+/// ```
+/// use std::mem::{self, MaybeUninit};
+/// use std::ptr;
+///
+/// let data = {
+/// // Create an uninitialized array of `MaybeUninit`. The `assume_init` is
+/// // safe because the type we are claiming to have initialized here is a
+/// // bunch of `MaybeUninit`s, which do not require initialization.
+/// let mut data: [MaybeUninit<Vec<u32>>; 1000] = unsafe {
+/// MaybeUninit::uninit().assume_init()
+/// };
+///
+/// // Dropping a `MaybeUninit` does nothing, so if there is a panic during this loop,
+/// // we have a memory leak, but there is no memory safety issue.
+/// for elem in &mut data[..] {
+/// unsafe { ptr::write(elem.as_mut_ptr(), vec![42]); }
+/// }
+///
+/// // Everything is initialized. Transmute the array to the
+/// // initialized type.
+/// unsafe { mem::transmute::<_, [Vec<u32>; 1000]>(data) }
+/// };
+///
+/// assert_eq!(&data[0], &[42]);
+/// ```
+///
+/// You can also work with partially initialized arrays, which could
+/// be found in low-level datastructures.
+///
+/// ```
+/// use std::mem::MaybeUninit;
+/// use std::ptr;
+///
+/// // Create an uninitialized array of `MaybeUninit`. The `assume_init` is
+/// // safe because the type we are claiming to have initialized here is a
+/// // bunch of `MaybeUninit`s, which do not require initialization.
+/// let mut data: [MaybeUninit<String>; 1000] = unsafe { MaybeUninit::uninit().assume_init() };
+/// // Count the number of elements we have assigned.
+/// let mut data_len: usize = 0;
+///
+/// for elem in &mut data[0..500] {
+/// unsafe { ptr::write(elem.as_mut_ptr(), String::from("hello")); }
+/// data_len += 1;
+/// }
+///
+/// // For each item in the array, drop if we allocated it.
+/// for elem in &mut data[0..data_len] {
+/// unsafe { ptr::drop_in_place(elem.as_mut_ptr()); }
+/// }
+/// ```
+///
+/// ## Initializing a struct field-by-field
+///
+/// There is currently no supported way to create a raw pointer or reference
+/// to a field of a struct inside `MaybeUninit<Struct>`. That means it is not possible
+/// to create a struct by calling `MaybeUninit::uninit::<Struct>()` and then writing
+/// to its fields.
+///
+/// [ub]: ../../reference/behavior-considered-undefined.html
+///
+/// # Layout
+///
+/// `MaybeUninit<T>` is guaranteed to have the same size and alignment as `T`:
+///
+/// ```rust
+/// use std::mem::{MaybeUninit, size_of, align_of};
+/// assert_eq!(size_of::<MaybeUninit<u64>>(), size_of::<u64>());
+/// assert_eq!(align_of::<MaybeUninit<u64>>(), align_of::<u64>());
+/// ```
+///
+/// However remember that a type *containing* a `MaybeUninit<T>` is not necessarily the same
+/// layout; Rust does not in general guarantee that the fields of a `Foo<T>` have the same order as
+/// a `Foo<U>` even if `T` and `U` have the same size and alignment. Furthermore because any bit
+/// value is valid for a `MaybeUninit<T>` the compiler can't apply non-zero/niche-filling
+/// optimizations, potentially resulting in a larger size:
+///
+/// ```rust
+/// # use std::mem::{MaybeUninit, size_of, align_of};
+/// assert_eq!(size_of::<Option<bool>>(), 1);
+/// assert_eq!(size_of::<Option<MaybeUninit<bool>>>(), 2);
+/// ```
#[allow(missing_debug_implementations)]
-#[unstable(feature = "maybe_uninit", issue = "53491")]
+#[stable(feature = "maybe_uninit", since = "1.36.0")]
#[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")]
+#[stable(feature = "maybe_uninit", since = "1.36.0")]
impl<T: Copy> Clone for MaybeUninit<T> {
#[inline(always)]
fn clone(&self) -> Self {
impl<T> MaybeUninit<T> {
/// Creates a new `MaybeUninit<T>` initialized with the given value.
+ /// It is safe to call [`assume_init`] on the return value of this function.
///
/// 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")]
+ ///
+ /// [`assume_init`]: #method.assume_init
+ #[stable(feature = "maybe_uninit", since = "1.36.0")]
#[inline(always)]
pub const fn new(val: T) -> MaybeUninit<T> {
MaybeUninit { value: ManuallyDrop::new(val) }
///
/// 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")]
+ ///
+ /// See the [type-level documentation][type] for some examples.
+ ///
+ /// [type]: union.MaybeUninit.html
+ #[stable(feature = "maybe_uninit", since = "1.36.0")]
#[inline(always)]
pub const fn uninit() -> MaybeUninit<T> {
MaybeUninit { uninit: () }
/// 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();
/// cannot hold 0 as a valid value.
///
/// ```rust,no_run
- /// #![feature(maybe_uninit)]
/// use std::mem::MaybeUninit;
///
/// enum NotZero { One = 1, Two = 2 };
/// // Inside a pair, we create a `NotZero` that does not have a valid discriminant.
/// // This is undefined behavior.
/// ```
- #[unstable(feature = "maybe_uninit", issue = "53491")]
+ #[stable(feature = "maybe_uninit", since = "1.36.0")]
#[inline]
pub fn zeroed() -> MaybeUninit<T> {
let mut u = MaybeUninit::<T>::uninit();
/// 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")]
+ #[unstable(feature = "maybe_uninit_extra", issue = "53491")]
#[inline(always)]
pub fn write(&mut self, val: T) -> &mut T {
unsafe {
/// Gets a pointer to the contained value. Reading from this pointer or turning it
/// into a reference is undefined behavior unless the `MaybeUninit<T>` is initialized.
+ /// Writing to memory that this pointer (non-transitively) points to is undefined behavior
+ /// (except inside an `UnsafeCell<T>`).
///
/// # Examples
///
/// Correct usage of this method:
///
/// ```rust
- /// #![feature(maybe_uninit)]
/// use std::mem::MaybeUninit;
///
/// let mut x = MaybeUninit::<Vec<u32>>::uninit();
/// *Incorrect* usage of this method:
///
/// ```rust,no_run
- /// #![feature(maybe_uninit)]
/// use std::mem::MaybeUninit;
///
/// let x = MaybeUninit::<Vec<u32>>::uninit();
///
/// (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")]
+ #[stable(feature = "maybe_uninit", since = "1.36.0")]
#[inline(always)]
pub fn as_ptr(&self) -> *const T {
unsafe { &*self.value as *const T }
/// Correct usage of this method:
///
/// ```rust
- /// #![feature(maybe_uninit)]
/// use std::mem::MaybeUninit;
///
/// let mut x = MaybeUninit::<Vec<u32>>::uninit();
/// *Incorrect* usage of this method:
///
/// ```rust,no_run
- /// #![feature(maybe_uninit)]
/// use std::mem::MaybeUninit;
///
/// let mut x = MaybeUninit::<Vec<u32>>::uninit();
///
/// (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")]
+ #[stable(feature = "maybe_uninit", since = "1.36.0")]
#[inline(always)]
pub fn as_mut_ptr(&mut self) -> *mut T {
unsafe { &mut *self.value as *mut 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.
+ /// state. Calling this when the content is not yet fully initialized causes immediate undefined
+ /// behavior. The [type-level documentation][inv] contains more information about
+ /// this initialization invariant.
+ ///
+ /// [inv]: #initialization-invariant
///
/// # Examples
///
/// Correct usage of this method:
///
/// ```rust
- /// #![feature(maybe_uninit)]
/// use std::mem::MaybeUninit;
///
/// let mut x = MaybeUninit::<bool>::uninit();
/// *Incorrect* usage of this method:
///
/// ```rust,no_run
- /// #![feature(maybe_uninit)]
/// use std::mem::MaybeUninit;
///
/// let x = MaybeUninit::<Vec<u32>>::uninit();
/// let x_init = unsafe { x.assume_init() };
/// // `x` had not been initialized yet, so this last line caused undefined behavior.
/// ```
- #[unstable(feature = "maybe_uninit", issue = "53491")]
+ #[stable(feature = "maybe_uninit", since = "1.36.0")]
#[inline(always)]
pub unsafe fn assume_init(self) -> T {
intrinsics::panic_if_uninhabited::<T>();
///
/// 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.
+ /// behavior. The [type-level documentation][inv] contains more information about
+ /// this initialization invariant.
///
/// Moreover, this leaves a copy of the same data behind in the `MaybeUninit<T>`. When using
/// multiple copies of the data (by calling `read` multiple times, or first
/// calling `read` and then [`assume_init`]), it is your responsibility
/// to ensure that that data may indeed be duplicated.
///
+ /// [inv]: #initialization-invariant
/// [`assume_init`]: #method.assume_init
///
/// # Examples
/// Correct usage of this method:
///
/// ```rust
- /// #![feature(maybe_uninit)]
+ /// #![feature(maybe_uninit_extra)]
/// use std::mem::MaybeUninit;
///
/// let mut x = MaybeUninit::<u32>::uninit();
/// *Incorrect* usage of this method:
///
/// ```rust,no_run
- /// #![feature(maybe_uninit)]
+ /// #![feature(maybe_uninit_extra)]
/// use std::mem::MaybeUninit;
///
/// let mut x = MaybeUninit::<Option<Vec<u32>>>::uninit();
/// // 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")]
+ #[unstable(feature = "maybe_uninit_extra", issue = "53491")]
#[inline(always)]
pub unsafe fn read(&self) -> T {
intrinsics::panic_if_uninhabited::<T>();
/// location first:
/// ```
/// use std::ptr;
-/// use std::mem;
+/// use std::mem::{self, MaybeUninit};
///
/// unsafe fn drop_after_copy<T>(to_drop: *mut T) {
-/// let mut copy: T = mem::uninitialized();
-/// ptr::copy(to_drop, &mut copy, 1);
-/// drop(copy);
+/// let mut copy: MaybeUninit<T> = MaybeUninit::uninit();
+/// ptr::copy(to_drop, copy.as_mut_ptr(), 1);
+/// drop(copy.assume_init());
/// }
///
/// #[repr(packed, C)]
/// to not be elided or reordered by the compiler across other volatile
/// operations.
///
-/// Memory accessed with `read_volatile` or [`write_volatile`] should not be
-/// accessed with non-volatile operations.
-///
/// [`write_volatile`]: ./fn.write_volatile.html
///
/// # Notes
///
/// * `src` must be properly aligned.
///
-/// Like [`read`], `read_unaligned` creates a bitwise copy of `T`, regardless of
+/// Like [`read`], `read_volatile` creates a bitwise copy of `T`, regardless of
/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the returned
/// value and the value at `*src` can [violate memory safety][read-ownership].
/// However, storing non-[`Copy`] types in volatile memory is almost certainly
/// to not be elided or reordered by the compiler across other volatile
/// operations.
///
-/// Memory accessed with [`read_volatile`] or `write_volatile` should not be
-/// accessed with non-volatile operations.
-///
/// `write_volatile` does not drop the contents of `dst`. This is safe, but it
/// could leak allocations or resources, so care should be taken not to overwrite
/// an object that should be dropped.
///
/// It consists of a data pointer and a [virtual function pointer table (vtable)][vtable] that
/// customizes the behavior of the `RawWaker`.
+///
+/// [`Waker`]: struct.Waker.html
#[derive(PartialEq, Debug)]
#[stable(feature = "futures_api", since = "1.36.0")]
pub struct RawWaker {
/// pointer of a properly constructed [`RawWaker`] object from inside the
/// [`RawWaker`] implementation. Calling one of the contained functions using
/// any other `data` pointer will cause undefined behavior.
+///
+/// [`RawWaker`]: struct.RawWaker.html
#[stable(feature = "futures_api", since = "1.36.0")]
#[derive(PartialEq, Copy, Clone, Debug)]
pub struct RawWakerVTable {
/// required for this additional instance of a [`RawWaker`] and associated
/// task. Calling `wake` on the resulting [`RawWaker`] should result in a wakeup
/// of the same task that would have been awoken by the original [`RawWaker`].
+ ///
+ /// [`Waker`]: struct.Waker.html
+ /// [`RawWaker`]: struct.RawWaker.html
clone: unsafe fn(*const ()) -> RawWaker,
/// This function will be called when `wake` is called on the [`Waker`].
/// The implementation of this function must make sure to release any
/// resources that are associated with this instance of a [`RawWaker`] and
/// associated task.
+ ///
+ /// [`Waker`]: struct.Waker.html
+ /// [`RawWaker`]: struct.RawWaker.html
wake: unsafe fn(*const ()),
/// This function will be called when `wake_by_ref` is called on the [`Waker`].
///
/// This function is similar to `wake`, but must not consume the provided data
/// pointer.
+ ///
+ /// [`Waker`]: struct.Waker.html
+ /// [`RawWaker`]: struct.RawWaker.html
wake_by_ref: unsafe fn(*const ()),
/// This function gets called when a [`RawWaker`] gets dropped.
/// The implementation of this function must make sure to release any
/// resources that are associated with this instance of a [`RawWaker`] and
/// associated task.
+ ///
+ /// [`RawWaker`]: struct.RawWaker.html
drop: unsafe fn(*const ()),
}
/// The implementation of this function must make sure to release any
/// resources that are associated with this instance of a [`RawWaker`] and
/// associated task.
+ ///
+ /// [`Waker`]: struct.Waker.html
+ /// [`RawWaker`]: struct.RawWaker.html
#[rustc_promotable]
#[cfg_attr(stage0, unstable(feature = "futures_api_const_fn_ptr", issue = "50547"))]
#[cfg_attr(not(stage0), stable(feature = "futures_api", since = "1.36.0"))]
/// executor-specific wakeup behavior.
///
/// Implements [`Clone`], [`Send`], and [`Sync`].
+///
+/// [`RawWaker`]: struct.RawWaker.html
#[repr(transparent)]
#[stable(feature = "futures_api", since = "1.36.0")]
pub struct Waker {
/// The behavior of the returned `Waker` is undefined if the contract defined
/// in [`RawWaker`]'s and [`RawWakerVTable`]'s documentation is not upheld.
/// Therefore this method is unsafe.
+ ///
+ /// [`RawWaker`]: struct.RawWaker.html
+ /// [`RawWakerVTable`]: struct.RawWakerVTable.html
#[inline]
#[stable(feature = "futures_api", since = "1.36.0")]
pub unsafe fn from_raw(waker: RawWaker) -> Waker {
--- /dev/null
+use core::alloc::Layout;
+
+#[test]
+fn const_unchecked_layout() {
+ const SIZE: usize = 0x2000;
+ const ALIGN: usize = 0x1000;
+ const LAYOUT: Layout = unsafe { Layout::from_size_align_unchecked(SIZE, ALIGN) };
+ assert_eq!(LAYOUT.size(), SIZE);
+ assert_eq!(LAYOUT.align(), ALIGN);
+}
#![feature(slice_partition_dedup)]
#![feature(copy_within)]
#![feature(int_error_matching)]
+#![feature(const_fn)]
#![warn(rust_2018_idioms)]
extern crate test;
+mod alloc;
mod any;
mod array;
mod ascii;
impl serialize::UseSpecializedEncodable for CrateNum {}
impl serialize::UseSpecializedDecodable for CrateNum {}
-/// A DefIndex is an index into the hir-map for a crate, identifying a
-/// particular definition. It should really be considered an interned
-/// shorthand for a particular DefPath.
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)]
-pub struct DefIndex(u32);
-
-/// The crate root is always assigned index 0 by the AST Map code,
-/// thanks to `NodeCollector::new`.
-pub const CRATE_DEF_INDEX: DefIndex = DefIndex(0);
+newtype_index! {
+ /// A DefIndex is an index into the hir-map for a crate, identifying a
+ /// particular definition. It should really be considered an interned
+ /// shorthand for a particular DefPath.
+ pub struct DefIndex {
+ DEBUG_FORMAT = "DefIndex({})",
-impl fmt::Debug for DefIndex {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "DefIndex({})", self.as_array_index())
+ /// The crate root is always assigned index 0 by the AST Map code,
+ /// thanks to `NodeCollector::new`.
+ const CRATE_DEF_INDEX = 0,
}
}
impl DefIndex {
- /// Converts this DefIndex into a zero-based array index.
- #[inline]
- pub fn as_array_index(&self) -> usize {
- self.0 as usize
- }
-
- #[inline]
- pub fn from_array_index(i: usize) -> DefIndex {
- DefIndex(i as u32)
- }
-
// Proc macros from a proc-macro crate have a kind of virtual DefIndex. This
// function maps the index of the macro within the crate (which is also the
// index of the macro in the CrateMetadata::proc_macros array) to the
// DefIndex for proc macros start from FIRST_FREE_DEF_INDEX,
// because the first FIRST_FREE_DEF_INDEX indexes are reserved
// for internal use.
- let def_index = DefIndex::from_array_index(
+ let def_index = DefIndex::from(
proc_macro_index.checked_add(FIRST_FREE_DEF_INDEX)
.expect("integer overflow adding `proc_macro_index`"));
assert!(def_index != CRATE_DEF_INDEX);
// This function is the reverse of from_proc_macro_index() above.
pub fn to_proc_macro_index(self: DefIndex) -> usize {
- self.as_array_index().checked_sub(FIRST_FREE_DEF_INDEX)
+ self.index().checked_sub(FIRST_FREE_DEF_INDEX)
.unwrap_or_else(|| {
bug!("using local index {:?} as proc-macro index", self)
})
}
-
- pub fn from_raw_u32(x: u32) -> DefIndex {
- DefIndex(x)
- }
-
- pub fn as_raw_u32(&self) -> u32 {
- self.0
- }
}
impl serialize::UseSpecializedEncodable for DefIndex {}
impl fmt::Debug for DefId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "DefId({}:{}", self.krate, self.index.as_array_index())?;
+ write!(f, "DefId({}:{}", self.krate, self.index.index())?;
ty::tls::with_opt(|opt_tcx| {
if let Some(tcx) = opt_tcx {
is_generator: bool,
is_async_body: bool,
+ /// Used to get the current `fn`'s def span to point to when using `await`
+ /// outside of an `async fn`.
+ current_item: Option<Span>,
+
catch_scopes: Vec<NodeId>,
loop_scopes: Vec<NodeId>,
is_in_loop_condition: bool,
node_id_to_hir_id: IndexVec::new(),
is_generator: false,
is_async_body: false,
+ current_item: None,
is_in_trait_impl: false,
lifetimes_to_define: Vec::new(),
is_collecting_in_band_lifetimes: false,
self.sess.diagnostic()
}
- fn str_to_ident(&self, s: &'static str) -> Ident {
- Ident::with_empty_ctxt(Symbol::gensym(s))
- }
-
fn with_anonymous_lifetime_mode<R>(
&mut self,
anonymous_lifetime_mode: AnonymousLifetimeMode,
bindings: hir_vec![
hir::TypeBinding {
hir_id: this.next_id(),
- ident: Ident::from_str(FN_OUTPUT_NAME),
+ ident: Ident::with_empty_ctxt(FN_OUTPUT_NAME),
ty: output
.as_ref()
.map(|ty| this.lower_ty(&ty, ImplTraitContext::disallowed()))
let future_params = P(hir::GenericArgs {
args: hir_vec![],
bindings: hir_vec![hir::TypeBinding {
- ident: Ident::from_str(FN_OUTPUT_NAME),
+ ident: Ident::with_empty_ctxt(FN_OUTPUT_NAME),
ty: output_ty,
hir_id: self.next_id(),
span,
ItemKind::Fn(ref decl, ref header, ref generics, ref body) => {
let fn_def_id = self.resolver.definitions().local_def_id(id);
self.with_new_scopes(|this| {
+ this.current_item = Some(ident.span);
let mut lower_fn = |decl: &FnDecl| {
// Note: we don't need to change the return type from `T` to
// `impl Future<Output = T>` here because lower_body
} else {
lower_method(sig)
};
+ self.current_item = Some(i.span);
(generics, hir::ImplItemKind::Method(sig, body_id))
}
let fn_decl = self.lower_fn_decl(decl, None, false, None);
self.with_new_scopes(|this| {
+ this.current_item = Some(fn_decl_span);
let mut is_generator = false;
let body_id = this.lower_body(Some(decl), |this| {
let e = this.lower_expr(body);
);
head.span = desugared_span;
- let iter = self.str_to_ident("iter");
+ let iter = Ident::with_empty_ctxt(sym::iter);
- let next_ident = self.str_to_ident("__next");
+ let next_ident = Ident::with_empty_ctxt(sym::__next);
let (next_pat, next_pat_hid) = self.pat_ident_binding_mode(
desugared_span,
next_ident,
hir::BindingAnnotation::Mutable,
);
- // `::std::option::Option::Some(val) => next = val`
+ // `::std::option::Option::Some(val) => __next = val`
let pat_arm = {
- let val_ident = self.str_to_ident("val");
+ let val_ident = Ident::with_empty_ctxt(sym::val);
let (val_pat, val_pat_hid) = self.pat_ident(pat.span, val_ident);
let val_expr = P(self.expr_ident(pat.span, val_ident, val_pat_hid));
let next_expr = P(self.expr_ident(pat.span, next_ident, next_pat_hid));
let unstable_span = self.sess.source_map().mark_span_with_reason(
CompilerDesugaringKind::QuestionMark,
e.span,
- Some(vec![
- Symbol::intern("try_trait")
- ].into()),
+ Some(vec![sym::try_trait].into()),
);
let try_span = self.sess.source_map().end_point(e.span);
let try_span = self.sess.source_map().mark_span_with_reason(
CompilerDesugaringKind::QuestionMark,
try_span,
- Some(vec![
- Symbol::intern("try_trait")
- ].into()),
+ Some(vec![sym::try_trait].into()),
);
// `Try::into_result(<expr>)`
let attr = {
// `allow(unreachable_code)`
let allow = {
- let allow_ident = Ident::from_str("allow").with_span_pos(e.span);
- let uc_ident = Ident::from_str("unreachable_code").with_span_pos(e.span);
+ let allow_ident = Ident::with_empty_ctxt(sym::allow).with_span_pos(e.span);
+ let uc_ident = Ident::with_empty_ctxt(sym::unreachable_code)
+ .with_span_pos(e.span);
let uc_nested = attr::mk_nested_word_item(uc_ident);
attr::mk_list_item(e.span, allow_ident, vec![uc_nested])
};
// `Ok(val) => #[allow(unreachable_code)] val,`
let ok_arm = {
- let val_ident = self.str_to_ident("val");
+ let val_ident = Ident::with_empty_ctxt(sym::val);
let (val_pat, val_pat_nid) = self.pat_ident(e.span, val_ident);
let val_expr = P(self.expr_ident_with_attrs(
e.span,
// `Err(err) => #[allow(unreachable_code)]
// return Try::from_error(From::from(err)),`
let err_arm = {
- let err_ident = self.str_to_ident("err");
+ let err_ident = Ident::with_empty_ctxt(sym::err);
let (err_local, err_local_nid) = self.pat_ident(try_span, err_ident);
let from_expr = {
let from_path = &[sym::convert, sym::From, sym::from];
// match ::std::future::poll_with_tls_context(unsafe {
// ::std::pin::Pin::new_unchecked(&mut pinned)
// }) {
- // ::std::task::Poll::Ready(x) => break x,
+ // ::std::task::Poll::Ready(result) => break result,
// ::std::task::Poll::Pending => {},
// }
// yield ();
// }
// }
if !self.is_async_body {
- span_err!(
+ let mut err = struct_span_err!(
self.sess,
await_span,
E0728,
"`await` is only allowed inside `async` functions and blocks"
);
- self.sess.abort_if_errors();
+ err.span_label(await_span, "only allowed inside `async` functions and blocks");
+ if let Some(item_sp) = self.current_item {
+ err.span_label(item_sp, "this is not `async`");
+ }
+ err.emit();
+ return hir::ExprKind::Err;
}
let span = self.sess.source_map().mark_span_with_reason(
CompilerDesugaringKind::Await,
let gen_future_span = self.sess.source_map().mark_span_with_reason(
CompilerDesugaringKind::Await,
await_span,
- Some(vec![Symbol::intern("gen_future")].into()),
+ Some(vec![sym::gen_future].into()),
);
// let mut pinned = <expr>;
let expr = P(self.lower_expr(expr));
- let pinned_ident = self.str_to_ident("pinned");
+ let pinned_ident = Ident::with_empty_ctxt(sym::pinned);
let (pinned_pat, pinned_pat_hid) = self.pat_ident_binding_mode(
span,
pinned_ident,
))
};
- // `::std::task::Poll::Ready(x) => break x`
+ // `::std::task::Poll::Ready(result) => break result`
let loop_node_id = self.sess.next_node_id();
let loop_hir_id = self.lower_node_id(loop_node_id);
let ready_arm = {
- let x_ident = self.str_to_ident("x");
+ let x_ident = Ident::with_empty_ctxt(sym::result);
let (x_pat, x_pat_hid) = self.pat_ident(span, x_ident);
let x_expr = P(self.expr_ident(span, x_ident, x_pat_hid));
let ready_pat = self.pat_std_enum(
fn insert_entry(&mut self, id: HirId, entry: Entry<'hir>) {
debug!("hir_map: {:?} => {:?}", id, entry);
- let local_map = &mut self.map[id.owner.as_array_index()];
+ let local_map = &mut self.map[id.owner.index()];
let i = id.local_id.as_u32() as usize;
if local_map.is_none() {
*local_map = Some(IndexVec::with_capacity(i + 1));
use std::hash::Hash;
use syntax::ast;
use syntax::ext::hygiene::Mark;
-use syntax::symbol::{Symbol, InternedString};
+use syntax::symbol::{Symbol, sym, InternedString};
use syntax_pos::{Span, DUMMY_SP};
use crate::util::nodemap::NodeMap;
def_path_hash: DefPathHash)
-> DefIndex {
let index = {
- let index = DefIndex::from_array_index(self.index_to_key.len());
+ let index = DefIndex::from(self.index_to_key.len());
debug!("DefPathTable::insert() - {:?} <-> {:?}", key, index);
self.index_to_key.push(key);
index
}
pub fn next_id(&self) -> DefIndex {
- DefIndex::from_array_index(self.index_to_key.len())
+ DefIndex::from(self.index_to_key.len())
}
#[inline(always)]
pub fn def_key(&self, index: DefIndex) -> DefKey {
- self.index_to_key[index.as_array_index()].clone()
+ self.index_to_key[index.index()].clone()
}
#[inline(always)]
pub fn def_path_hash(&self, index: DefIndex) -> DefPathHash {
- let ret = self.def_path_hashes[index.as_array_index()];
+ let ret = self.def_path_hashes[index.index()];
debug!("def_path_hash({:?}) = {:?}", index, ret);
return ret
}
.map(|(index, &hash)| {
let def_id = DefId {
krate: cnum,
- index: DefIndex::from_array_index(index),
+ index: DefIndex::from(index),
};
(hash, def_id)
})
#[inline]
pub fn as_local_node_id(&self, def_id: DefId) -> Option<ast::NodeId> {
if def_id.krate == LOCAL_CRATE {
- let node_id = self.def_index_to_node[def_id.index.as_array_index()];
+ let node_id = self.def_index_to_node[def_id.index.index()];
if node_id != ast::DUMMY_NODE_ID {
return Some(node_id);
}
#[inline]
pub fn def_index_to_hir_id(&self, def_index: DefIndex) -> hir::HirId {
- let node_id = self.def_index_to_node[def_index.as_array_index()];
+ let node_id = self.def_index_to_node[def_index.index()];
self.node_to_hir_id[node_id]
}
// Create the definition.
let index = self.table.allocate(key, def_path_hash);
- assert_eq!(index.as_array_index(), self.def_index_to_node.len());
+ assert_eq!(index.index(), self.def_index_to_node.len());
self.def_index_to_node.push(node_id);
// Some things for which we allocate DefIndices don't correspond to
return name
}
// note that this does not show up in user printouts
- CrateRoot => "{{crate}}",
- Impl => "{{impl}}",
- Misc => "{{misc}}",
- ClosureExpr => "{{closure}}",
- Ctor => "{{constructor}}",
- AnonConst => "{{constant}}",
- ImplTrait => "{{opaque}}",
+ CrateRoot => sym::double_braced_crate,
+ Impl => sym::double_braced_impl,
+ Misc => sym::double_braced_misc,
+ ClosureExpr => sym::double_braced_closure,
+ Ctor => sym::double_braced_constructor,
+ AnonConst => sym::double_braced_constant,
+ ImplTrait => sym::double_braced_opaque,
};
- Symbol::intern(s).as_interned_str()
+ s.as_interned_str()
}
pub fn to_string(&self) -> String {
.position(|k| *k == def_key)
.unwrap();
- DefIndex::from_array_index(index)
+ DefIndex::from(index)
}
fn name(&self) -> Symbol {
impl<'hir> Map<'hir> {
#[inline]
fn lookup(&self, id: HirId) -> Option<&Entry<'hir>> {
- let local_map = self.map.get(id.owner.as_array_index())?;
+ let local_map = self.map.get(id.owner.index())?;
local_map.as_ref()?.get(id.local_id)?.as_ref()
}
local_map.iter_enumerated().filter_map(move |(i, entry)| entry.map(move |_| {
// Reconstruct the HirId based on the 3 indices we used to find it
HirId {
- owner: DefIndex::from_array_index(array_index),
+ owner: DefIndex::from(array_index),
local_id: i,
}
}))
own_counts
}
- pub fn get_named(&self, name: &InternedString) -> Option<&GenericParam> {
+ pub fn get_named(&self, name: InternedString) -> Option<&GenericParam> {
for param in &self.params {
- if *name == param.name.ident().as_interned_str() {
+ if name == param.name.ident().as_interned_str() {
return Some(param);
}
}
// `Expr` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")]
-static_assert!(MEM_SIZE_OF_EXPR: std::mem::size_of::<Expr>() == 72);
+static_assert_size!(Expr, 72);
impl Expr {
pub fn precedence(&self) -> ExprPrecedence {
let mut sp = cm.def_span(self.hir().span_by_hir_id(node));
if let Some(param) = self.hir()
.get_generics(scope)
- .and_then(|generics| generics.get_named(&br.name))
+ .and_then(|generics| generics.get_named(br.name))
{
sp = param.span;
}
(format!("the lifetime {} as defined on", br.name), sp)
}
ty::ReFree(ty::FreeRegion {
- bound_region: ty::BoundRegion::BrNamed(_, ref name),
+ bound_region: ty::BoundRegion::BrNamed(_, name),
..
}) => {
let mut sp = cm.def_span(self.hir().span_by_hir_id(node));
if let Some(param) = self.hir()
.get_generics(scope)
- .and_then(|generics| generics.get_named(&name))
+ .and_then(|generics| generics.get_named(name))
{
sp = param.span;
}
) -> Option<AnonymousArgInfo<'_>> {
let (id, bound_region) = match *anon_region {
ty::ReFree(ref free_region) => (free_region.scope, free_region.bound_region),
- ty::ReEarlyBound(ref ebr) => (
+ ty::ReEarlyBound(ebr) => (
self.tcx().parent(ebr.def_id).unwrap(),
ty::BoundRegion::BrNamed(ebr.def_id, ebr.name),
),
}
let requested_node = env::var("RUST_REGION_GRAPH_NODE")
- .ok().and_then(|s| s.parse().map(DefIndex::from_raw_u32).ok());
+ .ok().and_then(|s| s.parse().map(DefIndex::from_u32).ok());
if requested_node.is_some() && requested_node != Some(context.index) {
return;
let mut new_str = String::new();
for c in output_template.chars() {
if c == '%' {
- new_str.push_str(&context.index.as_raw_u32().to_string());
+ new_str.push_str(&context.index.as_u32().to_string());
} else {
new_str.push(c);
}
"detects generic lifetime arguments in path segments with late bound lifetime parameters"
}
-declare_lint! {
- pub INCOHERENT_FUNDAMENTAL_IMPLS,
- Deny,
- "potentially-conflicting impls were erroneously allowed"
-}
-
declare_lint! {
pub ORDER_DEPENDENT_TRAIT_OBJECTS,
Deny,
MISSING_FRAGMENT_SPECIFIER,
PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
LATE_BOUND_LIFETIME_ARGUMENTS,
- INCOHERENT_FUNDAMENTAL_IMPLS,
ORDER_DEPENDENT_TRAIT_OBJECTS,
DEPRECATED,
UNUSED_UNSAFE,
// This shouldn't ever be needed, but just in case:
Ok(vec![match trait_ref {
- Some(trait_ref) => Symbol::intern(&format!("{:?}", trait_ref)).as_str(),
- None => Symbol::intern(&format!("<{}>", self_ty)).as_str(),
+ Some(trait_ref) => LocalInternedString::intern(&format!("{:?}", trait_ref)),
+ None => LocalInternedString::intern(&format!("<{}>", self_ty)),
}])
}
// This shouldn't ever be needed, but just in case:
path.push(match trait_ref {
Some(trait_ref) => {
- Symbol::intern(&format!("<impl {} for {}>", trait_ref, self_ty)).as_str()
+ LocalInternedString::intern(&format!("<impl {} for {}>", trait_ref,
+ self_ty))
},
- None => Symbol::intern(&format!("<impl {}>", self_ty)).as_str(),
+ None => LocalInternedString::intern(&format!("<impl {}>", self_ty)),
});
Ok(path)
let push = builder.levels.push(&krate.attrs);
builder.levels.register_id(hir::CRATE_HIR_ID);
+ for macro_def in &krate.exported_macros {
+ builder.levels.register_id(macro_def.hir_id);
+ }
intravisit::walk_crate(&mut builder, krate);
builder.levels.pop(push);
impl_stable_hash_for!(struct crate::middle::region::FirstStatementIndex { private });
// compilation error if size of `ScopeData` is not the same as a `u32`
-static_assert!(ASSERT_SCOPE_DATA: mem::size_of::<ScopeData>() == 4);
+static_assert_size!(ScopeData, 4);
impl Scope {
/// Returns a item-local ID associated with this scope.
pub tag: Tag,
}
-static_assert!(POINTER_SIZE: ::std::mem::size_of::<Pointer>() == 16);
+static_assert_size!(Pointer, 16);
/// Produces a `Pointer` which points to the beginning of the Allocation
impl From<AllocId> for Pointer {
}
#[cfg(target_arch = "x86_64")]
-static_assert!(CONST_SIZE: ::std::mem::size_of::<ConstValue<'static>>() == 40);
+static_assert_size!(ConstValue<'_>, 40);
impl<'tcx> ConstValue<'tcx> {
#[inline]
}
#[cfg(target_arch = "x86_64")]
-static_assert!(SCALAR_SIZE: ::std::mem::size_of::<Scalar>() == 24);
+static_assert_size!(Scalar, 24);
impl<Tag> fmt::Display for Scalar<Tag> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// `Statement` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")]
-static_assert!(MEM_SIZE_OF_STATEMENT: mem::size_of::<Statement<'_>>() == 56);
+static_assert_size!(Statement<'_>, 56);
impl<'tcx> Statement<'tcx> {
/// Changes a statement to a nop. This is both faster than deleting instructions and avoids
/// and the index is a local.
pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>>;
-// at least on 64 bit systems, `PlaceElem` should not be larger than two pointers
-static_assert!(PROJECTION_ELEM_IS_2_PTRS_LARGE:
- mem::size_of::<PlaceElem<'_>>() <= 16
-);
+// At least on 64 bit systems, `PlaceElem` should not be larger than two pointers.
+#[cfg(target_arch = "x86_64")]
+static_assert_size!(PlaceElem<'_>, 16);
/// Alias for projections as they appear in `UserTypeProjection`, where we
/// need neither the `V` parameter for `Index` nor the `T` for `Field`.
use crate::hir::def_id::{DefId, CrateNum, LOCAL_CRATE};
use crate::hir::HirId;
-use syntax::symbol::{Symbol, InternedString};
+use syntax::symbol::InternedString;
use crate::ty::{Instance, TyCtxt};
use crate::util::nodemap::FxHashMap;
use rustc_data_structures::base_n;
cgu_name
} else {
let cgu_name = &cgu_name.as_str()[..];
- Symbol::intern(&CodegenUnit::mangle_name(cgu_name)).as_interned_str()
+ InternedString::intern(&CodegenUnit::mangle_name(cgu_name))
}
}
write!(cgu_name, ".{}", special_suffix).unwrap();
}
- Symbol::intern(&cgu_name[..]).as_interned_str()
+ InternedString::intern(&cgu_name[..])
}
}
pub variant_index: Option<VariantIdx>,
}
-static_assert!(PLACE_TY_IS_3_PTRS_LARGE:
- mem::size_of::<PlaceTy<'_>>() <= 24
-);
+// At least on 64 bit systems, `PlaceTy` should not be larger than two or three pointers.
+#[cfg(target_arch = "x86_64")]
+static_assert_size!(PlaceTy<'_>, 16);
impl<'a, 'gcx, 'tcx> PlaceTy<'tcx> {
pub fn from_ty(ty: Ty<'tcx>) -> PlaceTy<'tcx> {
// Convert strings provided as --cfg [cfgspec] into a crate_cfg
pub fn parse_cfgspecs(cfgspecs: Vec<String>) -> FxHashSet<(String, Option<String>)> {
- syntax::with_globals(move || {
+ syntax::with_default_globals(move || {
let cfg = cfgspecs.into_iter().map(|s| {
let sess = parse::ParseSess::new(FilePathMapping::empty());
let filename = FileName::cfg_spec_source_code(&s);
// When the user supplies --test we should implicitly supply --cfg test
#[test]
fn test_switch_implies_cfg_test() {
- syntax::with_globals(|| {
+ syntax::with_default_globals(|| {
let matches = &match optgroups().parse(&["--test".to_string()]) {
Ok(m) => m,
Err(f) => panic!("test_switch_implies_cfg_test: {}", f),
#[test]
fn test_switch_implies_cfg_test_unless_cfg_test() {
use syntax::symbol::sym;
- syntax::with_globals(|| {
+ syntax::with_default_globals(|| {
let matches = &match optgroups().parse(&["--test".to_string(),
"--cfg=test".to_string()]) {
Ok(m) => m,
#[test]
fn test_can_print_warnings() {
- syntax::with_globals(|| {
+ syntax::with_default_globals(|| {
let matches = optgroups().parse(&["-Awarnings".to_string()]).unwrap();
let registry = errors::registry::Registry::new(&[]);
let (sessopts, _) = build_session_options_and_crate_config(&matches);
assert!(!sess.diagnostic().flags.can_emit_warnings);
});
- syntax::with_globals(|| {
+ syntax::with_default_globals(|| {
let matches = optgroups()
.parse(&["-Awarnings".to_string(), "-Dwarnings".to_string()])
.unwrap();
assert!(sess.diagnostic().flags.can_emit_warnings);
});
- syntax::with_globals(|| {
+ syntax::with_default_globals(|| {
let matches = optgroups().parse(&["-Adead_code".to_string()]).unwrap();
let registry = errors::registry::Registry::new(&[]);
let (sessopts, _) = build_session_options_and_crate_config(&matches);
.map(|s| &s == "?")
.unwrap_or(false);
let is_from = format!("{}", trait_ref).starts_with("std::convert::From<");
- let message = if is_try && is_from {
- Some(format!(
+ let (message, note) = if is_try && is_from {
+ (Some(format!(
"`?` couldn't convert the error to `{}`",
trait_ref.self_ty(),
+ )), Some(
+ "the question mark operation (`?`) implicitly performs a \
+ conversion on the error value using the `From` trait".to_owned()
))
} else {
- message
+ (message, note)
};
let mut err = struct_span_err!(
use crate::ty::subst::{Subst, InternalSubsts};
use std::borrow::Cow;
use std::iter::{self};
-use syntax::ast::{self, Name};
+use syntax::ast::{self};
+use syntax::symbol::InternedString;
use syntax_pos::Span;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
// are implemented
let unsized_self_ty: Ty<'tcx> = self.mk_ty_param(
::std::u32::MAX,
- Name::intern("RustaceansAreAwesome").as_interned_str(),
+ InternedString::intern("RustaceansAreAwesome"),
);
// `Receiver[Self => U]`
projection_ty: ty::ProjectionTy::from_ref_and_name(
tcx,
trait_ref,
- Ident::from_str(FN_OUTPUT_NAME),
+ Ident::with_empty_ctxt(FN_OUTPUT_NAME),
),
ty: ret_type
}
// negated `CrateNum` (so remote definitions are visited first) and then
// by a flattened version of the `DefIndex`.
trait_impls.sort_unstable_by_key(|def_id| {
- (-(def_id.krate.as_u32() as i64), def_id.index.as_array_index())
+ (-(def_id.krate.as_u32() as i64), def_id.index.index())
});
for impl_def_id in trait_impls {
String::new(), |ty| {
format!(" for type `{}`", ty)
}),
- if used_to_be_allowed.is_some() { " (E0119)" } else { "" }
+ match used_to_be_allowed {
+ Some(FutureCompatOverlapErrorKind::Issue33140) => " (E0119)",
+ _ => "",
+ }
);
let impl_span = tcx.sess.source_map().def_span(
tcx.span_of_impl(impl_def_id).unwrap()
);
- let mut err = if let Some(kind) = used_to_be_allowed {
- let lint = match kind {
- FutureCompatOverlapErrorKind::Issue43355 =>
- lint::builtin::INCOHERENT_FUNDAMENTAL_IMPLS,
- FutureCompatOverlapErrorKind::Issue33140 =>
- lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS,
- };
- tcx.struct_span_lint_hir(
- lint,
- tcx.hir().as_local_hir_id(impl_def_id).unwrap(),
- impl_span,
- &msg)
- } else {
- struct_span_err!(tcx.sess,
- impl_span,
- E0119,
- "{}",
- msg)
+ let mut err = match used_to_be_allowed {
+ Some(FutureCompatOverlapErrorKind::Issue43355) | None =>
+ struct_span_err!(tcx.sess,
+ impl_span,
+ E0119,
+ "{}",
+ msg),
+ Some(kind) => {
+ let lint = match kind {
+ FutureCompatOverlapErrorKind::Issue43355 =>
+ unreachable!("converted to hard error above"),
+ FutureCompatOverlapErrorKind::Issue33140 =>
+ lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS,
+ };
+ tcx.struct_span_lint_hir(
+ lint,
+ tcx.hir().as_local_hir_id(impl_def_id).unwrap(),
+ impl_span,
+ &msg)
+ }
};
match tcx.span_of_impl(overlap.with_impl) {
}
fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
- use syntax::symbol::Symbol;
-
match t.sty {
ty::Bound(debruijn, bound_ty) if debruijn == self.binder_index => {
self.types.insert(
bound_ty.var.as_u32(),
match bound_ty.kind {
ty::BoundTyKind::Param(name) => name,
- ty::BoundTyKind::Anon => Symbol::intern(
- &format!("^{}", bound_ty.var.as_u32())
- ).as_interned_str(),
+ ty::BoundTyKind::Anon =>
+ InternedString::intern(&format!("^{}", bound_ty.var.as_u32()),
+ ),
}
);
}
}
fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
- use syntax::symbol::Symbol;
-
match r {
ty::ReLateBound(index, br) if *index == self.binder_index => {
match br {
}
ty::BoundRegion::BrAnon(var) => {
- self.regions.insert(Symbol::intern(
- &format!("'^{}", var)
- ).as_interned_str());
+ self.regions.insert(InternedString::intern(&format!("'^{}", var)));
}
_ => (),
// `TyS` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")]
-static_assert!(MEM_SIZE_OF_TY_S: ::std::mem::size_of::<TyS<'_>>() == 32);
+static_assert_size!(TyS<'_>, 32);
impl<'tcx> Ord for TyS<'tcx> {
fn cmp(&self, other: &TyS<'tcx>) -> Ordering {
impl SymbolName {
pub fn new(name: &str) -> SymbolName {
SymbolName {
- name: Symbol::intern(name).as_interned_str()
+ name: InternedString::intern(name)
}
}
use crate::ty::{self, DefIdTree, ParamConst, Ty, TyCtxt, TypeFoldable};
use crate::ty::subst::{Kind, Subst, UnpackedKind};
use crate::mir::interpret::ConstValue;
-use syntax::symbol::{keywords, Symbol};
-
use rustc_target::spec::abi::Abi;
-use syntax::symbol::InternedString;
+use syntax::symbol::{keywords, InternedString};
use std::cell::Cell;
use std::fmt::{self, Write as _};
{
fn name_by_region_index(index: usize) -> InternedString {
match index {
- 0 => Symbol::intern("'r"),
- 1 => Symbol::intern("'s"),
- i => Symbol::intern(&format!("'t{}", i-2)),
- }.as_interned_str()
+ 0 => InternedString::intern("'r"),
+ 1 => InternedString::intern("'s"),
+ i => InternedString::intern(&format!("'t{}", i-2)),
+ }
}
// Replace any anonymous late-bound regions with named
use crate::ty::{self, Ty, TyCtxt, AdtSizedConstraint};
use crate::ty::util::NeedsDrop;
-use syntax::symbol::Symbol;
+use syntax::symbol::InternedString;
pub(super) trait Value<'tcx>: Sized {
fn from_cycle_error<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self;
impl<'tcx> Value<'tcx> for ty::SymbolName {
fn from_cycle_error<'a>(_: TyCtxt<'a, 'tcx, 'tcx>) -> Self {
- ty::SymbolName { name: Symbol::intern("<error>").as_interned_str() }
+ ty::SymbolName { name: InternedString::intern("<error>") }
}
}
// `TyKind` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")]
-static_assert!(MEM_SIZE_OF_TY_KIND: ::std::mem::size_of::<TyKind<'_>>() == 24);
+static_assert_size!(TyKind<'_>, 24);
/// A closure can be modeled as a struct that looks like:
///
// FIXME(#50125): Ignoring `Self` with `index != 0` might lead to weird behavior elsewhere,
// but this should only be possible when using `-Z continue-parse-after-error` like
// `compile-fail/issue-36638.rs`.
- self.name == keywords::SelfUpper.name().as_str() && self.index == 0
+ self.name.as_symbol() == keywords::SelfUpper.name() && self.index == 0
}
}
}
#[cfg(target_arch = "x86_64")]
-static_assert!(CONST_SIZE: ::std::mem::size_of::<Const<'static>>() == 48);
+static_assert_size!(Const<'_>, 48);
impl<'tcx> Const<'tcx> {
#[inline]
use std::sync::mpsc::{Sender};
use syntax_pos::{SpanData};
+use syntax::symbol::{Symbol, sym};
use rustc_macros::HashStable;
use crate::ty::TyCtxt;
use crate::dep_graph::{DepNode};
use crate::session::Session;
// The name of the associated type for `Fn` return types
-pub const FN_OUTPUT_NAME: &str = "Output";
+pub const FN_OUTPUT_NAME: Symbol = sym::Output;
// Useful type to use with `Result<>` indicate that an error has already
// been reported to the user, so no need to continue checking.
base::{ExtCtxt, Resolver},
build::AstBuilder,
expand::ExpansionConfig,
- hygiene::{self, Mark, SyntaxContext},
+ hygiene::{Mark, SyntaxContext},
},
mut_visit::{self, MutVisitor},
parse::ParseSess,
ptr::P,
- symbol::{Symbol, sym}
+ symbol::{keywords, Symbol, sym}
};
use syntax_pos::Span;
].into()),
allow_internal_unsafe: false,
local_inner_macros: false,
- edition: hygiene::default_edition(),
+ edition: self.sess.edition,
});
// Tie the span to the macro expansion info we just created
span,
kind: AllocatorKind::Global,
global: item.ident,
- core: Ident::from_str("core"),
+ core: Ident::with_empty_ctxt(sym::core),
cx: ExtCtxt::new(self.sess, ecfg, self.resolver),
};
// We will generate a new submodule. To `use` the static from that module, we need to get
// the `super::...` path.
- let super_path = f.cx.path(f.span, vec![Ident::from_str("super"), f.global]);
+ let super_path =
+ f.cx.path(f.span, vec![Ident::with_empty_ctxt(keywords::Super.name()), f.global]);
// Generate the items in the submodule
let mut items = vec![
// Generate the submodule itself
let name = f.kind.fn_name("allocator_abi");
- let allocator_abi = Ident::with_empty_ctxt(Symbol::gensym(&name));
+ let allocator_abi = Ident::from_str(&name).gensym();
let module = f.cx.item_mod(span, span, allocator_abi, Vec::new(), items);
let module = f.cx.monotonic_expander().flat_map_item(module).pop().unwrap();
) -> P<Expr> {
match *ty {
AllocatorTy::Layout => {
- let usize = self.cx.path_ident(self.span, Ident::from_str("usize"));
+ let usize = self.cx.path_ident(self.span, Ident::with_empty_ctxt(sym::usize));
let ty_usize = self.cx.ty_path(usize);
let size = ident();
let align = ident();
}
fn usize(&self) -> P<Ty> {
- let usize = self.cx.path_ident(self.span, Ident::from_str("usize"));
+ let usize = self.cx.path_ident(self.span, Ident::with_empty_ctxt(sym::usize));
self.cx.ty_path(usize)
}
fn ptr_u8(&self) -> P<Ty> {
- let u8 = self.cx.path_ident(self.span, Ident::from_str("u8"));
+ let u8 = self.cx.path_ident(self.span, Ident::with_empty_ctxt(sym::u8));
let ty_u8 = self.cx.ty_path(u8);
self.cx.ty_ptr(self.span, ty_u8, Mutability::Mutable)
}
return
}
// The x86 ABI seems to require that leading underscores are added to symbol
- // names, so we need an extra underscore on 32-bit. There's also a leading
+ // names, so we need an extra underscore on x86. There's also a leading
// '\x01' here which disables LLVM's symbol mangling (e.g., no extra
// underscores added in front).
- let prefix = if cgcx.target_pointer_width == "32" {
+ let prefix = if cgcx.target_arch == "x86" {
"\x01__imp__"
} else {
"\x01__imp_"
use rustc::ty::layout::{self, Align, Integer, IntegerExt, LayoutOf,
PrimitiveExt, Size, TyLayout, VariantIdx};
use rustc::ty::subst::UnpackedKind;
-use rustc::session::config;
+use rustc::session::config::{self, DebugInfo};
use rustc::util::nodemap::FxHashMap;
use rustc_fs_util::path_to_c_string;
use rustc_data_structures::small_c_str::SmallCStr;
use rustc_target::abi::HasDataLayout;
use libc::{c_uint, c_longlong};
+use std::collections::hash_map::Entry;
use std::ffi::CString;
use std::fmt::{self, Write};
use std::hash::{Hash, Hasher};
use std::ptr;
use std::path::{Path, PathBuf};
use syntax::ast;
-use syntax::symbol::{Interner, InternedString, Symbol};
+use syntax::symbol::{Interner, InternedString};
use syntax_pos::{self, Span, FileName};
impl PartialEq for llvm::Metadata {
file_name,
defining_crate);
- let file_name = &file_name.to_string();
- let file_name_symbol = Symbol::intern(file_name);
- if defining_crate == LOCAL_CRATE {
- let directory = &cx.sess().working_dir.0.to_string_lossy();
- file_metadata_raw(cx, file_name, Some(file_name_symbol),
- directory, Some(Symbol::intern(directory)))
+ let file_name = Some(file_name.to_string());
+ let directory = if defining_crate == LOCAL_CRATE {
+ Some(cx.sess().working_dir.0.to_string_lossy().to_string())
} else {
// If the path comes from an upstream crate we assume it has been made
// independent of the compiler's working directory one way or another.
- file_metadata_raw(cx, file_name, Some(file_name_symbol), "", None)
- }
+ None
+ };
+ file_metadata_raw(cx, file_name, directory)
}
pub fn unknown_file_metadata(cx: &CodegenCx<'ll, '_>) -> &'ll DIFile {
- file_metadata_raw(cx, "<unknown>", None, "", None)
+ file_metadata_raw(cx, None, None)
}
fn file_metadata_raw(cx: &CodegenCx<'ll, '_>,
- file_name: &str,
- file_name_symbol: Option<Symbol>,
- directory: &str,
- directory_symbol: Option<Symbol>)
+ file_name: Option<String>,
+ directory: Option<String>)
-> &'ll DIFile {
- let key = (file_name_symbol, directory_symbol);
+ let key = (file_name, directory);
+
+ match debug_context(cx).created_files.borrow_mut().entry(key) {
+ Entry::Occupied(o) => return o.get(),
+ Entry::Vacant(v) => {
+ let (file_name, directory) = v.key();
+ debug!("file_metadata: file_name: {:?}, directory: {:?}", file_name, directory);
+
+ let file_name = SmallCStr::new(
+ if let Some(file_name) = file_name { &file_name } else { "<unknown>" });
+ let directory = SmallCStr::new(
+ if let Some(directory) = directory { &directory } else { "" });
+
+ let file_metadata = unsafe {
+ llvm::LLVMRustDIBuilderCreateFile(DIB(cx),
+ file_name.as_ptr(),
+ directory.as_ptr())
+ };
- if let Some(file_metadata) = debug_context(cx).created_files.borrow().get(&key) {
- return *file_metadata;
+ v.insert(file_metadata);
+ file_metadata
+ }
}
-
- debug!("file_metadata: file_name: {}, directory: {}", file_name, directory);
-
- let file_name = SmallCStr::new(file_name);
- let directory = SmallCStr::new(directory);
-
- let file_metadata = unsafe {
- llvm::LLVMRustDIBuilderCreateFile(DIB(cx),
- file_name.as_ptr(),
- directory.as_ptr())
- };
-
- let mut created_files = debug_context(cx).created_files.borrow_mut();
- created_files.insert(key, file_metadata);
- file_metadata
}
fn basic_type_metadata(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType {
let producer = CString::new(producer).unwrap();
let flags = "\0";
let split_name = "\0";
- let kind = DebugEmissionKind::from_generic(tcx.sess.opts.debuginfo);
+
+ // FIXME(#60020):
+ //
+ // This should actually be
+ //
+ // ```
+ // let kind = DebugEmissionKind::from_generic(tcx.sess.opts.debuginfo);
+ // ```
+ //
+ // that is, we should set LLVM's emission kind to `LineTablesOnly` if
+ // we are compiling with "limited" debuginfo. However, some of the
+ // existing tools relied on slightly more debuginfo being generated than
+ // would be the case with `LineTablesOnly`, and we did not want to break
+ // these tools in a "drive-by fix", without a good idea or plan about
+ // what limited debuginfo should exactly look like. So for now we keep
+ // the emission kind as `FullDebug`.
+ //
+ // See https://github.com/rust-lang/rust/issues/60020 for details.
+ let kind = DebugEmissionKind::FullDebug;
+ assert!(tcx.sess.opts.debuginfo != DebugInfo::None);
unsafe {
let file_metadata = llvm::LLVMRustDIBuilderCreateFile(
use syntax_pos::{self, Span, Pos};
use syntax::ast;
-use syntax::symbol::{Symbol, InternedString};
+use syntax::symbol::InternedString;
use rustc::ty::layout::{self, LayoutOf, HasTyCtxt};
use rustc_codegen_ssa::traits::*;
llcontext: &'a llvm::Context,
llmod: &'a llvm::Module,
builder: &'a mut DIBuilder<'a>,
- created_files: RefCell<FxHashMap<(Option<Symbol>, Option<Symbol>), &'a DIFile>>,
+ created_files: RefCell<FxHashMap<(Option<String>, Option<String>), &'a DIFile>>,
created_enum_disr_types: RefCell<FxHashMap<(DefId, layout::Primitive), &'a DIType>>,
type_map: RefCell<TypeMap<'a, 'tcx>>,
use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
use rustc::hir;
use syntax::ast::{self, FloatTy};
-use syntax::symbol::Symbol;
+use syntax::symbol::LocalInternedString;
use rustc_codegen_ssa::traits::*;
}
"type_name" => {
let tp_ty = substs.type_at(0);
- let ty_name = Symbol::intern(&tp_ty.to_string()).as_str();
+ let ty_name = LocalInternedString::intern(&tp_ty.to_string());
self.const_str_slice(ty_name)
}
"type_id" => {
pub tm_factory: TargetMachineFactory<B>,
pub msvc_imps_needed: bool,
pub target_pointer_width: String,
+ pub target_arch: String,
pub debuginfo: config::DebugInfo,
// Number of cgus excluding the allocator/metadata modules
total_cgus,
msvc_imps_needed: msvc_imps_needed(tcx),
target_pointer_width: tcx.sess.target.target.target_pointer_width.clone(),
+ target_arch: tcx.sess.target.target.arch.clone(),
debuginfo: tcx.sess.opts.debuginfo,
assembler_cmd,
};
}
PlaceContext::MutatingUse(MutatingUseContext::Drop) => {
- let ty = mir::Place::Base(mir::PlaceBase::Local(local)).ty(self.fx.mir,
- self.fx.cx.tcx());
- let ty = self.fx.monomorphize(&ty.ty);
+ let ty = self.fx.mir.local_decls[local].ty;
+ let ty = self.fx.monomorphize(&ty);
// Only need the place if we're actually dropping it.
if self.fx.cx.type_needs_drop(ty) {
use std::borrow::Cow;
-use syntax::symbol::Symbol;
+use syntax::symbol::LocalInternedString;
use syntax_pos::Pos;
use super::{FunctionCx, LocalRef};
// Get the location information.
let loc = bx.sess().source_map().lookup_char_pos(span.lo());
- let filename = Symbol::intern(&loc.file.name.to_string()).as_str();
+ let filename = LocalInternedString::intern(&loc.file.name.to_string());
let line = bx.const_u32(loc.line as u32);
let col = bx.const_u32(loc.col.to_usize() as u32 + 1);
}
_ => {
let str = msg.description();
- let msg_str = Symbol::intern(str).as_str();
+ let msg_str = LocalInternedString::intern(str);
let msg_file_line_col = bx.static_panic_msg(
Some(msg_str),
filename,
let layout = bx.layout_of(ty);
if layout.abi.is_uninhabited() {
let loc = bx.sess().source_map().lookup_char_pos(span.lo());
- let filename = Symbol::intern(&loc.file.name.to_string()).as_str();
+ let filename = LocalInternedString::intern(&loc.file.name.to_string());
let line = bx.const_u32(loc.line as u32);
let col = bx.const_u32(loc.col.to_usize() as u32 + 1);
"Attempted to instantiate uninhabited type {}",
ty
);
- let msg_str = Symbol::intern(&str).as_str();
+ let msg_str = LocalInternedString::intern(&str);
let msg_file_line_col = bx.static_panic_msg(
Some(msg_str),
filename,
use rustc_mir::monomorphize::item::{InstantiationMode, MonoItem, MonoItemExt};
use rustc_mir::monomorphize::Instance;
-use syntax_pos::symbol::{Symbol, InternedString};
+use syntax_pos::symbol::InternedString;
use log::debug;
if def_id.is_local() {
if tcx.plugin_registrar_fn(LOCAL_CRATE) == Some(def_id) {
let disambiguator = tcx.sess.local_crate_disambiguator();
- return Symbol::intern(&tcx.sess.generate_plugin_registrar_symbol(disambiguator))
- .as_interned_str();
+ return
+ InternedString::intern(&tcx.sess.generate_plugin_registrar_symbol(disambiguator));
}
if tcx.proc_macro_decls_static(LOCAL_CRATE) == Some(def_id) {
let disambiguator = tcx.sess.local_crate_disambiguator();
- return Symbol::intern(&tcx.sess.generate_proc_macro_decls_symbol(disambiguator))
- .as_interned_str();
+ return
+ InternedString::intern(&tcx.sess.generate_proc_macro_decls_symbol(disambiguator));
}
}
let _ = printer.write_str("{{vtable-shim}}");
}
- Symbol::intern(&printer.path.finish(hash)).as_interned_str()
+ InternedString::intern(&printer.path.finish(hash))
}
// Follow C++ namespace-mangling style, see
static $name: () = [()][!($test: bool) as usize];
}
}
+
+/// Type size assertion. The first argument is a type and the second argument is its expected size.
+#[macro_export]
+#[allow_internal_unstable(underscore_const_names)]
+macro_rules! static_assert_size {
+ ($ty:ty, $size:expr) => {
+ const _: [(); $size] = [(); ::std::mem::size_of::<$ty>()];
+ }
+}
/// extended to 64 bits if needed.
pub struct StableHasher<W> {
state: SipHasher128,
- bytes_hashed: u64,
width: PhantomData<W>,
}
pub fn new() -> Self {
StableHasher {
state: SipHasher128::new_with_keys(0, 0),
- bytes_hashed: 0,
width: PhantomData,
}
}
pub fn finalize(self) -> (u64, u64) {
self.state.finish128()
}
-
- #[inline]
- pub fn bytes_hashed(&self) -> u64 {
- self.bytes_hashed
- }
}
impl<W> Hasher for StableHasher<W> {
#[inline]
fn write(&mut self, bytes: &[u8]) {
self.state.write(bytes);
- self.bytes_hashed += bytes.len() as u64;
}
#[inline]
fn write_u8(&mut self, i: u8) {
self.state.write_u8(i);
- self.bytes_hashed += 1;
}
#[inline]
fn write_u16(&mut self, i: u16) {
self.state.write_u16(i.to_le());
- self.bytes_hashed += 2;
}
#[inline]
fn write_u32(&mut self, i: u32) {
self.state.write_u32(i.to_le());
- self.bytes_hashed += 4;
}
#[inline]
fn write_u64(&mut self, i: u64) {
self.state.write_u64(i.to_le());
- self.bytes_hashed += 8;
}
#[inline]
fn write_u128(&mut self, i: u128) {
self.state.write_u128(i.to_le());
- self.bytes_hashed += 16;
}
#[inline]
// platforms. This is important for symbol hashes when cross compiling,
// for example.
self.state.write_u64((i as u64).to_le());
- self.bytes_hashed += 8;
}
#[inline]
fn write_i8(&mut self, i: i8) {
self.state.write_i8(i);
- self.bytes_hashed += 1;
}
#[inline]
fn write_i16(&mut self, i: i16) {
self.state.write_i16(i.to_le());
- self.bytes_hashed += 2;
}
#[inline]
fn write_i32(&mut self, i: i32) {
self.state.write_i32(i.to_le());
- self.bytes_hashed += 4;
}
#[inline]
fn write_i64(&mut self, i: i64) {
self.state.write_i64(i.to_le());
- self.bytes_hashed += 8;
}
#[inline]
fn write_i128(&mut self, i: i128) {
self.state.write_i128(i.to_le());
- self.bytes_hashed += 16;
}
#[inline]
// platforms. This is important for symbol hashes when cross compiling,
// for example.
self.state.write_i64((i as i64).to_le());
- self.bytes_hashed += 8;
}
}
/// Something that implements `HashStable<CTX>` can be hashed in a way that is
/// stable across multiple compilation sessions.
+///
+/// Note that `HashStable` imposes rather more strict requirements than usual
+/// hash functions:
+///
+/// - Stable hashes are sometimes used as identifiers. Therefore they must
+/// conform to the corresponding `PartialEq` implementations:
+///
+/// - `x == y` implies `hash_stable(x) == hash_stable(y)`, and
+/// - `x != y` implies `hash_stable(x) != hash_stable(y)`.
+///
+/// That second condition is usually not required for hash functions
+/// (e.g. `Hash`). In practice this means that `hash_stable` must feed any
+/// information into the hasher that a `PartialEq` comparision takes into
+/// account. See [#49300](https://github.com/rust-lang/rust/issues/49300)
+/// for an example where violating this invariant has caused trouble in the
+/// past.
+///
+/// - `hash_stable()` must be independent of the current
+/// compilation session. E.g. they must not hash memory addresses or other
+/// things that are "randomly" assigned per compilation session.
+///
+/// - `hash_stable()` must be independent of the host architecture. The
+/// `StableHasher` takes care of endianness and `isize`/`usize` platform
+/// differences.
pub trait HashStable<CTX> {
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut CTX,
// have to be user friendly.
let name = format!(
"hir_id_{}_{}",
- hir_id.owner.as_array_index(),
+ hir_id.owner.index(),
hir_id.local_id.index(),
);
let lcfg = LabelledCFG {
use std::sync::{Arc, Mutex};
use syntax;
use syntax::source_map::{FileLoader, SourceMap};
+use syntax_pos::edition;
pub type Result<T> = result::Result<T, ErrorReported>;
{
let stderr = config.stderr.take();
util::spawn_thread_pool(
+ config.opts.edition,
config.opts.debugging_opts.threads,
&stderr,
|| run_compiler_in_existing_thread_pool(config, f),
)
}
-pub fn default_thread_pool<F, R>(f: F) -> R
+pub fn default_thread_pool<F, R>(edition: edition::Edition, f: F) -> R
where
F: FnOnce() -> R + Send,
R: Send,
{
- util::spawn_thread_pool(None, &None, f)
+ util::spawn_thread_pool(edition, None, &None, f)
}
use syntax::util::lev_distance::find_best_match_for_name;
use syntax::symbol::Symbol;
use syntax::feature_gate::AttributeType;
-use syntax_pos::{FileName, hygiene};
+use syntax_pos::{FileName, edition::Edition, hygiene};
use syntax_ext;
use serialize::json;
pub fn parse<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate> {
sess.diagnostic()
.set_continue_after_error(sess.opts.debugging_opts.continue_parse_after_error);
- hygiene::set_default_edition(sess.edition());
-
sess.profiler(|p| p.start_activity("parsing"));
let krate = time(sess, "parsing", || match *input {
Input::File(ref file) => parse::parse_crate_from_file(file, &sess.parse_sess),
crate_loader,
&resolver_arenas,
);
- syntax_ext::register_builtins(&mut resolver, plugin_info.syntax_exts);
+ syntax_ext::register_builtins(&mut resolver, plugin_info.syntax_exts, sess.edition());
// Expand all macros
sess.profiler(|p| p.start_activity("macro expansion"));
use syntax::source_map::{FileLoader, RealFileLoader, SourceMap};
use syntax::symbol::{Symbol, sym};
use syntax::{self, ast, attr};
+use syntax_pos::edition::Edition;
#[cfg(not(parallel_compiler))]
use std::{thread, panic};
#[cfg(not(parallel_compiler))]
pub fn spawn_thread_pool<F: FnOnce() -> R + Send, R: Send>(
+ edition: Edition,
_threads: Option<usize>,
stderr: &Option<Arc<Mutex<Vec<u8>>>>,
f: F,
}
scoped_thread(cfg, || {
- syntax::with_globals( || {
+ syntax::with_globals(edition, || {
ty::tls::GCX_PTR.set(&Lock::new(0), || {
if let Some(stderr) = stderr {
io::set_panic(Some(box Sink(stderr.clone())));
#[cfg(parallel_compiler)]
pub fn spawn_thread_pool<F: FnOnce() -> R + Send, R: Send>(
+ edition: Edition,
threads: Option<usize>,
stderr: &Option<Arc<Mutex<Vec<u8>>>>,
f: F,
let with_pool = move |pool: &ThreadPool| pool.install(move || f());
- syntax::with_globals(|| {
+ syntax::with_globals(edition, || {
syntax::GLOBALS.with(|syntax_globals| {
syntax_pos::GLOBALS.with(|syntax_pos_globals| {
// The main handler runs for each Rayon worker thread and sets up
reference: "issue #46043 <https://github.com/rust-lang/rust/issues/46043>",
edition: None,
},
- FutureIncompatibleInfo {
- id: LintId::of(INCOHERENT_FUNDAMENTAL_IMPLS),
- reference: "issue #46205 <https://github.com/rust-lang/rust/issues/46205>",
- edition: None,
- },
FutureIncompatibleInfo {
id: LintId::of(ORDER_DEPENDENT_TRAIT_OBJECTS),
reference: "issue #56484 <https://github.com/rust-lang/rust/issues/56484>",
"replaced with a generic attribute input check");
store.register_removed("duplicate_matcher_binding_name",
"converted into hard error, see https://github.com/rust-lang/rust/issues/57742");
+ store.register_removed("incoherent_fundamental_impls",
+ "converted into hard error, see https://github.com/rust-lang/rust/issues/46205");
}
pub fn register_internals(store: &mut lint::LintStore, sess: Option<&Session>) {
impl<'a> LoadError<'a> {
fn report(self) -> ! {
match self {
- LoadError::LocatorError(mut locate_ctxt) => locate_ctxt.report_errs(),
+ LoadError::LocatorError(locate_ctxt) => locate_ctxt.report_errs(),
}
}
}
span,
ident,
crate_name: name,
- hash: hash.map(|a| &*a),
- extra_filename: extra_filename,
+ hash,
+ extra_filename,
filesearch: self.sess.target_filesearch(path_kind),
target: &self.sess.target.target,
triple: self.sess.opts.target_triple.clone(),
impl<'a, 'tcx> SpecializedDecoder<DefIndex> for DecodeContext<'a, 'tcx> {
#[inline]
fn specialized_decode(&mut self) -> Result<DefIndex, Self::Error> {
- Ok(DefIndex::from_raw_u32(self.read_u32()?))
+ Ok(DefIndex::from_u32(self.read_u32()?))
}
}
use syntax::attr;
use syntax::source_map::Spanned;
use syntax::symbol::{keywords, sym};
-use syntax_pos::{self, hygiene, FileName, SourceFile, Span};
+use syntax_pos::{self, FileName, SourceFile, Span};
use log::{debug, trace};
use rustc::hir::{self, PatKind};
impl<'a, 'tcx> SpecializedEncoder<DefIndex> for EncodeContext<'a, 'tcx> {
#[inline]
fn specialized_encode(&mut self, def_index: &DefIndex) -> Result<(), Self::Error> {
- self.emit_u32(def_index.as_raw_u32())
+ self.emit_u32(def_index.as_u32())
}
}
hash: tcx.crate_hash(LOCAL_CRATE),
disambiguator: tcx.sess.local_crate_disambiguator(),
panic_strategy: tcx.sess.panic_strategy(),
- edition: hygiene::default_edition(),
+ edition: tcx.sess.edition(),
has_global_allocator: has_global_allocator,
has_panic_handler: has_panic_handler,
has_default_lib_allocator: has_default_lib_allocator,
pub fn record_index(&mut self, item: DefIndex, entry: Lazy<Entry<'_>>) {
assert!(entry.position < (u32::MAX as usize));
let position = entry.position as u32;
- let array_index = item.as_array_index();
+ let array_index = item.index();
let positions = &mut self.positions;
assert!(u32::read_from_bytes_at(positions, array_index) == u32::MAX,
def_index,
self.len);
- let position = u32::read_from_bytes_at(bytes, 1 + def_index.as_array_index());
+ let position = u32::read_from_bytes_at(bytes, 1 + def_index.index());
if position == u32::MAX {
debug!("Index::lookup: position=u32::MAX");
None
}
}
- pub fn report_errs(&mut self) -> ! {
+ pub fn report_errs(self) -> ! {
let add = match self.root {
&None => String::new(),
&Some(ref r) => format!(" which `{}` depends on", r.ident),
let mut inflated = Vec::new();
match DeflateDecoder::new(compressed_bytes).read_to_end(&mut inflated) {
Ok(_) => {
- let buf = unsafe { OwningRef::new_assert_stable_address(inflated) };
- rustc_erase_owner!(buf.map_owner_box())
+ rustc_erase_owner!(OwningRef::new(inflated).map_owner_box())
}
Err(_) => {
return Err(format!("failed to decompress metadata: {}", filename.display()));
use rustc::ty::{self, RegionKind, RegionVid, Ty, TyCtxt};
use rustc::ty::print::RegionHighlightMode;
use rustc_errors::DiagnosticBuilder;
-use syntax::ast::Name;
use syntax::symbol::keywords;
use syntax_pos::Span;
use syntax_pos::symbol::InternedString;
}
#[allow(dead_code)]
- crate fn name(&self) -> &InternedString {
- &self.name
+ crate fn name(&self) -> InternedString {
+ self.name
}
crate fn highlight_region_name(
match error_region {
ty::ReEarlyBound(ebr) => {
if ebr.has_name() {
- let span = self.get_named_span(tcx, error_region, &ebr.name);
+ let span = self.get_named_span(tcx, error_region, ebr.name);
Some(RegionName {
name: ebr.name,
source: RegionNameSource::NamedEarlyBoundRegion(span)
ty::ReFree(free_region) => match free_region.bound_region {
ty::BoundRegion::BrNamed(_, name) => {
- let span = self.get_named_span(tcx, error_region, &name);
+ let span = self.get_named_span(tcx, error_region, name);
Some(RegionName {
name,
source: RegionNameSource::NamedFreeRegion(span),
&self,
tcx: TyCtxt<'_, '_, 'tcx>,
error_region: &RegionKind,
- name: &InternedString,
+ name: InternedString,
) -> Span {
let scope = error_region.free_region_binding_scope(tcx);
let node = tcx.hir().as_local_hir_id(scope).unwrap_or(hir::DUMMY_HIR_ID);
let c = *counter;
*counter += 1;
- Name::intern(&format!("'{:?}", c)).as_interned_str()
+ InternedString::intern(&format!("'{:?}", c))
}
}
trace!("{:?} is now live", local);
let local_val = LocalValue::Uninitialized;
- // StorageLive *always* kills the value that's currently stored
+ // StorageLive *always* kills the value that's currently stored.
+ // However, we do not error if the variable already is live;
+ // see <https://github.com/rust-lang/rust/issues/42371>.
Ok(mem::replace(&mut self.frame_mut().locals[local].value, local_val))
}
use std::fmt::{self, Write};
use std::iter;
use rustc::mir::mono::Linkage;
-use syntax_pos::symbol::Symbol;
+use syntax_pos::symbol::InternedString;
use syntax::source_map::Span;
pub use rustc::mir::mono::MonoItem;
MonoItem::GlobalAsm(hir_id) => {
let def_id = tcx.hir().local_def_id_from_hir_id(hir_id);
ty::SymbolName {
- name: Symbol::intern(&format!("global_asm_{:?}", def_id)).as_interned_str()
+ name: InternedString::intern(&format!("global_asm_{:?}", def_id))
}
}
}
use rustc::mir::*;
use rustc::mir::visit::{PlaceContext, Visitor, MutatingUseContext};
-use syntax::symbol::{Symbol, sym};
+use syntax::symbol::{InternedString, sym};
use std::ops::Bound;
(CastTy::FnPtr, CastTy::Int(_)) => {
self.register_violations(&[UnsafetyViolation {
source_info: self.source_info,
- description: Symbol::intern("cast of pointer to int").as_interned_str(),
- details: Symbol::intern("casting pointers to integers in constants")
- .as_interned_str(),
+ description: InternedString::intern("cast of pointer to int"),
+ details: InternedString::intern(
+ "casting pointers to integers in constants"),
kind: UnsafetyViolationKind::General,
}], &[]);
},
if let ty::RawPtr(_) | ty::FnPtr(..) = lhs.ty(self.mir, self.tcx).sty {
self.register_violations(&[UnsafetyViolation {
source_info: self.source_info,
- description: Symbol::intern("pointer operation").as_interned_str(),
- details: Symbol::intern("operations on pointers in constants")
- .as_interned_str(),
+ description: InternedString::intern("pointer operation"),
+ details: InternedString::intern("operations on pointers in constants"),
kind: UnsafetyViolationKind::General,
}], &[]);
}
self.source_scope_local_data[source_info.scope].lint_root;
self.register_violations(&[UnsafetyViolation {
source_info,
- description: Symbol::intern("borrow of packed field").as_interned_str(),
- details:
- Symbol::intern("fields of packed structs might be misaligned: \
- dereferencing a misaligned pointer or even just \
- creating a misaligned reference is undefined \
- behavior")
- .as_interned_str(),
+ description: InternedString::intern("borrow of packed field"),
+ details: InternedString::intern(
+ "fields of packed structs might be misaligned: dereferencing a \
+ misaligned pointer or even just creating a misaligned reference \
+ is undefined behavior"),
kind: UnsafetyViolationKind::BorrowPacked(lint_root)
}], &[]);
}
self.source_scope_local_data[source_info.scope].lint_root;
self.register_violations(&[UnsafetyViolation {
source_info,
- description: Symbol::intern("use of extern static").as_interned_str(),
- details:
- Symbol::intern("extern statics are not controlled by the Rust type \
- system: invalid data, aliasing violations or data \
- races will cause undefined behavior")
- .as_interned_str(),
+ description: InternedString::intern("use of extern static"),
+ details: InternedString::intern(
+ "extern statics are not controlled by the Rust type system: invalid \
+ data, aliasing violations or data races will cause undefined behavior"),
kind: UnsafetyViolationKind::ExternStatic(lint_root)
}], &[]);
}
let source_info = self.source_info;
self.register_violations(&[UnsafetyViolation {
source_info,
- description: Symbol::intern(description).as_interned_str(),
- details: Symbol::intern(details).as_interned_str(),
+ description: InternedString::intern(description),
+ details: InternedString::intern(details),
kind,
}], &[]);
}
let source_info = self.source_info;
self.register_violations(&[UnsafetyViolation {
source_info,
- description: Symbol::intern(description).as_interned_str(),
- details: Symbol::intern(details).as_interned_str(),
+ description: InternedString::intern(description),
+ details: InternedString::intern(details),
kind: UnsafetyViolationKind::GeneralAndConstFn,
}], &[]);
}
use rustc::hir::def::DefKind;
use rustc::mir::{
- Constant, Location, Place, PlaceBase, Mir, Operand, Rvalue, Local,
+ AggregateKind, Constant, Location, Place, PlaceBase, Mir, Operand, Rvalue, Local,
NullOp, UnOp, StatementKind, Statement, LocalKind, Static, StaticKind,
TerminatorKind, Terminator, ClearCrossCrate, SourceInfo, BinOp, ProjectionElem,
SourceScope, SourceScopeLocalData, LocalDecl, Promoted,
};
-use rustc::mir::visit::{Visitor, PlaceContext, MutatingUseContext, NonMutatingUseContext};
+use rustc::mir::visit::{
+ Visitor, PlaceContext, MutatingUseContext, MutVisitor, NonMutatingUseContext,
+};
use rustc::mir::interpret::{InterpError, Scalar, GlobalId, EvalResult};
use rustc::ty::{self, Instance, ParamEnv, Ty, TyCtxt};
-use syntax::source_map::DUMMY_SP;
+use syntax_pos::{Span, DUMMY_SP};
use rustc::ty::subst::InternalSubsts;
use rustc_data_structures::indexed_vec::IndexVec;
use rustc::ty::layout::{
HasTyCtxt, TargetDataLayout, HasDataLayout,
};
-use crate::interpret::{InterpretCx, ScalarMaybeUndef, Immediate, OpTy, ImmTy, MemoryKind};
+use crate::interpret::{self, InterpretCx, ScalarMaybeUndef, Immediate, OpTy, ImmTy, MemoryKind};
use crate::const_eval::{
CompileTimeInterpreter, error_to_const_error, eval_promoted, mk_eval_cx,
};
},
}
}
+
+ fn operand_from_scalar(&self, scalar: Scalar, ty: Ty<'tcx>, span: Span) -> Operand<'tcx> {
+ Operand::Constant(Box::new(
+ Constant {
+ span,
+ ty,
+ user_ty: None,
+ literal: self.tcx.mk_const(ty::Const::from_scalar(
+ scalar,
+ ty,
+ ))
+ }
+ ))
+ }
+
+ fn replace_with_const(&self, rval: &mut Rvalue<'tcx>, value: Const<'tcx>, span: Span) {
+ self.ecx.validate_operand(
+ value,
+ vec![],
+ None,
+ true,
+ ).expect("value should already be a valid const");
+
+ if let interpret::Operand::Immediate(im) = *value {
+ match im {
+ interpret::Immediate::Scalar(ScalarMaybeUndef::Scalar(scalar)) => {
+ *rval = Rvalue::Use(self.operand_from_scalar(scalar, value.layout.ty, span));
+ },
+ Immediate::ScalarPair(
+ ScalarMaybeUndef::Scalar(one),
+ ScalarMaybeUndef::Scalar(two)
+ ) => {
+ let ty = &value.layout.ty.sty;
+ if let ty::Tuple(substs) = ty {
+ *rval = Rvalue::Aggregate(
+ Box::new(AggregateKind::Tuple),
+ vec![
+ self.operand_from_scalar(one, substs[0].expect_ty(), span),
+ self.operand_from_scalar(two, substs[1].expect_ty(), span),
+ ],
+ );
+ }
+ },
+ _ => { }
+ }
+ }
+ }
+
+ fn should_const_prop(&self) -> bool {
+ self.tcx.sess.opts.debugging_opts.mir_opt_level >= 2
+ }
}
fn type_size_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
}
-impl<'b, 'a, 'tcx> Visitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> {
+impl<'b, 'a, 'tcx> MutVisitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> {
fn visit_constant(
&mut self,
- constant: &Constant<'tcx>,
+ constant: &mut Constant<'tcx>,
location: Location,
) {
trace!("visit_constant: {:?}", constant);
fn visit_statement(
&mut self,
- statement: &Statement<'tcx>,
+ statement: &mut Statement<'tcx>,
location: Location,
) {
trace!("visit_statement: {:?}", statement);
- if let StatementKind::Assign(ref place, ref rval) = statement.kind {
+ if let StatementKind::Assign(ref place, ref mut rval) = statement.kind {
let place_ty: Ty<'tcx> = place
.ty(&self.local_decls, self.tcx)
.ty;
trace!("storing {:?} to {:?}", value, local);
assert!(self.places[local].is_none());
self.places[local] = Some(value);
+
+ if self.should_const_prop() {
+ self.replace_with_const(rval, value, statement.source_info.span);
+ }
}
}
}
fn visit_terminator(
&mut self,
- terminator: &Terminator<'tcx>,
+ terminator: &mut Terminator<'tcx>,
location: Location,
) {
self.super_terminator(terminator, location);
- let source_info = terminator.source_info;;
- if let TerminatorKind::Assert { expected, msg, cond, .. } = &terminator.kind {
- if let Some(value) = self.eval_operand(&cond, source_info) {
- trace!("assertion on {:?} should be {:?}", value, expected);
- let expected = ScalarMaybeUndef::from(Scalar::from_bool(*expected));
- if expected != self.ecx.read_scalar(value).unwrap() {
- // poison all places this operand references so that further code
- // doesn't use the invalid value
- match cond {
- Operand::Move(ref place) | Operand::Copy(ref place) => {
- let mut place = place;
- while let Place::Projection(ref proj) = *place {
- place = &proj.base;
- }
- if let Place::Base(PlaceBase::Local(local)) = *place {
- self.places[local] = None;
+ let source_info = terminator.source_info;
+ match &mut terminator.kind {
+ TerminatorKind::Assert { expected, msg, ref mut cond, .. } => {
+ if let Some(value) = self.eval_operand(&cond, source_info) {
+ trace!("assertion on {:?} should be {:?}", value, expected);
+ let expected = ScalarMaybeUndef::from(Scalar::from_bool(*expected));
+ let value_const = self.ecx.read_scalar(value).unwrap();
+ if expected != value_const {
+ // poison all places this operand references so that further code
+ // doesn't use the invalid value
+ match cond {
+ Operand::Move(ref place) | Operand::Copy(ref place) => {
+ let mut place = place;
+ while let Place::Projection(ref proj) = *place {
+ place = &proj.base;
+ }
+ if let Place::Base(PlaceBase::Local(local)) = *place {
+ self.places[local] = None;
+ }
+ },
+ Operand::Constant(_) => {}
+ }
+ let span = terminator.source_info.span;
+ let hir_id = self
+ .tcx
+ .hir()
+ .as_local_hir_id(self.source.def_id())
+ .expect("some part of a failing const eval must be local");
+ use rustc::mir::interpret::InterpError::*;
+ let msg = match msg {
+ Overflow(_) |
+ OverflowNeg |
+ DivisionByZero |
+ RemainderByZero => msg.description().to_owned(),
+ BoundsCheck { ref len, ref index } => {
+ let len = self
+ .eval_operand(len, source_info)
+ .expect("len must be const");
+ let len = match self.ecx.read_scalar(len) {
+ Ok(ScalarMaybeUndef::Scalar(Scalar::Bits {
+ bits, ..
+ })) => bits,
+ other => bug!("const len not primitive: {:?}", other),
+ };
+ let index = self
+ .eval_operand(index, source_info)
+ .expect("index must be const");
+ let index = match self.ecx.read_scalar(index) {
+ Ok(ScalarMaybeUndef::Scalar(Scalar::Bits {
+ bits, ..
+ })) => bits,
+ other => bug!("const index not primitive: {:?}", other),
+ };
+ format!(
+ "index out of bounds: \
+ the len is {} but the index is {}",
+ len,
+ index,
+ )
+ },
+ // Need proper const propagator for these
+ _ => return,
+ };
+ self.tcx.lint_hir(
+ ::rustc::lint::builtin::CONST_ERR,
+ hir_id,
+ span,
+ &msg,
+ );
+ } else {
+ if self.should_const_prop() {
+ if let ScalarMaybeUndef::Scalar(scalar) = value_const {
+ *cond = self.operand_from_scalar(
+ scalar,
+ self.tcx.types.bool,
+ source_info.span,
+ );
}
- },
- Operand::Constant(_) => {}
+ }
}
- let span = terminator.source_info.span;
- let hir_id = self
- .tcx
- .hir()
- .as_local_hir_id(self.source.def_id())
- .expect("some part of a failing const eval must be local");
- use rustc::mir::interpret::InterpError::*;
- let msg = match msg {
- Overflow(_) |
- OverflowNeg |
- DivisionByZero |
- RemainderByZero => msg.description().to_owned(),
- BoundsCheck { ref len, ref index } => {
- let len = self
- .eval_operand(len, source_info)
- .expect("len must be const");
- let len = match self.ecx.read_scalar(len) {
- Ok(ScalarMaybeUndef::Scalar(Scalar::Bits {
- bits, ..
- })) => bits,
- other => bug!("const len not primitive: {:?}", other),
- };
- let index = self
- .eval_operand(index, source_info)
- .expect("index must be const");
- let index = match self.ecx.read_scalar(index) {
- Ok(ScalarMaybeUndef::Scalar(Scalar::Bits {
- bits, ..
- })) => bits,
- other => bug!("const index not primitive: {:?}", other),
- };
- format!(
- "index out of bounds: \
- the len is {} but the index is {}",
- len,
- index,
- )
- },
- // Need proper const propagator for these
- _ => return,
- };
- self.tcx.lint_hir(
- ::rustc::lint::builtin::CONST_ERR,
- hir_id,
- span,
- &msg,
- );
}
- }
+ },
+ TerminatorKind::SwitchInt { ref mut discr, switch_ty, .. } => {
+ if self.should_const_prop() {
+ if let Some(value) = self.eval_operand(&discr, source_info) {
+ if let ScalarMaybeUndef::Scalar(scalar) =
+ self.ecx.read_scalar(value).unwrap() {
+ *discr = self.operand_from_scalar(scalar, switch_ty, source_info.span);
+ }
+ }
+ }
+ },
+ //none of these have Operands to const-propagate
+ TerminatorKind::Goto { .. } |
+ TerminatorKind::Resume |
+ TerminatorKind::Abort |
+ TerminatorKind::Return |
+ TerminatorKind::Unreachable |
+ TerminatorKind::Drop { .. } |
+ TerminatorKind::DropAndReplace { .. } |
+ TerminatorKind::Yield { .. } |
+ TerminatorKind::GeneratorDrop |
+ TerminatorKind::FalseEdges { .. } |
+ TerminatorKind::FalseUnwind { .. } => { }
+ //FIXME(wesleywiser) Call does have Operands that could be const-propagated
+ TerminatorKind::Call { .. } => { }
}
}
}
format!(
"{}_{}",
def_id.krate.index(),
- def_id.index.as_array_index(),
+ def_id.index.index(),
)
}
use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT, IdentTT};
use syntax::ext::base::MacroExpanderFn;
-use syntax::ext::hygiene;
use syntax::symbol::{Symbol, sym};
use syntax::ast;
use syntax::feature_gate::AttributeType;
allow_internal_unsafe: false,
local_inner_macros: false,
unstable_feature: None,
- edition: hygiene::default_edition(),
+ edition: self.sess.edition(),
});
}
Ident::new(keywords::SelfLower.name(), new_span)
),
kind: ast::UseTreeKind::Simple(
- Some(Ident::new(Name::gensym("__dummy"), new_span)),
+ Some(Ident::from_str_and_span("__dummy", new_span).gensym()),
ast::DUMMY_NODE_ID,
ast::DUMMY_NODE_ID,
),
.collect();
if !attr::contains_name(&krate.attrs, sym::no_core) {
- extern_prelude.insert(Ident::from_str("core"), Default::default());
+ extern_prelude.insert(Ident::with_empty_ctxt(sym::core), Default::default());
if !attr::contains_name(&krate.attrs, sym::no_std) {
- extern_prelude.insert(Ident::from_str("std"), Default::default());
+ extern_prelude.insert(Ident::with_empty_ctxt(sym::std), Default::default());
if session.rust_2018() {
- extern_prelude.insert(Ident::from_str("meta"), Default::default());
+ extern_prelude.insert(Ident::with_empty_ctxt(sym::meta), Default::default());
}
}
}
self.trait_map.insert(id, traits);
}
- let mut std_path = vec![Segment::from_ident(Ident::from_str("std"))];
+ let mut std_path = vec![Segment::from_ident(Ident::with_empty_ctxt(sym::std))];
std_path.extend(path);
if self.primitive_type_table.primitive_types.contains_key(&path[0].ident.name) {
let cl = CrateLint::No;
let add_module_candidates = |module: Module<'_>, names: &mut Vec<TypoSuggestion>| {
for (&(ident, _), resolution) in module.resolutions.borrow().iter() {
if let Some(binding) = resolution.borrow().binding {
- if !ident.name.is_gensymed() && filter_fn(binding.res()) {
+ if !ident.is_gensymed() && filter_fn(binding.res()) {
names.push(TypoSuggestion {
candidate: ident.name,
article: binding.res().article(),
for rib in self.ribs[ns].iter().rev() {
// Locals and type parameters
for (ident, &res) in &rib.bindings {
- if !ident.name.is_gensymed() && filter_fn(res) {
+ if !ident.is_gensymed() && filter_fn(res) {
names.push(TypoSuggestion {
candidate: ident.name,
article: res.article(),
},
);
- if !ident.name.is_gensymed() && filter_fn(crate_mod) {
+ if !ident.is_gensymed() && filter_fn(crate_mod) {
Some(TypoSuggestion {
candidate: ident.name,
article: "a",
names.extend(
self.primitive_type_table.primitive_types
.iter()
- .filter(|(name, _)| !name.is_gensymed())
.map(|(name, _)| {
TypoSuggestion {
candidate: *name,
use syntax::ext::base::{self, Determinacy};
use syntax::ext::base::{MacroKind, SyntaxExtension};
use syntax::ext::expand::{AstFragment, Invocation, InvocationKind};
-use syntax::ext::hygiene::{self, Mark};
+use syntax::ext::hygiene::Mark;
use syntax::ext::tt::macro_rules;
use syntax::feature_gate::{
feature_err, is_builtin_attr_name, AttributeGate, GateIssue, Stability, BUILTIN_ATTRIBUTES,
fn add_builtin(&mut self, ident: ast::Ident, ext: Lrc<SyntaxExtension>) {
let def_id = DefId {
krate: CrateNum::BuiltinMacros,
- index: DefIndex::from_array_index(self.macro_map.len()),
+ index: DefIndex::from(self.macro_map.len()),
};
let kind = ext.kind();
self.macro_map.insert(def_id, ext);
let def_id = self.definitions.local_def_id(item.id);
let ext = Lrc::new(macro_rules::compile(&self.session.parse_sess,
&self.session.features_untracked(),
- item, hygiene::default_edition()));
+ item, self.session.edition()));
self.macro_map.insert(def_id, ext);
let def = match item.node { ast::ItemKind::MacroDef(ref def) => def, _ => unreachable!() };
// so they can cause name conflict errors downstream.
let is_good_import = binding.is_import() && !binding.is_ambiguity() &&
// Note that as_str() de-gensyms the Symbol
- !(ident.name.is_gensymed() && ident.name.as_str() != "_");
+ !(ident.is_gensymed() && ident.name.as_str() != "_");
if is_good_import || binding.is_macro_def() {
let res = binding.res();
if res != Res::Err {
fn id_from_def_id(id: DefId) -> rls_data::Id {
rls_data::Id {
krate: id.krate.as_u32(),
- index: id.index.as_raw_u32(),
+ index: id.index.as_u32(),
}
}
}
// Prohibit explicit lifetime arguments if late-bound lifetime parameters are present.
+ let mut reported_late_bound_region_err = None;
if !infer_lifetimes {
if let Some(span_late) = def.has_late_bound_regions {
let msg = "cannot specify lifetime arguments explicitly \
let mut err = tcx.sess.struct_span_err(span, msg);
err.span_note(span_late, note);
err.emit();
- return (true, None);
+ reported_late_bound_region_err = Some(true);
} else {
let mut multispan = MultiSpan::from_span(span);
multispan.push_span_label(span_late, note.to_string());
tcx.lint_hir(lint::builtin::LATE_BOUND_LIFETIME_ARGUMENTS,
args.args[0].id(), multispan, msg);
- return (false, None);
+ reported_late_bound_region_err = Some(false);
}
}
}
// For kinds without defaults (i.e., lifetimes), `required == permitted`.
// For other kinds (i.e., types), `permitted` may be greater than `required`.
if required <= provided && provided <= permitted {
- return (false, None);
+ return (reported_late_bound_region_err.unwrap_or(false), None);
}
// Unfortunately lifetime and type parameter mismatches are typically styled
potential_assoc_types)
};
- if !infer_lifetimes || arg_counts.lifetimes > param_counts.lifetimes {
+ if reported_late_bound_region_err.is_none()
+ && (!infer_lifetimes || arg_counts.lifetimes > param_counts.lifetimes) {
check_kind_count(
"lifetime",
param_counts.lifetimes,
arg_counts.lifetimes,
)
} else {
- (false, None)
+ (reported_late_bound_region_err.unwrap_or(false), None)
}
}
use crate::require_same_types;
use rustc_target::spec::abi::Abi;
-use syntax::symbol::Symbol;
+use syntax::symbol::InternedString;
use rustc::hir;
/// and in libcore/intrinsics.rs
pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
it: &hir::ForeignItem) {
- let param = |n| tcx.mk_ty_param(n, Symbol::intern(&format!("P{}", n)).as_interned_str());
+ let param = |n| tcx.mk_ty_param(n, InternedString::intern(&format!("P{}", n)));
let name = it.ident.as_str();
let mk_va_list_ty = || {
pub fn check_platform_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
it: &hir::ForeignItem) {
let param = |n| {
- let name = Symbol::intern(&format!("P{}", n)).as_interned_str();
+ let name = InternedString::intern(&format!("P{}", n));
tcx.mk_ty_param(n, name)
};
};
if let Some(missing_trait) = missing_trait {
if op.node == hir::BinOpKind::Add &&
- self.check_str_addition(expr, lhs_expr, rhs_expr, lhs_ty,
- rhs_ty, &mut err, true, op) {
+ self.check_str_addition(
+ lhs_expr, rhs_expr, lhs_ty, rhs_ty, &mut err, true, op) {
// This has nothing here because it means we did string
// concatenation (e.g., "Hello " += "World!"). This means
// we don't want the note in the else clause to be emitted
};
if let Some(missing_trait) = missing_trait {
if op.node == hir::BinOpKind::Add &&
- self.check_str_addition(expr, lhs_expr, rhs_expr, lhs_ty,
- rhs_ty, &mut err, false, op) {
+ self.check_str_addition(
+ lhs_expr, rhs_expr, lhs_ty, rhs_ty, &mut err, false, op) {
// This has nothing here because it means we did string
// concatenation (e.g., "Hello " + "World!"). This means
// we don't want the note in the else clause to be emitted
false
}
+ /// Provide actionable suggestions when trying to add two strings with incorrect types,
+ /// like `&str + &str`, `String + String` and `&str + &String`.
+ ///
+ /// If this function returns `true` it means a note was printed, so we don't need
+ /// to print the normal "implementation of `std::ops::Add` might be missing" note
fn check_str_addition(
&self,
- expr: &'gcx hir::Expr,
lhs_expr: &'gcx hir::Expr,
rhs_expr: &'gcx hir::Expr,
lhs_ty: Ty<'tcx>,
op: hir::BinOp,
) -> bool {
let source_map = self.tcx.sess.source_map();
+ let remove_borrow_msg = "String concatenation appends the string on the right to the \
+ string on the left and may require reallocation. This \
+ requires ownership of the string on the left";
+
let msg = "`to_owned()` can be used to create an owned `String` \
from a string reference. String concatenation \
appends the string on the right to the string \
on the left and may require reallocation. This \
requires ownership of the string on the left";
- // If this function returns true it means a note was printed, so we don't need
- // to print the normal "implementation of `std::ops::Add` might be missing" note
+
+ let is_std_string = |ty| &format!("{:?}", ty) == "std::string::String";
+
match (&lhs_ty.sty, &rhs_ty.sty) {
- (&Ref(_, l_ty, _), &Ref(_, r_ty, _))
- if l_ty.sty == Str && r_ty.sty == Str => {
- if !is_assign {
- err.span_label(op.span,
- "`+` can't be used to concatenate two `&str` strings");
+ (&Ref(_, l_ty, _), &Ref(_, r_ty, _)) // &str or &String + &str, &String or &&str
+ if (l_ty.sty == Str || is_std_string(l_ty)) && (
+ r_ty.sty == Str || is_std_string(r_ty) ||
+ &format!("{:?}", rhs_ty) == "&&str"
+ ) =>
+ {
+ if !is_assign { // Do not supply this message if `&str += &str`
+ err.span_label(
+ op.span,
+ "`+` cannot be used to concatenate two `&str` strings",
+ );
match source_map.span_to_snippet(lhs_expr.span) {
- Ok(lstring) => err.span_suggestion(
- lhs_expr.span,
- msg,
- format!("{}.to_owned()", lstring),
- Applicability::MachineApplicable,
- ),
+ Ok(lstring) => {
+ err.span_suggestion(
+ lhs_expr.span,
+ if lstring.starts_with("&") {
+ remove_borrow_msg
+ } else {
+ msg
+ },
+ if lstring.starts_with("&") {
+ // let a = String::new();
+ // let _ = &a + "bar";
+ format!("{}", &lstring[1..])
+ } else {
+ format!("{}.to_owned()", lstring)
+ },
+ Applicability::MachineApplicable,
+ )
+ }
_ => err.help(msg),
};
}
true
}
- (&Ref(_, l_ty, _), &Adt(..))
- if l_ty.sty == Str && &format!("{:?}", rhs_ty) == "std::string::String" => {
- err.span_label(expr.span,
- "`+` can't be used to concatenate a `&str` with a `String`");
+ (&Ref(_, l_ty, _), &Adt(..)) // Handle `&str` & `&String` + `String`
+ if (l_ty.sty == Str || is_std_string(l_ty)) && is_std_string(rhs_ty) =>
+ {
+ err.span_label(
+ op.span,
+ "`+` cannot be used to concatenate a `&str` with a `String`",
+ );
match (
source_map.span_to_snippet(lhs_expr.span),
source_map.span_to_snippet(rhs_expr.span),
is_assign,
) {
(Ok(l), Ok(r), false) => {
+ let to_string = if l.starts_with("&") {
+ // let a = String::new(); let b = String::new();
+ // let _ = &a + b;
+ format!("{}", &l[1..])
+ } else {
+ format!("{}.to_owned()", l)
+ };
err.multipart_suggestion(
msg,
vec![
- (lhs_expr.span, format!("{}.to_owned()", l)),
+ (lhs_expr.span, to_string),
(rhs_expr.span, format!("&{}", r)),
],
Applicability::MachineApplicable,
continue;
}
+ // If the extern crate is renamed, then we cannot suggest replacing it with a use as this
+ // would not insert the new name into the prelude, where other imports in the crate may be
+ // expecting it.
+ if extern_crate.orig_name.is_some() {
+ continue;
+ }
+
// If the extern crate has any attributes, they may have funky
// semantics we can't faithfully represent using `use` (most
// notably `#[macro_use]`). Ignore it.
use rustc::traits::{self, IntercrateMode};
use rustc::ty::TyCtxt;
-use crate::lint;
-
pub fn crate_inherent_impls_overlap_check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
crate_num: CrateNum) {
assert_eq!(crate_num, LOCAL_CRATE);
impl<'a, 'tcx> InherentOverlapChecker<'a, 'tcx> {
fn check_for_common_items_in_impls(&self, impl1: DefId, impl2: DefId,
- overlap: traits::OverlapResult<'_>,
- used_to_be_allowed: bool) {
+ overlap: traits::OverlapResult<'_>) {
let name_and_namespace = |def_id| {
let item = self.tcx.associated_item(def_id);
for &item2 in &impl_items2[..] {
if (name, namespace) == name_and_namespace(item2) {
- let hir_id = self.tcx.hir().as_local_hir_id(impl1);
- let mut err = if used_to_be_allowed && hir_id.is_some() {
- self.tcx.struct_span_lint_hir(
- lint::builtin::INCOHERENT_FUNDAMENTAL_IMPLS,
- hir_id.unwrap(),
- self.tcx.span_of_impl(item1).unwrap(),
- &format!("duplicate definitions with name `{}` (E0592)", name)
- )
- } else {
+ let mut err =
struct_span_err!(self.tcx.sess,
self.tcx.span_of_impl(item1).unwrap(),
E0592,
"duplicate definitions with name `{}`",
- name)
- };
-
+ name);
err.span_label(self.tcx.span_of_impl(item1).unwrap(),
format!("duplicate definitions for `{}`", name));
err.span_label(self.tcx.span_of_impl(item2).unwrap(),
for (i, &impl1_def_id) in impls.iter().enumerate() {
for &impl2_def_id in &impls[(i + 1)..] {
- let used_to_be_allowed = traits::overlapping_impls(
+ traits::overlapping_impls(
self.tcx,
impl1_def_id,
impl2_def_id,
impl1_def_id,
impl2_def_id,
overlap,
- false,
);
false
},
|| true,
);
-
- if used_to_be_allowed {
- traits::overlapping_impls(
- self.tcx,
- impl1_def_id,
- impl2_def_id,
- IntercrateMode::Fixed,
- |overlap| self.check_for_common_items_in_impls(
- impl1_def_id,
- impl2_def_id,
- overlap,
- true,
- ),
- || (),
- );
- }
}
}
}
use syntax::attr::{InlineAttr, OptimizeAttr, list_contains_name, mark_used};
use syntax::source_map::Spanned;
use syntax::feature_gate;
-use syntax::symbol::{keywords, Symbol, sym};
+use syntax::symbol::{InternedString, keywords, Symbol, sym};
use syntax_pos::{Span, DUMMY_SP};
use rustc::hir::def::{CtorKind, Res, DefKind};
.enumerate()
.map(|(i, &arg)| ty::GenericParamDef {
index: type_start + i as u32,
- name: Symbol::intern(arg).as_interned_str(),
+ name: InternedString::intern(arg),
def_id,
pure_wrt_drop: false,
kind: ty::GenericParamDefKind::Type {
params.extend(upvars.iter().zip((dummy_args.len() as u32)..).map(|(_, i)| {
ty::GenericParamDef {
index: type_start + i,
- name: Symbol::intern("<upvar>").as_interned_str(),
+ name: InternedString::intern("<upvar>"),
def_id,
pure_wrt_drop: false,
kind: ty::GenericParamDefKind::Type {
use syntax::attr;
use syntax::source_map::dummy_spanned;
use syntax::symbol::Symbol;
- use syntax::with_globals;
+ use syntax::with_default_globals;
fn word_cfg(s: &str) -> Cfg {
Cfg::Cfg(Symbol::intern(s), None)
#[test]
fn test_cfg_not() {
- with_globals(|| {
+ with_default_globals(|| {
assert_eq!(!Cfg::False, Cfg::True);
assert_eq!(!Cfg::True, Cfg::False);
assert_eq!(!word_cfg("test"), Cfg::Not(Box::new(word_cfg("test"))));
#[test]
fn test_cfg_and() {
- with_globals(|| {
+ with_default_globals(|| {
let mut x = Cfg::False;
x &= Cfg::True;
assert_eq!(x, Cfg::False);
#[test]
fn test_cfg_or() {
- with_globals(|| {
+ with_default_globals(|| {
let mut x = Cfg::True;
x |= Cfg::False;
assert_eq!(x, Cfg::True);
#[test]
fn test_parse_ok() {
- with_globals(|| {
+ with_default_globals(|| {
let mi = dummy_meta_item_word("all");
assert_eq!(Cfg::parse(&mi), Ok(word_cfg("all")));
#[test]
fn test_parse_err() {
- with_globals(|| {
+ with_default_globals(|| {
let mi = attr::mk_name_value_item(
DUMMY_SP,
Ident::from_str("foo"),
#[test]
fn test_render_short_html() {
- with_globals(|| {
+ with_default_globals(|| {
assert_eq!(
word_cfg("unix").render_short_html(),
"Unix"
#[test]
fn test_render_long_html() {
- with_globals(|| {
+ with_default_globals(|| {
assert_eq!(
word_cfg("unix").render_long_html(),
"This is supported on <strong>Unix</strong> only."
for attr in attrs.lists(sym::target_feature) {
if attr.check_name(sym::enable) {
if let Some(feat) = attr.value_str() {
- let meta = attr::mk_name_value_item_str(Ident::from_str("target_feature"),
- dummy_spanned(feat));
+ let meta = attr::mk_name_value_item_str(
+ Ident::with_empty_ctxt(sym::target_feature),
+ dummy_spanned(feat));
if let Ok(feat_cfg) = Cfg::parse(&meta) {
cfg &= feat_cfg;
}
fn clean(&self, cx: &DocContext<'_>) -> Constant {
Constant {
type_: self.ty.clean(cx),
- expr: format!("{:?}", self.val), // FIXME(const_generics)
+ expr: match self.val {
+ ConstValue::Param(ty::ParamConst { name, .. }) => format!("{}", name),
+ e => format!("{:?}", e), // FIXME generic consts with expressions
+ },
}
}
}
pub locol: usize,
pub hiline: usize,
pub hicol: usize,
+ pub original: syntax_pos::Span,
}
impl Span {
filename: FileName::Anon(0),
loline: 0, locol: 0,
hiline: 0, hicol: 0,
+ original: syntax_pos::DUMMY_SP,
}
}
+
+ pub fn span(&self) -> syntax_pos::Span {
+ self.original
+ }
}
impl Clean<Span> for syntax_pos::Span {
locol: lo.col.to_usize(),
hiline: hi.line,
hicol: hi.col.to_usize(),
+ original: *self,
}
}
}
use rustc::session::search_paths::SearchPath;
use rustc_driver;
use rustc_target::spec::TargetTriple;
-use syntax::edition::Edition;
+use syntax::edition::{Edition, DEFAULT_EDITION};
use crate::core::new_handler;
use crate::externalfiles::ExternalHtml;
}
}
+ let edition = if let Some(e) = matches.opt_str("edition") {
+ match e.parse() {
+ Ok(e) => e,
+ Err(_) => {
+ diag.struct_err("could not parse edition").emit();
+ return Err(1);
+ }
+ }
+ } else {
+ DEFAULT_EDITION
+ };
+
let mut id_map = html::markdown::IdMap::new();
id_map.populate(html::render::initial_ids());
let external_html = match ExternalHtml::load(
&matches.opt_strs("html-before-content"),
&matches.opt_strs("html-after-content"),
&matches.opt_strs("markdown-before-content"),
- &matches.opt_strs("markdown-after-content"), &diag, &mut id_map) {
+ &matches.opt_strs("markdown-after-content"),
+ &diag, &mut id_map, edition) {
Some(eh) => eh,
None => return Err(3),
};
- let edition = matches.opt_str("edition").unwrap_or("2015".to_string());
- let edition = match edition.parse() {
- Ok(e) => e,
- Err(_) => {
- diag.struct_err("could not parse edition").emit();
- return Err(1);
- }
- };
-
match matches.opt_str("r").as_ref().map(|s| &**s) {
Some("rust") | None => {}
Some(s) => {
"passes",
];
- for flag in deprecated_flags.into_iter() {
+ for flag in deprecated_flags.iter() {
if matches.opt_present(flag) {
let mut err = diag.struct_warn(&format!("the '{}' flag is considered deprecated",
flag));
crate_num,
DefId {
krate: crate_num,
- index: DefIndex::from_array_index(def_id.index.as_array_index() + 1),
+ index: DefIndex::from(def_id.index.index() + 1),
},
);
use std::str;
use errors;
use crate::syntax::feature_gate::UnstableFeatures;
+use crate::syntax::edition::Edition;
use crate::html::markdown::{IdMap, ErrorCodes, Markdown};
use std::cell::RefCell;
impl ExternalHtml {
pub fn load(in_header: &[String], before_content: &[String], after_content: &[String],
md_before_content: &[String], md_after_content: &[String], diag: &errors::Handler,
- id_map: &mut IdMap)
+ id_map: &mut IdMap, edition: Edition)
-> Option<ExternalHtml> {
let codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build());
load_external_files(in_header, diag)
.and_then(|(ih, bc)|
load_external_files(md_before_content, diag)
.map(|m_bc| (ih,
- format!("{}{}", bc, Markdown(&m_bc, &[], RefCell::new(id_map), codes))))
+ format!("{}{}", bc, Markdown(&m_bc, &[], RefCell::new(id_map),
+ codes, edition))))
)
.and_then(|(ih, bc)|
load_external_files(after_content, diag)
.and_then(|(ih, bc, ac)|
load_external_files(md_after_content, diag)
.map(|m_ac| (ih, bc,
- format!("{}{}", ac, Markdown(&m_ac, &[], RefCell::new(id_map), codes))))
+ format!("{}{}", ac, Markdown(&m_ac, &[], RefCell::new(id_map),
+ codes, edition))))
)
.map(|(ih, bc, ac)|
ExternalHtml {
impl fmt::Display for clean::Constant {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- fmt::Display::fmt(&self.expr, f)?;
- f.write_str(": ")?;
- fmt::Display::fmt(&self.type_, f)
+ fmt::Display::fmt(&self.expr, f)
}
}
let p = SlashChecker(&p);
if layout.logo.is_empty() {
format!("<a href='{path}index.html'>\
- <img src='{static_root_path}rust-logo{suffix}.png' \
- alt='logo' width='100'></a>",
+ <div class='logo-container'>\
+ <img src='{static_root_path}rust-logo{suffix}.png' alt='logo'></div></a>",
path=p,
static_root_path=static_root_path,
suffix=page.resource_suffix)
} else {
format!("<a href='{}index.html'>\
- <img src='{}' alt='logo' width='100'></a>",
+ <div class='logo-container'><img src='{}' alt='logo'></div></a>",
p,
layout.logo)
}
//! ```
//! #![feature(rustc_private)]
//!
+//! extern crate syntax;
+//!
+//! use syntax::edition::Edition;
//! use rustdoc::html::markdown::{IdMap, Markdown, ErrorCodes};
//! use std::cell::RefCell;
//!
//! let s = "My *markdown* _text_";
//! let mut id_map = IdMap::new();
-//! let html = format!("{}", Markdown(s, &[], RefCell::new(&mut id_map), ErrorCodes::Yes));
+//! let html = format!("{}", Markdown(s, &[], RefCell::new(&mut id_map),
+//! ErrorCodes::Yes, Edition::Edition2015));
//! // ... something using html
//! ```
/// A unit struct which has the `fmt::Display` trait implemented. When
/// formatted, this struct will emit the HTML corresponding to the rendered
/// version of the contained markdown string.
-/// The second parameter is a list of link replacements
+///
+/// The second parameter is a list of link replacements.
+///
+/// The third is the current list of used header IDs.
+///
+/// The fourth is whether to allow the use of explicit error codes in doctest lang strings.
+///
+/// The fifth is what default edition to use when parsing doctests (to add a `fn main`).
pub struct Markdown<'a>(
- pub &'a str, pub &'a [(String, String)], pub RefCell<&'a mut IdMap>, pub ErrorCodes);
+ pub &'a str, pub &'a [(String, String)], pub RefCell<&'a mut IdMap>, pub ErrorCodes, pub Edition);
/// A unit struct like `Markdown`, that renders the markdown with a
/// table of contents.
-pub struct MarkdownWithToc<'a>(pub &'a str, pub RefCell<&'a mut IdMap>, pub ErrorCodes);
+pub struct MarkdownWithToc<'a>(pub &'a str, pub RefCell<&'a mut IdMap>, pub ErrorCodes, pub Edition);
/// A unit struct like `Markdown`, that renders the markdown escaping HTML tags.
-pub struct MarkdownHtml<'a>(pub &'a str, pub RefCell<&'a mut IdMap>, pub ErrorCodes);
+pub struct MarkdownHtml<'a>(pub &'a str, pub RefCell<&'a mut IdMap>, pub ErrorCodes, pub Edition);
/// A unit struct like `Markdown`, that renders only the first paragraph.
pub struct MarkdownSummaryLine<'a>(pub &'a str, pub &'a [(String, String)]);
struct CodeBlocks<'a, I: Iterator<Item = Event<'a>>> {
inner: I,
check_error_codes: ErrorCodes,
+ edition: Edition,
}
impl<'a, I: Iterator<Item = Event<'a>>> CodeBlocks<'a, I> {
- fn new(iter: I, error_codes: ErrorCodes) -> Self {
+ fn new(iter: I, error_codes: ErrorCodes, edition: Edition) -> Self {
CodeBlocks {
inner: iter,
check_error_codes: error_codes,
+ edition,
}
}
}
return event;
}
+ let explicit_edition = edition.is_some();
+ let edition = edition.unwrap_or(self.edition);
+
let mut origtext = String::new();
for event in &mut self.inner {
match event {
.collect::<Vec<Cow<'_, str>>>().join("\n");
let krate = krate.as_ref().map(|s| &**s);
let (test, _) = test::make_test(&test, krate, false,
- &Default::default());
+ &Default::default(), edition);
let channel = if test.contains("#![feature(") {
"&version=nightly"
} else {
""
};
- let edition_string = if let Some(e @ Edition::Edition2018) = edition {
- format!("&edition={}{}", e,
- if channel == "&version=nightly" { "" }
- else { "&version=nightly" })
- } else if let Some(e) = edition {
- format!("&edition={}", e)
- } else {
- "".to_owned()
- };
+ let edition_string = format!("&edition={}", edition);
// These characters don't need to be escaped in a URI.
// FIXME: use a library function for percent encoding.
Some(("This example is not tested".to_owned(), "ignore"))
} else if compile_fail {
Some(("This example deliberately fails to compile".to_owned(), "compile_fail"))
- } else if let Some(e) = edition {
- Some((format!("This code runs with edition {}", e), "edition"))
+ } else if explicit_edition {
+ Some((format!("This code runs with edition {}", edition), "edition"))
} else {
None
};
Some(&format!("rust-example-rendered{}",
if ignore { " ignore" }
else if compile_fail { " compile_fail" }
- else if edition.is_some() { " edition " }
+ else if explicit_edition { " edition " }
else { "" })),
playground_button.as_ref().map(String::as_str),
Some((s1.as_str(), s2))));
Some(&format!("rust-example-rendered{}",
if ignore { " ignore" }
else if compile_fail { " compile_fail" }
- else if edition.is_some() { " edition " }
+ else if explicit_edition { " edition " }
else { "" })),
playground_button.as_ref().map(String::as_str),
None));
impl<'a> fmt::Display for Markdown<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
- let Markdown(md, links, ref ids, codes) = *self;
+ let Markdown(md, links, ref ids, codes, edition) = *self;
let mut ids = ids.borrow_mut();
// This is actually common enough to special-case
let p = HeadingLinks::new(p, None, &mut ids);
let p = LinkReplacer::new(p, links);
- let p = CodeBlocks::new(p, codes);
+ let p = CodeBlocks::new(p, codes, edition);
let p = Footnotes::new(p);
html::push_html(&mut s, p);
impl<'a> fmt::Display for MarkdownWithToc<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
- let MarkdownWithToc(md, ref ids, codes) = *self;
+ let MarkdownWithToc(md, ref ids, codes, edition) = *self;
let mut ids = ids.borrow_mut();
let p = Parser::new_ext(md, opts());
{
let p = HeadingLinks::new(p, Some(&mut toc), &mut ids);
- let p = CodeBlocks::new(p, codes);
+ let p = CodeBlocks::new(p, codes, edition);
let p = Footnotes::new(p);
html::push_html(&mut s, p);
}
impl<'a> fmt::Display for MarkdownHtml<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
- let MarkdownHtml(md, ref ids, codes) = *self;
+ let MarkdownHtml(md, ref ids, codes, edition) = *self;
let mut ids = ids.borrow_mut();
// This is actually common enough to special-case
let mut s = String::with_capacity(md.len() * 3 / 2);
let p = HeadingLinks::new(p, None, &mut ids);
- let p = CodeBlocks::new(p, codes);
+ let p = CodeBlocks::new(p, codes, edition);
let p = Footnotes::new(p);
html::push_html(&mut s, p);
use super::{ErrorCodes, LangString, Markdown, MarkdownHtml, IdMap};
use super::plain_summary_line;
use std::cell::RefCell;
- use syntax::edition::Edition;
+ use syntax::edition::{Edition, DEFAULT_EDITION};
#[test]
fn test_lang_string_parse() {
fn test_header() {
fn t(input: &str, expect: &str) {
let mut map = IdMap::new();
- let output = Markdown(input, &[], RefCell::new(&mut map), ErrorCodes::Yes).to_string();
+ let output = Markdown(input, &[], RefCell::new(&mut map),
+ ErrorCodes::Yes, DEFAULT_EDITION).to_string();
assert_eq!(output, expect, "original: {}", input);
}
fn test_header_ids_multiple_blocks() {
let mut map = IdMap::new();
fn t(map: &mut IdMap, input: &str, expect: &str) {
- let output = Markdown(input, &[], RefCell::new(map), ErrorCodes::Yes).to_string();
+ let output = Markdown(input, &[], RefCell::new(map),
+ ErrorCodes::Yes, DEFAULT_EDITION).to_string();
assert_eq!(output, expect, "original: {}", input);
}
fn test_markdown_html_escape() {
fn t(input: &str, expect: &str) {
let mut idmap = IdMap::new();
- let output = MarkdownHtml(input, RefCell::new(&mut idmap), ErrorCodes::Yes).to_string();
+ let output = MarkdownHtml(input, RefCell::new(&mut idmap),
+ ErrorCodes::Yes, DEFAULT_EDITION).to_string();
assert_eq!(output, expect, "original: {}", input);
}
use errors;
use serialize::json::{ToJson, Json, as_json};
use syntax::ast;
+use syntax::edition::Edition;
use syntax::ext::base::MacroKind;
use syntax::source_map::FileName;
use syntax::feature_gate::UnstableFeatures;
/// publicly reused items to redirect to the right location.
pub render_redirect_pages: bool,
pub codes: ErrorCodes,
+ /// The default edition used to parse doctests.
+ pub edition: Edition,
/// The map used to ensure all generated 'id=' attributes are unique.
id_map: Rc<RefCell<IdMap>>,
pub shared: Arc<SharedContext>,
"methods",
"deref-methods",
"implementations",
- ].into_iter().map(|id| (String::from(*id))).collect()
+ ].iter().map(|id| (String::from(*id))).collect()
}
/// Generates the documentation for `crate` into the directory `dst`
options: RenderOptions,
passes: FxHashSet<String>,
renderinfo: RenderInfo,
- diag: &errors::Handler) -> Result<(), Error> {
+ diag: &errors::Handler,
+ edition: Edition) -> Result<(), Error> {
// need to save a copy of the options for rendering the index page
let md_opts = options.clone();
let RenderOptions {
dst,
render_redirect_pages: false,
codes: ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build()),
+ edition,
id_map: Rc::new(RefCell::new(id_map)),
shared: Arc::new(scx),
};
md_opts.output = cx.dst.clone();
md_opts.external_html = (*cx.shared).layout.external_html.clone();
- crate::markdown::render(index_page, md_opts, diag);
+ crate::markdown::render(index_page, md_opts, diag, cx.edition);
} else {
let dst = cx.dst.join("index.html");
let mut w = BufWriter::new(try_err!(File::create(&dst), &dst));
if is_hidden { " hidden" } else { "" },
prefix,
Markdown(md_text, &links, RefCell::new(&mut ids),
- cx.codes))
+ cx.codes, cx.edition))
}
fn document_short(
if let Some(note) = note {
let mut ids = cx.id_map.borrow_mut();
- let html = MarkdownHtml(¬e, RefCell::new(&mut ids), error_codes);
+ let html = MarkdownHtml(¬e, RefCell::new(&mut ids), error_codes, cx.edition);
message.push_str(&format!(": {}", html));
}
stability.push(format!("<div class='stab deprecated'>{}</div>", message));
message = format!(
"<details><summary>{}</summary>{}</details>",
message,
- MarkdownHtml(&unstable_reason, RefCell::new(&mut ids), error_codes)
+ MarkdownHtml(&unstable_reason, RefCell::new(&mut ids), error_codes, cx.edition)
);
}
fn item_constant(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
c: &clean::Constant) -> fmt::Result {
write!(w, "<pre class='rust const'>")?;
- render_attributes(w, it)?;
+ render_attributes(w, it, false)?;
write!(w, "{vis}const \
{name}: {typ}</pre>",
vis = VisSpace(&it.visibility),
fn item_static(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
s: &clean::Static) -> fmt::Result {
write!(w, "<pre class='rust static'>")?;
- render_attributes(w, it)?;
+ render_attributes(w, it, false)?;
write!(w, "{vis}static {mutability}\
{name}: {typ}</pre>",
vis = VisSpace(&it.visibility),
f.generics
).len();
write!(w, "{}<pre class='rust fn'>", render_spotlight_traits(it)?)?;
- render_attributes(w, it)?;
+ render_attributes(w, it, false)?;
write!(w,
"{vis}{constness}{unsafety}{asyncness}{abi}fn \
{name}{generics}{decl}{where_clause}</pre>",
// Output the trait definition
wrap_into_docblock(w, |w| {
write!(w, "<pre class='rust trait'>")?;
- render_attributes(w, it)?;
+ render_attributes(w, it, true)?;
write!(w, "{}{}{}trait {}{}{}",
VisSpace(&it.visibility),
UnsafetySpace(t.unsafety),
it: &clean::Item,
ty: &clean::Type,
_default: Option<&String>,
- link: AssocItemLink<'_>) -> fmt::Result {
- write!(w, "{}const <a href='{}' class=\"constant\"><b>{}</b></a>: {}",
+ link: AssocItemLink<'_>,
+ extra: &str) -> fmt::Result {
+ write!(w, "{}{}const <a href='{}' class=\"constant\"><b>{}</b></a>: {}",
+ extra,
VisSpace(&it.visibility),
naive_assoc_href(it, link),
it.name.as_ref().unwrap(),
fn assoc_type<W: fmt::Write>(w: &mut W, it: &clean::Item,
bounds: &[clean::GenericBound],
default: Option<&clean::Type>,
- link: AssocItemLink<'_>) -> fmt::Result {
- write!(w, "type <a href='{}' class=\"type\">{}</a>",
+ link: AssocItemLink<'_>,
+ extra: &str) -> fmt::Result {
+ write!(w, "{}type <a href='{}' class=\"type\">{}</a>",
+ extra,
naive_assoc_href(it, link),
it.name.as_ref().unwrap())?;
if !bounds.is_empty() {
} else {
(0, true)
};
- render_attributes(w, meth)?;
+ render_attributes(w, meth, false)?;
write!(w, "{}{}{}{}{}{}{}fn <a href='{href}' class='fnname'>{name}</a>\
{generics}{decl}{where_clause}",
if parent == ItemType::Trait { " " } else { "" },
method(w, item, m.header, &m.generics, &m.decl, link, parent)
}
clean::AssociatedConstItem(ref ty, ref default) => {
- assoc_const(w, item, ty, default.as_ref(), link)
+ assoc_const(w, item, ty, default.as_ref(), link,
+ if parent == ItemType::Trait { " " } else { "" })
}
clean::AssociatedTypeItem(ref bounds, ref default) => {
- assoc_type(w, item, bounds, default.as_ref(), link)
+ assoc_type(w, item, bounds, default.as_ref(), link,
+ if parent == ItemType::Trait { " " } else { "" })
}
_ => panic!("render_assoc_item called on non-associated-item")
}
s: &clean::Struct) -> fmt::Result {
wrap_into_docblock(w, |w| {
write!(w, "<pre class='rust struct'>")?;
- render_attributes(w, it)?;
+ render_attributes(w, it, true)?;
render_struct(w,
it,
Some(&s.generics),
s: &clean::Union) -> fmt::Result {
wrap_into_docblock(w, |w| {
write!(w, "<pre class='rust union'>")?;
- render_attributes(w, it)?;
+ render_attributes(w, it, true)?;
render_union(w,
it,
Some(&s.generics),
e: &clean::Enum) -> fmt::Result {
wrap_into_docblock(w, |w| {
write!(w, "<pre class='rust enum'>")?;
- render_attributes(w, it)?;
+ render_attributes(w, it, true)?;
write!(w, "{}enum {}{}{}",
VisSpace(&it.visibility),
it.name.as_ref().unwrap(),
sym::non_exhaustive
];
-fn render_attributes(w: &mut dyn fmt::Write, it: &clean::Item) -> fmt::Result {
+// The `top` parameter is used when generating the item declaration to ensure it doesn't have a
+// left padding. For example:
+//
+// #[foo] <----- "top" attribute
+// struct Foo {
+// #[bar] <---- not "top" attribute
+// bar: usize,
+// }
+fn render_attributes(w: &mut dyn fmt::Write, it: &clean::Item, top: bool) -> fmt::Result {
let mut attrs = String::new();
for attr in &it.attrs.other_attrs {
}
}
if attrs.len() > 0 {
- write!(w, "<div class=\"docblock attributes\">{}</div>", &attrs)?;
+ write!(w, "<div class=\"docblock attributes{}\">{}</div>",
+ if top { " top-attr" } else { "" }, &attrs)?;
}
Ok(())
}
out.push_str("<span class=\"where fmt-newline\"> ");
assoc_type(&mut out, it, &[],
Some(&tydef.type_),
- AssocItemLink::GotoSource(t_did, &FxHashSet::default()))?;
+ AssocItemLink::GotoSource(t_did, &FxHashSet::default()),
+ "")?;
out.push_str(";</span>");
}
}
if let clean::TypedefItem(ref tydef, _) = it.inner {
write!(w, "<span class=\"where fmt-newline\"> ")?;
assoc_type(w, it, &vec![], Some(&tydef.type_),
- AssocItemLink::Anchor(None))?;
+ AssocItemLink::Anchor(None),
+ "")?;
write!(w, ";</span>")?;
}
}
if let Some(ref dox) = cx.shared.maybe_collapsed_doc_value(&i.impl_item) {
let mut ids = cx.id_map.borrow_mut();
write!(w, "<div class='docblock'>{}</div>",
- Markdown(&*dox, &i.impl_item.links(), RefCell::new(&mut ids), cx.codes))?;
+ Markdown(&*dox, &i.impl_item.links(), RefCell::new(&mut ids),
+ cx.codes, cx.edition))?;
}
}
let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space()));
write!(w, "<h4 id='{}' class=\"{}{}\">", id, item_type, extra_class)?;
write!(w, "<code id='{}'>", ns_id)?;
- assoc_type(w, item, &Vec::new(), Some(&tydef.type_), link.anchor(&id))?;
+ assoc_type(w, item, &Vec::new(), Some(&tydef.type_), link.anchor(&id), "")?;
write!(w, "</code></h4>")?;
}
clean::AssociatedConstItem(ref ty, ref default) => {
let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space()));
write!(w, "<h4 id='{}' class=\"{}{}\">", id, item_type, extra_class)?;
write!(w, "<code id='{}'>", ns_id)?;
- assoc_const(w, item, ty, default.as_ref(), link.anchor(&id))?;
+ assoc_const(w, item, ty, default.as_ref(), link.anchor(&id), "")?;
write!(w, "</code>")?;
render_stability_since_raw(w, item.stable_since(), outer_version)?;
if let Some(l) = (Item { cx, item }).src_href() {
let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space()));
write!(w, "<h4 id='{}' class=\"{}{}\">", id, item_type, extra_class)?;
write!(w, "<code id='{}'>", ns_id)?;
- assoc_type(w, item, bounds, default.as_ref(), link.anchor(&id))?;
+ assoc_type(w, item, bounds, default.as_ref(), link.anchor(&id), "")?;
write!(w, "</code></h4>")?;
}
clean::StrippedItem(..) => return Ok(()),
t: &clean::Existential,
) -> fmt::Result {
write!(w, "<pre class='rust existential'>")?;
- render_attributes(w, it)?;
+ render_attributes(w, it, false)?;
write!(w, "existential type {}{}{where_clause}: {bounds};</pre>",
it.name.as_ref().unwrap(),
t.generics,
fn item_trait_alias(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
t: &clean::TraitAlias) -> fmt::Result {
write!(w, "<pre class='rust trait-alias'>")?;
- render_attributes(w, it)?;
+ render_attributes(w, it, false)?;
write!(w, "trait {}{}{} = {};</pre>",
it.name.as_ref().unwrap(),
t.generics,
fn item_typedef(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
t: &clean::Typedef) -> fmt::Result {
write!(w, "<pre class='rust typedef'>")?;
- render_attributes(w, it)?;
+ render_attributes(w, it, false)?;
write!(w, "type {}{}{where_clause} = {type_};</pre>",
it.name.as_ref().unwrap(),
t.generics,
fn item_foreign_type(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item) -> fmt::Result {
writeln!(w, "<pre class='rust foreigntype'>extern {{")?;
- render_attributes(w, it)?;
+ render_attributes(w, it, false)?;
write!(
w,
" {}type {};\n}}</pre>",
}
var attributesToggle = createToggleWrapper(createSimpleToggle(false));
onEachLazy(main.getElementsByClassName("attributes"), function(i_e) {
- i_e.parentNode.insertBefore(attributesToggle.cloneNode(true), i_e);
+ var attr_tog = attributesToggle.cloneNode(true);
+ if (hasClass(i_e, "top-attr") === true) {
+ addClass(attr_tog, "top-attr");
+ }
+ i_e.parentNode.insertBefore(attr_tog, i_e);
itemAttributesFunc(i_e);
});
display: none !important;
}
-.sidebar img {
+.logo-container {
+ height: 100px;
+ width: 100px;
+ position: relative;
margin: 20px auto;
display: block;
margin-top: 10px;
}
+.logo-container > img {
+ max-width: 100px;
+ max-height: 100px;
+ position: absolute;
+ left: 50%;
+ top: 50%;
+ transform: translate(-50%, -50%);
+ display: block;
+}
+
.sidebar .location {
border: 1px solid;
font-size: 17px;
transition: border-color 300ms ease;
transition: border-radius 300ms ease-in-out;
transition: box-shadow 300ms ease-in-out;
- width: calc(100% - 32px);
+ width: 100%;
}
#crate-search + .search-input {
border-radius: 0 1px 1px 0;
+ width: calc(100% - 32px);
}
.search-input:focus {
border-radius: 2px;
border: 0;
outline: 0;
- box-shadow: 0 0 8px #078dd8;
}
.search-results .desc {
opacity: 1;
}
+.information {
+ position: absolute;
+ left: -20px;
+ margin-top: 7px;
+ z-index: 1;
+}
+
+.tooltip {
+ position: relative;
+ display: inline-block;
+ cursor: pointer;
+}
+
+.tooltip .tooltiptext {
+ width: 120px;
+ display: none;
+ text-align: center;
+ padding: 5px 3px;
+ border-radius: 6px;
+ margin-left: 5px;
+ top: -5px;
+ left: 105%;
+ z-index: 10;
+}
+
+.tooltip:hover .tooltiptext {
+ display: inline;
+}
+
+.tooltip .tooltiptext::after {
+ content: " ";
+ position: absolute;
+ top: 50%;
+ left: 11px;
+ margin-top: -5px;
+ border-width: 5px;
+ border-style: solid;
+}
+
+.important-traits .tooltip .tooltiptext {
+ border: 1px solid;
+}
+
+pre.rust {
+ position: relative;
+ tab-width: 4;
+ -moz-tab-width: 4;
+}
+
+.search-failed {
+ text-align: center;
+ margin-top: 20px;
+}
+
+.search-failed > ul {
+ text-align: left;
+ max-width: 570px;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+#titles {
+ height: 35px;
+}
+
+#titles > div {
+ float: left;
+ width: 33.3%;
+ text-align: center;
+ font-size: 18px;
+ cursor: pointer;
+ border-top: 2px solid;
+}
+
+#titles > div:not(:last-child) {
+ margin-right: 1px;
+ width: calc(33.3% - 1px);
+}
+
+#titles > div > div.count {
+ display: inline-block;
+ font-size: 16px;
+}
+
+.important-traits {
+ cursor: pointer;
+ z-index: 2;
+}
+
+h4 > .important-traits {
+ position: absolute;
+ left: -44px;
+ top: 2px;
+}
+
+#all-types {
+ text-align: center;
+ border: 1px solid;
+ margin: 0 10px;
+ margin-bottom: 10px;
+ display: block;
+ border-radius: 7px;
+}
+#all-types > p {
+ margin: 5px 0;
+}
+
+#sidebar-toggle {
+ position: fixed;
+ top: 30px;
+ left: 300px;
+ z-index: 10;
+ padding: 3px;
+ border-top-right-radius: 3px;
+ border-bottom-right-radius: 3px;
+ cursor: pointer;
+ font-weight: bold;
+ transition: left .5s;
+ font-size: 1.2em;
+ border: 1px solid;
+ border-left: 0;
+}
+#source-sidebar {
+ position: fixed;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ width: 300px;
+ z-index: 1;
+ overflow: auto;
+ transition: left .5s;
+ border-right: 1px solid;
+}
+#source-sidebar > .title {
+ font-size: 1.5em;
+ text-align: center;
+ border-bottom: 1px solid;
+ margin-bottom: 6px;
+}
+
+.theme-picker {
+ position: absolute;
+ left: 211px;
+ top: 19px;
+}
+
+.theme-picker button {
+ outline: none;
+}
+
+#settings-menu {
+ position: absolute;
+ right: 0;
+ top: 10px;
+ outline: none;
+}
+
+#theme-picker, #settings-menu {
+ padding: 4px;
+ width: 27px;
+ height: 29px;
+ border: 1px solid;
+ border-radius: 3px;
+ cursor: pointer;
+}
+
+#theme-choices {
+ display: none;
+ position: absolute;
+ left: 0;
+ top: 28px;
+ border: 1px solid;
+ border-radius: 3px;
+ z-index: 1;
+ cursor: pointer;
+}
+
+#theme-choices > button {
+ border: none;
+ width: 100%;
+ padding: 4px;
+ text-align: center;
+ background: rgba(0,0,0,0);
+}
+
+#theme-choices > button:not(:first-child) {
+ border-top: 1px solid;
+}
+
/* Media Queries */
@media (max-width: 700px) {
padding: 0;
}
- .sidebar img {
+ .sidebar .logo-container {
width: 35px;
+ height: 35px;
margin-top: 5px;
margin-bottom: 5px;
float: left;
margin-left: 50px;
}
+ .sidebar .logo-container > img {
+ max-width: 35px;
+ max-height: 35px;
+ }
+
.sidebar-menu {
position: fixed;
z-index: 10;
overflow: initial;
}
- #main > .line-numbers {
- margin-top: 0;
- }
-}
-
-@media print {
- nav.sub, .content .out-of-band, .collapse-toggle {
- display: none;
+ .theme-picker {
+ left: 10px;
+ top: 54px;
+ z-index: 1;
}
-}
-.information {
- position: absolute;
- left: -20px;
- margin-top: 7px;
- z-index: 1;
-}
-
-.tooltip {
- position: relative;
- display: inline-block;
- cursor: pointer;
-}
-
-.tooltip .tooltiptext {
- width: 120px;
- display: none;
- text-align: center;
- padding: 5px 3px;
- border-radius: 6px;
- margin-left: 5px;
- top: -5px;
- left: 105%;
- z-index: 10;
-}
-
-.tooltip:hover .tooltiptext {
- display: inline;
-}
-
-.tooltip .tooltiptext::after {
- content: " ";
- position: absolute;
- top: 50%;
- left: 11px;
- margin-top: -5px;
- border-width: 5px;
- border-style: solid;
-}
-
-.important-traits .tooltip .tooltiptext {
- border: 1px solid;
-}
-
-pre.rust {
- position: relative;
- tab-width: 4;
- -moz-tab-width: 4;
-}
-
-.search-failed {
- text-align: center;
- margin-top: 20px;
-}
-
-.search-failed > ul {
- text-align: left;
- max-width: 570px;
- margin-left: auto;
- margin-right: auto;
-}
-
-#titles {
- height: 35px;
-}
-
-#titles > div {
- float: left;
- width: 33.3%;
- text-align: center;
- font-size: 18px;
- cursor: pointer;
- border-top: 2px solid;
-}
-
-#titles > div:not(:last-child) {
- margin-right: 1px;
- width: calc(33.3% - 1px);
-}
-
-#titles > div > div.count {
- display: inline-block;
- font-size: 16px;
-}
-
-.important-traits {
- cursor: pointer;
- z-index: 2;
-}
-
-h4 > .important-traits {
- position: absolute;
- left: -44px;
- top: 2px;
-}
-
-#all-types {
- text-align: center;
- border: 1px solid;
- margin: 0 10px;
- margin-bottom: 10px;
- display: block;
- border-radius: 7px;
-}
-#all-types > p {
- margin: 5px 0;
-}
-
-@media (max-width: 700px) {
h4 > .important-traits {
position: absolute;
left: -22px;
#all-types {
margin: 10px;
}
+
+ #sidebar-toggle {
+ top: 100px;
+ width: 30px;
+ font-size: 1.5rem;
+ text-align: center;
+ padding: 0;
+ }
+
+ #source-sidebar {
+ z-index: 11;
+ }
+
+ #main > .line-numbers {
+ margin-top: 0;
+ }
}
+@media print {
+ nav.sub, .content .out-of-band, .collapse-toggle {
+ display: none;
+ }
+}
@media (max-width: 416px) {
#titles {
cursor: default;
}
-.theme-picker {
- position: absolute;
- left: 211px;
- top: 19px;
-}
-
-.theme-picker button {
- outline: none;
-}
-
-#settings-menu {
- position: absolute;
- right: 0;
- top: 10px;
- outline: none;
-}
-
-#theme-picker, #settings-menu {
- padding: 4px;
- width: 27px;
- height: 29px;
- border: 1px solid;
- border-radius: 3px;
- cursor: pointer;
-}
-
-#theme-choices {
- display: none;
- position: absolute;
- left: 0;
- top: 28px;
- border: 1px solid;
- border-radius: 3px;
- z-index: 1;
- cursor: pointer;
-}
-
-#theme-choices > button {
- border: none;
- width: 100%;
- padding: 4px;
- text-align: center;
- background: rgba(0,0,0,0);
-}
-
-#theme-choices > button:not(:first-child) {
- border-top: 1px solid;
-}
-
-@media (max-width: 700px) {
- .theme-picker {
- left: 10px;
- top: 54px;
- z-index: 1;
- }
-}
-
.hidden-by-impl-hider,
.hidden-by-usual-hider {
/* important because of conflicting rule for small screens */
margin-bottom: 1em;
}
-#sidebar-toggle {
- position: fixed;
- top: 30px;
- left: 300px;
- z-index: 10;
- padding: 3px;
- border-top-right-radius: 3px;
- border-bottom-right-radius: 3px;
- cursor: pointer;
- font-weight: bold;
- transition: left .5s;
- font-size: 1.2em;
- border: 1px solid;
- border-left: 0;
-}
-#source-sidebar {
- position: fixed;
- top: 0;
- bottom: 0;
- left: 0;
- width: 300px;
- z-index: 1;
- overflow: auto;
- transition: left .5s;
- border-right: 1px solid;
-}
-#source-sidebar > .title {
- font-size: 1.5em;
- text-align: center;
- border-bottom: 1px solid;
- margin-bottom: 6px;
-}
-
div.children {
padding-left: 27px;
display: none;
}
/* This part is to fix the "Expand attributes" part in the type declaration. */
-.type-decl > pre > :first-child {
+.type-decl > pre > .toggle-wrapper.toggle-attributes.top-attr {
margin-left: 0 !important;
}
-.type-decl > pre > :nth-child(2) {
+.type-decl > pre > .docblock.attributes.top-attr {
margin-left: 1.8em !important;
}
.type-decl > pre > .toggle-attributes {
color: #111;
background-color: #f0f0f0;
border-color: #000;
+ box-shadow: 0 0 0 1px #000, 0 0 0 2px transparent;
}
.search-input {
color: #111;
- box-shadow: 0 0 0 1px #000, 0 0 0 2px transparent;
background-color: #f0f0f0;
+ box-shadow: 0 0 0 1px #000, 0 0 0 2px transparent;
}
.search-input:focus {
border-color: #008dfd;
}
-#crate-search + .search-input {
- box-shadow: 1px 0 0 1px #000, 0 0 0 2px transparent;
+#crate-search + .search-input:focus {
+ box-shadow: 0 0 8px 4px #078dd8;
}
.module-item .stab {
color: #555;
background-color: white;
border-color: #e0e0e0;
- box-shadow: 0px 0 0 1px #e0e0e0, 0 0 0 2px transparent;
+ box-shadow: 0 0 0 1px #e0e0e0, 0 0 0 2px transparent;
}
.search-input {
color: #555;
- box-shadow: 0 0 0 1px #e0e0e0, 0 0 0 2px transparent;
background-color: white;
+ box-shadow: 0 0 0 1px #e0e0e0, 0 0 0 2px transparent;
}
.search-input:focus {
border-color: #66afe9;
}
-#crate-search + .search-input {
- box-shadow: 1px 0 0 1px #e0e0e0, 0 0 0 2px transparent;
+#crate-search + .search-input:focus {
+ box-shadow: 0 0 8px #078dd8;
}
.module-item .stab {
rustc_driver::set_sigpipe_handler();
env_logger::init();
let res = std::thread::Builder::new().stack_size(thread_stack_size).spawn(move || {
- rustc_interface::interface::default_thread_pool(move || {
- get_args().map(|args| main_args(&args)).unwrap_or(1)
- })
+ get_args().map(|args| main_args(&args)).unwrap_or(1)
}).unwrap().join().unwrap_or(rustc_driver::EXIT_FAILURE);
process::exit(res);
}
Ok(opts) => opts,
Err(code) => return code,
};
+ rustc_interface::interface::default_thread_pool(options.edition, move || {
+ main_options(options)
+ })
+}
+fn main_options(options: config::Options) -> i32 {
let diag = core::new_handler(options.error_format,
None,
options.debugging_options.treat_err_as_bug,
match (options.should_test, options.markdown_input()) {
(true, true) => return markdown::test(options, &diag),
(true, false) => return test::run(options),
- (false, true) => return markdown::render(options.input, options.render_options, &diag),
+ (false, true) => return markdown::render(options.input,
+ options.render_options,
+ &diag,
+ options.edition),
(false, false) => {}
}
// but we can't crates the Handler ahead of time because it's not Send
let diag_opts = (options.error_format,
options.debugging_options.treat_err_as_bug,
- options.debugging_options.ui_testing);
+ options.debugging_options.ui_testing,
+ options.edition);
let show_coverage = options.show_coverage;
rust_input(options, move |out| {
if show_coverage {
let Output { krate, passes, renderinfo, renderopts } = out;
info!("going to format");
- let (error_format, treat_err_as_bug, ui_testing) = diag_opts;
+ let (error_format, treat_err_as_bug, ui_testing, edition) = diag_opts;
let diag = core::new_handler(error_format, None, treat_err_as_bug, ui_testing);
match html::render::run(
krate,
passes.into_iter().collect(),
renderinfo,
&diag,
+ edition,
) {
Ok(_) => rustc_driver::EXIT_SUCCESS,
Err(e) => {
use errors;
use testing;
+use syntax::edition::Edition;
use syntax::source_map::DUMMY_SP;
use syntax::feature_gate::UnstableFeatures;
/// Render `input` (e.g., "foo.md") into an HTML file in `output`
/// (e.g., output = "bar" => "bar/foo.html").
-pub fn render(input: PathBuf, options: RenderOptions, diag: &errors::Handler) -> i32 {
+pub fn render(
+ input: PathBuf,
+ options: RenderOptions,
+ diag: &errors::Handler,
+ edition: Edition
+) -> i32 {
let mut output = options.output;
output.push(input.file_stem().unwrap());
output.set_extension("html");
let mut ids = IdMap::new();
let error_codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build());
let text = if !options.markdown_no_toc {
- MarkdownWithToc(text, RefCell::new(&mut ids), error_codes).to_string()
+ MarkdownWithToc(text, RefCell::new(&mut ids), error_codes, edition).to_string()
} else {
- Markdown(text, &[], RefCell::new(&mut ids), error_codes).to_string()
+ Markdown(text, &[], RefCell::new(&mut ids), error_codes, edition).to_string()
};
let err = write!(
if let Ok(res) = self.resolve(path_str, ns, ¤t_item, parent_node) {
res
} else {
- resolution_failure(cx, &item.attrs, path_str, &dox, link_range);
+ resolution_failure(cx, &item, path_str, &dox, link_range);
// This could just be a normal link or a broken link
// we could potentially check if something is
// "intra-doc-link-like" and warn in that case.
if let Ok(res) = self.resolve(path_str, ns, ¤t_item, parent_node) {
res
} else {
- resolution_failure(cx, &item.attrs, path_str, &dox, link_range);
+ resolution_failure(cx, &item, path_str, &dox, link_range);
// This could just be a normal link.
continue;
}
};
if candidates.is_empty() {
- resolution_failure(cx, &item.attrs, path_str, &dox, link_range);
+ resolution_failure(cx, &item, path_str, &dox, link_range);
// this could just be a normal link
continue;
}
} else {
ambiguity_error(
cx,
- &item.attrs,
+ &item,
path_str,
&dox,
link_range,
if let Some(res) = macro_resolve(cx, path_str) {
(res, None)
} else {
- resolution_failure(cx, &item.attrs, path_str, &dox, link_range);
+ resolution_failure(cx, &item, path_str, &dox, link_range);
continue
}
}
/// line containing the failure as a note as well.
fn resolution_failure(
cx: &DocContext<'_>,
- attrs: &Attributes,
+ item: &Item,
path_str: &str,
dox: &str,
link_range: Option<Range<usize>>,
) {
+ let hir_id = match cx.as_local_hir_id(item.def_id) {
+ Some(hir_id) => hir_id,
+ None => {
+ // If non-local, no need to check anything.
+ return;
+ }
+ };
+ let attrs = &item.attrs;
let sp = span_of_attrs(attrs);
let mut diag = cx.tcx.struct_span_lint_hir(
lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE,
- hir::CRATE_HIR_ID,
+ hir_id,
sp,
&format!("`[{}]` cannot be resolved, ignoring it...", path_str),
);
fn ambiguity_error(
cx: &DocContext<'_>,
- attrs: &Attributes,
+ item: &Item,
path_str: &str,
dox: &str,
link_range: Option<Range<usize>>,
candidates: PerNS<Option<Res>>,
) {
+ let hir_id = match cx.as_local_hir_id(item.def_id) {
+ Some(hir_id) => hir_id,
+ None => {
+ // If non-local, no need to check anything.
+ return;
+ }
+ };
+ let attrs = &item.attrs;
let sp = span_of_attrs(attrs);
let mut msg = format!("`{}` is ", path_str);
let mut diag = cx.tcx.struct_span_lint_hir(
lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE,
- hir::CRATE_HIR_ID,
+ hir_id,
sp,
&msg,
);
//! Contains information about "passes", used to modify crate information during the documentation
//! process.
-use rustc::hir;
use rustc::hir::def_id::DefId;
use rustc::lint as lint;
use rustc::middle::privacy::AccessLevels;
item: &Item,
check_missing_code: bool,
) {
- if cx.as_local_hir_id(item.def_id).is_none() {
- // If non-local, no need to check anything.
- return;
- }
+ let hir_id = match cx.as_local_hir_id(item.def_id) {
+ Some(hir_id) => hir_id,
+ None => {
+ // If non-local, no need to check anything.
+ return;
+ }
+ };
struct Tests {
found_tests: usize,
find_testable_code(&dox, &mut tests, ErrorCodes::No);
if check_missing_code == true && tests.found_tests == 0 {
+ let sp = span_of_attrs(&item.attrs).substitute_dummy(item.source.span());
let mut diag = cx.tcx.struct_span_lint_hir(
lint::builtin::MISSING_DOC_CODE_EXAMPLES,
- hir::CRATE_HIR_ID,
- span_of_attrs(&item.attrs),
+ hir_id,
+ sp,
"Missing code example in this documentation");
diag.emit();
} else if check_missing_code == false &&
!cx.renderinfo.borrow().access_levels.is_doc_reachable(item.def_id) {
let mut diag = cx.tcx.struct_span_lint_hir(
lint::builtin::PRIVATE_DOC_TESTS,
- hir::CRATE_HIR_ID,
+ hir_id,
span_of_attrs(&item.attrs),
"Documentation test in private item");
diag.emit();
use rustc::session::search_paths::SearchPath;
use rustc::util::common::ErrorReported;
use syntax::ast;
+use syntax::with_globals;
use syntax::source_map::SourceMap;
use syntax::edition::Edition;
use syntax::feature_gate::UnstableFeatures;
maybe_sysroot: Option<PathBuf>, linker: Option<PathBuf>, edition: Edition,
persist_doctests: Option<PathBuf>) {
let (test, line_offset) = match panic::catch_unwind(|| {
- make_test(test, Some(cratename), as_test_harness, opts)
+ make_test(test, Some(cratename), as_test_harness, opts, edition)
}) {
Ok((test, line_offset)) => (test, line_offset),
Err(cause) if cause.is::<errors::FatalErrorMarker>() => {
pub fn make_test(s: &str,
cratename: Option<&str>,
dont_insert_main: bool,
- opts: &TestOptions)
+ opts: &TestOptions,
+ edition: Edition)
-> (String, usize) {
let (crate_attrs, everything_else, crates) = partition_source(s);
let everything_else = everything_else.trim();
// Uses libsyntax to parse the doctest and find if there's a main fn and the extern
// crate already is included.
- let (already_has_main, already_has_extern_crate, found_macro) = crate::syntax::with_globals(|| {
+ let (already_has_main, already_has_extern_crate, found_macro) = with_globals(edition, || {
use crate::syntax::{parse::{self, ParseSess}, source_map::FilePathMapping};
use errors::emitter::EmitterWriter;
use errors::Handler;
// send all the errors that libsyntax emits directly into a `Sink` instead of stderr.
let cm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
let emitter = EmitterWriter::new(box io::sink(), None, false, false, false);
+ // FIXME(misdreavus): pass `-Z treat-err-as-bug` to the doctest parser
let handler = Handler::with_emitter(false, None, box emitter);
let sess = ParseSess::with_span_handler(handler, cm);
#[cfg(test)]
mod tests {
use super::{TestOptions, make_test};
+ use syntax::edition::DEFAULT_EDITION;
#[test]
fn make_test_basic() {
fn main() {
assert_eq!(2+2, 4);
}".to_string();
- let output = make_test(input, None, false, &opts);
+ let output = make_test(input, None, false, &opts, DEFAULT_EDITION);
assert_eq!(output, (expected, 2));
}
fn main() {
assert_eq!(2+2, 4);
}".to_string();
- let output = make_test(input, Some("asdf"), false, &opts);
+ let output = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
assert_eq!(output, (expected, 2));
}
use asdf::qwop;
assert_eq!(2+2, 4);
}".to_string();
- let output = make_test(input, Some("asdf"), false, &opts);
+ let output = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
assert_eq!(output, (expected, 3));
}
use asdf::qwop;
assert_eq!(2+2, 4);
}".to_string();
- let output = make_test(input, Some("asdf"), false, &opts);
+ let output = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
assert_eq!(output, (expected, 2));
}
use std::*;
assert_eq!(2+2, 4);
}".to_string();
- let output = make_test(input, Some("std"), false, &opts);
+ let output = make_test(input, Some("std"), false, &opts, DEFAULT_EDITION);
assert_eq!(output, (expected, 2));
}
use asdf::qwop;
assert_eq!(2+2, 4);
}".to_string();
- let output = make_test(input, Some("asdf"), false, &opts);
+ let output = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
assert_eq!(output, (expected, 2));
}
use asdf::qwop;
assert_eq!(2+2, 4);
}".to_string();
- let output = make_test(input, Some("asdf"), false, &opts);
+ let output = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
assert_eq!(output, (expected, 2));
}
use asdf::qwop;
assert_eq!(2+2, 4);
}".to_string();
- let output = make_test(input, Some("asdf"), false, &opts);
+ let output = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
assert_eq!(output, (expected, 3));
// Adding more will also bump the returned line offset.
use asdf::qwop;
assert_eq!(2+2, 4);
}".to_string();
- let output = make_test(input, Some("asdf"), false, &opts);
+ let output = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
assert_eq!(output, (expected, 4));
}
fn main() {
assert_eq!(2+2, 4);
}".to_string();
- let output = make_test(input, None, false, &opts);
+ let output = make_test(input, None, false, &opts, DEFAULT_EDITION);
assert_eq!(output, (expected, 2));
}
fn main() {
assert_eq!(2+2, 4);
}".to_string();
- let output = make_test(input, None, false, &opts);
+ let output = make_test(input, None, false, &opts, DEFAULT_EDITION);
assert_eq!(output, (expected, 1));
}
fn main() {
assert_eq!(2+2, 4);
}".to_string();
- let output = make_test(input, None, false, &opts);
+ let output = make_test(input, None, false, &opts, DEFAULT_EDITION);
assert_eq!(output, (expected, 2));
}
"#![allow(unused)]
//Ceci n'est pas une `fn main`
assert_eq!(2+2, 4);".to_string();
- let output = make_test(input, None, true, &opts);
+ let output = make_test(input, None, true, &opts, DEFAULT_EDITION);
assert_eq!(output, (expected, 1));
}
"fn main() {
assert_eq!(2+2, 4);
}".to_string();
- let output = make_test(input, None, false, &opts);
+ let output = make_test(input, None, false, &opts, DEFAULT_EDITION);
assert_eq!(output, (expected, 1));
}
assert_eq!(2+2, 4);
}".to_string();
- let output = make_test(input, None, false, &opts);
+ let output = make_test(input, None, false, &opts, DEFAULT_EDITION);
assert_eq!(output, (expected, 2));
let input =
assert_eq!(asdf::foo, 4);
}".to_string();
- let output = make_test(input, Some("asdf"), false, &opts);
+ let output = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
assert_eq!(output, (expected, 3));
}
fn main() {}
}".to_string();
- let output = make_test(input, Some("my_crate"), false, &opts);
+ let output = make_test(input, Some("my_crate"), false, &opts, DEFAULT_EDITION);
assert_eq!(output, (expected, 1));
}
}
name = "std"
version = "0.0.0"
build = "build.rs"
-license = "MIT/Apache-2.0"
+license = "MIT OR Apache-2.0"
repository = "https://github.com/rust-lang/rust.git"
description = "The Rust Standard Library"
edition = "2018"
panic_abort = { path = "../libpanic_abort" }
core = { path = "../libcore" }
libc = { version = "0.2.51", default-features = false, features = ['rustc-dep-of-std'] }
-compiler_builtins = { version = "0.1.12" }
+compiler_builtins = { version = "0.1.14" }
profiler_builtins = { path = "../libprofiler_builtins", optional = true }
unwind = { path = "../libunwind" }
hashbrown = { version = "0.3.0", features = ['rustc-dep-of-std'] }
backtrace = ["backtrace-sys"]
panic-unwind = ["panic_unwind"]
profiler = ["profiler_builtins"]
-compiler_builtins_c = ["compiler_builtins/c"]
+compiler_builtins_c = ["alloc/compiler-builtins-c"]
llvm-libunwind = ["unwind/llvm-libunwind"]
# Make panics and failed asserts immediately abort without formatting any message
/// about the allocation that failed.
///
/// The allocation error hook is a global resource.
+///
+/// [`set_alloc_error_hook`]: fn.set_alloc_error_hook.html
+/// [`take_alloc_error_hook`]: fn.take_alloc_error_hook.html
#[unstable(feature = "alloc_error_hook", issue = "51245")]
pub fn set_alloc_error_hook(hook: fn(Layout)) {
HOOK.store(hook as *mut (), Ordering::SeqCst);
/// *See also the function [`set_alloc_error_hook`].*
///
/// If no custom hook is registered, the default hook will be returned.
+///
+/// [`set_alloc_error_hook`]: fn.set_alloc_error_hook.html
#[unstable(feature = "alloc_error_hook", issue = "51245")]
pub fn take_alloc_error_hook() -> fn(Layout) {
let hook = HOOK.swap(ptr::null_mut(), Ordering::SeqCst);
///
/// This is a lower-level version of [`Entry`].
///
-/// This `enum` is constructed from the [`raw_entry`] method on [`HashMap`].
+/// This `enum` is constructed through the [`raw_entry_mut`] method on [`HashMap`],
+/// then calling one of the methods of that [`RawEntryBuilderMut`].
///
/// [`HashMap`]: struct.HashMap.html
/// [`Entry`]: enum.Entry.html
-/// [`raw_entry`]: struct.HashMap.html#method.raw_entry
+/// [`raw_entry_mut`]: struct.HashMap.html#method.raw_entry_mut
+/// [`RawEntryBuilderMut`]: struct.RawEntryBuilderMut.html
#[unstable(feature = "hash_raw_entry", issue = "56167")]
pub enum RawEntryMut<'a, K: 'a, V: 'a, S: 'a> {
/// An occupied entry.
#[stable(feature = "hashmap_default_hasher", since = "1.13.0")]
impl Default for DefaultHasher {
- /// Creates a new `DefaultHasher` using [`new`][DefaultHasher::new].
+ // FIXME: here should link `new` to [DefaultHasher::new], but it occurs intra-doc link
+ // resolution failure when re-exporting libstd items. When #56922 fixed,
+ // link `new` to [DefaultHasher::new] again.
+ /// Creates a new `DefaultHasher` using `new`.
/// See its documentation for more.
fn default() -> DefaultHasher {
DefaultHasher::new()
self.map.get_key_value(value).map(|(k, _)| k)
}
+ /// Inserts the given `value` into the set if it is not present, then
+ /// returns a reference to the value in the set.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(hash_set_entry)]
+ ///
+ /// use std::collections::HashSet;
+ ///
+ /// let mut set: HashSet<_> = [1, 2, 3].iter().cloned().collect();
+ /// assert_eq!(set.len(), 3);
+ /// assert_eq!(set.get_or_insert(2), &2);
+ /// assert_eq!(set.get_or_insert(100), &100);
+ /// assert_eq!(set.len(), 4); // 100 was inserted
+ /// ```
+ #[inline]
+ #[unstable(feature = "hash_set_entry", issue = "60896")]
+ pub fn get_or_insert(&mut self, value: T) -> &T {
+ // Although the raw entry gives us `&mut T`, we only return `&T` to be consistent with
+ // `get`. Key mutation is "raw" because you're not supposed to affect `Eq` or `Hash`.
+ self.map.raw_entry_mut().from_key(&value).or_insert(value, ()).0
+ }
+
+ /// Inserts a value computed from `f` into the set if the given `value` is
+ /// not present, then returns a reference to the value in the set.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(hash_set_entry)]
+ ///
+ /// use std::collections::HashSet;
+ ///
+ /// let mut set: HashSet<String> = ["cat", "dog", "horse"]
+ /// .iter().map(|&pet| pet.to_owned()).collect();
+ ///
+ /// assert_eq!(set.len(), 3);
+ /// for &pet in &["cat", "dog", "fish"] {
+ /// let value = set.get_or_insert_with(pet, str::to_owned);
+ /// assert_eq!(value, pet);
+ /// }
+ /// assert_eq!(set.len(), 4); // a new "fish" was inserted
+ /// ```
+ #[inline]
+ #[unstable(feature = "hash_set_entry", issue = "60896")]
+ pub fn get_or_insert_with<Q: ?Sized, F>(&mut self, value: &Q, f: F) -> &T
+ where T: Borrow<Q>,
+ Q: Hash + Eq,
+ F: FnOnce(&Q) -> T
+ {
+ // Although the raw entry gives us `&mut T`, we only return `&T` to be consistent with
+ // `get`. Key mutation is "raw" because you're not supposed to affect `Eq` or `Hash`.
+ self.map.raw_entry_mut().from_key(value).or_insert_with(|| (f(value), ())).0
+ }
+
/// Returns `true` if `self` has no elements in common with `other`.
/// This is equivalent to checking for an empty intersection.
///
#[unstable(feature = "error_type_id",
reason = "this is memory unsafe to override in user code",
issue = "60784")]
- fn type_id(&self) -> TypeId where Self: 'static {
+ fn type_id(&self, _: private::Internal) -> TypeId where Self: 'static {
TypeId::of::<Self>()
}
}
+mod private {
+ // This is a hack to prevent `type_id` from being overridden by `Error`
+ // implementations, since that can enable unsound downcasting.
+ #[unstable(feature = "error_type_id", issue = "60784")]
+ #[derive(Debug)]
+ pub struct Internal;
+}
+
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> {
/// Converts a type of [`Error`] into a box of dyn [`Error`].
///
+ /// [`Error`]: ../error/trait.Error.html
+ ///
/// # Examples
///
/// ```
/// Converts a type of [`Error`] + [`Send`] + [`Sync`] into a box of dyn [`Error`] +
/// [`Send`] + [`Sync`].
///
+ /// [`Error`]: ../error/trait.Error.html
+ ///
/// # Examples
///
/// ```
impl From<String> for Box<dyn Error + Send + Sync> {
/// Converts a [`String`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
///
+ /// [`Error`]: ../error/trait.Error.html
+ ///
/// # Examples
///
/// ```
impl From<String> for Box<dyn Error> {
/// Converts a [`String`] into a box of dyn [`Error`].
///
+ /// [`Error`]: ../error/trait.Error.html
+ ///
/// # Examples
///
/// ```
impl<'a> From<&str> for Box<dyn Error + Send + Sync + 'a> {
/// Converts a [`str`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
///
+ /// [`Error`]: ../error/trait.Error.html
+ ///
/// # Examples
///
/// ```
impl From<&str> for Box<dyn Error> {
/// Converts a [`str`] into a box of dyn [`Error`].
///
+ /// [`Error`]: ../error/trait.Error.html
+ ///
/// # Examples
///
/// ```
impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + Send + Sync + 'a> {
/// Converts a [`Cow`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
///
+ /// [`Cow`]: ../borrow/enum.Cow.html
+ /// [`Error`]: ../error/trait.Error.html
+ ///
/// # Examples
///
/// ```
impl<'a> From<Cow<'a, str>> for Box<dyn Error> {
/// Converts a [`Cow`] into a box of dyn [`Error`].
///
+ /// [`Cow`]: ../borrow/enum.Cow.html
+ /// [`Error`]: ../error/trait.Error.html
+ ///
/// # Examples
///
/// ```
let t = TypeId::of::<T>();
// Get TypeId of the type in the trait object
- let boxed = self.type_id();
+ let boxed = self.type_id(private::Internal);
// Compare both TypeIds on equality
t == boxed
/// Converts a [`String`] into a [`OsString`].
///
/// The conversion copies the data, and includes an allocation on the heap.
+ ///
+ /// [`OsString`]: ../../std/ffi/struct.OsString.html
fn from(s: String) -> OsString {
OsString { inner: Buf::from_string(s) }
}
/// function.)
/// * `path` already exists.
///
+/// [`create_dir_all`]: fn.create_dir_all.html
+///
/// # Examples
///
/// ```no_run
/// completed, rather than the entire buffer at once. Enter `LineWriter`. It
/// does exactly that.
///
-/// Like [`BufWriter`], a `LineWriter`’s buffer will also be flushed when the
+/// Like [`BufWriter`][bufwriter], a `LineWriter`’s buffer will also be flushed when the
/// `LineWriter` goes out of scope or when its internal buffer is full.
///
/// [bufwriter]: struct.BufWriter.html
/// let stdin = io::stdin();
/// let mut stdin = stdin.lock();
///
- /// // we can't have two `&mut` references to `stdin`, so use a block
- /// // to end the borrow early.
- /// let length = {
- /// let buffer = stdin.fill_buf().unwrap();
+ /// let buffer = stdin.fill_buf().unwrap();
///
- /// // work with buffer
- /// println!("{:?}", buffer);
- ///
- /// buffer.len()
- /// };
+ /// // work with buffer
+ /// println!("{:?}", buffer);
///
/// // ensure the bytes we worked with aren't returned again later
+ /// let length = buffer.len();
/// stdin.consume(length);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(keyword = "as")]
//
-/// The keyword for casting a value to a type.
+/// Cast between types, or rename an import.
///
/// `as` is most commonly used to turn primitive types into other primitive types, but it has other
/// uses that include turning pointers into addresses, addresses into pointers, and pointers into
/// [`crate`]: keyword.crate.html
mod as_keyword { }
+#[doc(keyword = "break")]
+//
+/// Exit early from a loop.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod break_keyword { }
+
#[doc(keyword = "const")]
//
-/// The keyword for defining constants.
+/// Compile-time constants and deterministic functions.
///
/// Sometimes a certain value is used many times throughout a program, and it can become
/// inconvenient to copy it over and over. What's more, it's not always possible or desirable to
/// [Reference]: ../reference/items/constant-items.html
mod const_keyword { }
+#[doc(keyword = "continue")]
+//
+/// Skip to the next iteration of a loop.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod continue_keyword { }
+
#[doc(keyword = "crate")]
//
-/// The `crate` keyword.
+/// A Rust binary or library.
///
/// The primary use of the `crate` keyword is as a part of `extern crate` declarations, which are
/// used to specify a dependency on a crate external to the one it's declared in. Crates are the
/// [Reference]: ../reference/items/extern-crates.html
mod crate_keyword { }
+#[doc(keyword = "else")]
+//
+/// What to do when an [`if`] condition does not hold.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [`if`]: keyword.if.html
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod else_keyword { }
+
#[doc(keyword = "enum")]
//
-/// For defining enumerations.
+/// A type that can be any one of several variants.
///
/// Enums in Rust are similar to those of other compiled languages like C, but have important
/// differences that make them considerably more powerful. What Rust calls enums are more commonly
-/// known as [Algebraic Data Types] if you're coming from a functional programming background. The
-/// important detail is that each enum variant can have data to go along with it.
+/// known as [Algebraic Data Types][ADT] if you're coming from a functional programming background.
+/// The important detail is that each enum variant can have data to go along with it.
///
/// ```rust
/// # struct Coord;
///
/// For more information, take a look at the [Rust Book] or the [Reference]
///
-/// [Algebraic Data Types]: https://en.wikipedia.org/wiki/Algebraic_data_type
+/// [ADT]: https://en.wikipedia.org/wiki/Algebraic_data_type
/// [`Option`]: option/enum.Option.html
/// [Rust Book]: ../book/ch06-01-defining-an-enum.html
/// [Reference]: ../reference/items/enumerations.html
#[doc(keyword = "extern")]
//
-/// For external connections in Rust code.
+/// Link to or import external code.
///
/// The `extern` keyword is used in two places in Rust. One is in conjunction with the [`crate`]
/// keyword to make your Rust code aware of other Rust crates in your project, i.e., `extern crate
/// [Reference]: ../reference/items/external-blocks.html
mod extern_keyword { }
+#[doc(keyword = "false")]
+//
+/// A value of type [`bool`] representing logical **false**.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [`bool`]: primitive.bool.html
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod false_keyword { }
+
#[doc(keyword = "fn")]
//
-/// The keyword for defining functions.
+/// A function or function pointer.
///
/// Functions are the primary way code is executed within Rust. Function blocks, usually just
/// called functions, can be defined in a variety of different places and be assigned many
#[doc(keyword = "for")]
//
-/// The `for` keyword.
+/// Iteration with [`in`], trait implementation with [`impl`], or [higher-ranked trait bounds]
+/// (`for<'a>`).
///
/// The `for` keyword is used in many syntactic locations:
///
///
/// For more information on for-loops, see the [Rust book] or the [Reference].
///
+/// [`in`]: keyword.in.html
/// [`impl`]: keyword.impl.html
/// [higher-ranked trait bounds]: ../reference/trait-bounds.html#higher-ranked-trait-bounds
/// [`IntoIterator`]: iter/trait.IntoIterator.html
#[doc(keyword = "if")]
//
-/// If statements and expressions.
+/// Evaluate a block if a condition holds.
///
/// `if` is a familiar construct to most programmers, and is the main way you'll often do logic in
/// your code. However, unlike in most languages, `if` blocks can also act as expressions.
#[doc(keyword = "impl")]
//
-/// The implementation-defining keyword.
+/// Implement some functionality for a type.
///
/// The `impl` keyword is primarily used to define implementations on types. Inherent
/// implementations are standalone, while trait implementations are used to implement traits for
/// [book2]: ../book/ch10-02-traits.html#returning-types-that-implement-traits
mod impl_keyword { }
+#[doc(keyword = "in")]
+//
+/// Iterate over a series of values with [`for`].
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [`for`]: keyword.for.html
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod in_keyword { }
+
#[doc(keyword = "let")]
//
-/// The variable binding keyword.
+/// Bind a value to a variable.
///
/// The primary use for the `let` keyword is in `let` statements, which are used to introduce a new
/// set of variables into the current scope, as given by a pattern.
#[doc(keyword = "loop")]
//
-/// The loop-defining keyword.
+/// Loop indefinitely.
///
/// `loop` is used to define the simplest kind of loop supported in Rust. It runs the code inside
/// it until the code uses `break` or the program exits.
/// [Reference]: ../reference/expressions/loop-expr.html
mod loop_keyword { }
+#[doc(keyword = "match")]
+//
+/// Control flow based on pattern matching.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod match_keyword { }
+
+#[doc(keyword = "mod")]
+//
+/// Organize code into [modules].
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [modules]: ../reference/items/modules.html
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod mod_keyword { }
+
+#[doc(keyword = "move")]
+//
+/// Capture a [closure]'s environment by value.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [closure]: ../book/second-edition/ch13-01-closures.html
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod move_keyword { }
+
+#[doc(keyword = "mut")]
+//
+/// A mutable binding, reference, or pointer.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod mut_keyword { }
+
+#[doc(keyword = "pub")]
+//
+/// Make an item visible to others.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod pub_keyword { }
+
+#[doc(keyword = "ref")]
+//
+/// Bind by reference during pattern matching.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod ref_keyword { }
+
+#[doc(keyword = "return")]
+//
+/// Return a value from a function.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod return_keyword { }
+
+#[doc(keyword = "self")]
+//
+/// The receiver of a method, or the current module.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod self_keyword { }
+
+#[doc(keyword = "Self")]
+//
+/// The implementing type within a [`trait`] or [`impl`] block, or the current type within a type
+/// definition.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [`impl`]: keyword.impl.html
+/// [`trait`]: keyword.trait.html
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod self_upper_keyword { }
+
+#[doc(keyword = "static")]
+//
+/// A place that is valid for the duration of a program.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod static_keyword { }
+
#[doc(keyword = "struct")]
//
-/// The keyword used to define structs.
+/// A type that is composed of other types.
///
/// Structs in Rust come in three flavors: Structs with named fields, tuple structs, and unit
/// structs.
/// [book]: ../book/ch05-01-defining-structs.html
/// [reference]: ../reference/items/structs.html
mod struct_keyword { }
+
+#[doc(keyword = "super")]
+//
+/// The parent of the current [module].
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [module]: ../reference/items/modules.html
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod super_keyword { }
+
+#[doc(keyword = "trait")]
+//
+/// A common interface for a class of types.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod trait_keyword { }
+
+#[doc(keyword = "true")]
+//
+/// A value of type [`bool`] representing logical **true**.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [`bool`]: primitive.bool.html
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod true_keyword { }
+
+#[doc(keyword = "type")]
+//
+/// Define an alias for an existing type.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod type_keyword { }
+
+#[doc(keyword = "unsafe")]
+//
+/// Code or interfaces whose [memory safety] cannot be verified by the type system.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [memory safety]: ../book/ch19-01-unsafe-rust.html
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod unsafe_keyword { }
+
+#[doc(keyword = "use")]
+//
+/// Import or rename items from other crates or modules.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod use_keyword { }
+
+#[doc(keyword = "where")]
+//
+/// Add constraints that must be upheld to use an item.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod where_keyword { }
+
+#[doc(keyword = "while")]
+//
+/// Loop while a condition is upheld.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod while_keyword { }
+
+// 2018 Edition keywords
+
+#[unstable(feature = "async_await", issue = "50547")]
+#[doc(keyword = "async")]
+//
+/// Return a [`Future`] instead of blocking the current thread.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [`Future`]: ./future/trait.Future.html
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod async_keyword { }
+
+#[unstable(feature = "async_await", issue = "50547")]
+#[doc(keyword = "await")]
+//
+/// Suspend execution until the result of a [`Future`] is ready.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [`Future`]: ./future/trait.Future.html
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod await_keyword { }
+
+#[doc(keyword = "dyn")]
+//
+/// Name the type of a [trait object].
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [trait object]: ../book/ch17-02-trait-objects.html
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod dyn_keyword { }
+
+#[doc(keyword = "union")]
+//
+/// The [Rust equivalent of a C-style union][union].
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [union]: ../reference/items/unions.html
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod union_keyword { }
#![feature(libc)]
#![feature(link_args)]
#![feature(linkage)]
-#![feature(maybe_uninit)]
#![feature(needs_panic_runtime)]
#![feature(never_type)]
#![feature(nll)]
};
}
-/// Selects the first successful receive event from a number of receivers.
-///
-/// This macro is used to wait for the first event to occur on a number of
-/// receivers. It places no restrictions on the types of receivers given to
-/// this macro, this can be viewed as a heterogeneous select.
-///
-/// # Examples
-///
-/// ```
-/// #![feature(mpsc_select)]
-///
-/// use std::thread;
-/// use std::sync::mpsc;
-///
-/// // two placeholder functions for now
-/// fn long_running_thread() {}
-/// fn calculate_the_answer() -> u32 { 42 }
-///
-/// let (tx1, rx1) = mpsc::channel();
-/// let (tx2, rx2) = mpsc::channel();
-///
-/// thread::spawn(move|| { long_running_thread(); tx1.send(()).unwrap(); });
-/// thread::spawn(move|| { tx2.send(calculate_the_answer()).unwrap(); });
-///
-/// select! {
-/// _ = rx1.recv() => println!("the long running thread finished first"),
-/// answer = rx2.recv() => {
-/// println!("the answer was: {}", answer.unwrap());
-/// }
-/// }
-/// # drop(rx1.recv());
-/// # drop(rx2.recv());
-/// ```
-///
-/// For more information about select, see the `std::sync::mpsc::Select` structure.
-#[macro_export]
-#[unstable(feature = "mpsc_select", issue = "27800")]
-#[rustc_deprecated(since = "1.32.0",
- reason = "channel selection will be removed in a future release")]
-macro_rules! select {
- (
- $($name:pat = $rx:ident.$meth:ident() => $code:expr),+
- ) => ({
- use $crate::sync::mpsc::Select;
- let sel = Select::new();
- $( let mut $rx = sel.handle(&$rx); )+
- unsafe {
- $( $rx.add(); )+
- }
- let ret = sel.wait();
- $( if ret == $rx.id() { let $name = $rx.$meth(); $code } else )+
- { unreachable!() }
- })
-}
-
#[cfg(test)]
macro_rules! assert_approx_eq {
($a:expr, $b:expr) => ({
#[stable(feature = "ip_from_ip", since = "1.16.0")]
impl From<SocketAddrV4> for SocketAddr {
/// Converts a [`SocketAddrV4`] into a [`SocketAddr::V4`].
+ ///
+ /// [`SocketAddrV4`]: ../../std/net/struct.SocketAddrV4.html
+ /// [`SocketAddr::V4`]: ../../std/net/enum.SocketAddr.html#variant.V4
fn from(sock4: SocketAddrV4) -> SocketAddr {
SocketAddr::V4(sock4)
}
#[stable(feature = "ip_from_ip", since = "1.16.0")]
impl From<SocketAddrV6> for SocketAddr {
/// Converts a [`SocketAddrV6`] into a [`SocketAddr::V6`].
+ ///
+ /// [`SocketAddrV6`]: ../../std/net/struct.SocketAddrV6.html
+ /// [`SocketAddr::V6`]: ../../std/net/enum.SocketAddr.html#variant.V6
fn from(sock6: SocketAddrV6) -> SocketAddr {
SocketAddr::V6(sock6)
}
/// and creates a [`SocketAddr::V6`] for a [`IpAddr::V6`].
///
/// `u16` is treated as port of the newly created [`SocketAddr`].
+ ///
+ /// [`IpAddr`]: ../../std/net/enum.IpAddr.html
+ /// [`IpAddr::V4`]: ../../std/net/enum.IpAddr.html#variant.V4
+ /// [`IpAddr::V6`]: ../../std/net/enum.IpAddr.html#variant.V6
+ /// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html
+ /// [`SocketAddr::V4`]: ../../std/net/enum.SocketAddr.html#variant.V4
+ /// [`SocketAddr::V6`]: ../../std/net/enum.SocketAddr.html#variant.V6
fn from(pieces: (I, u16)) -> SocketAddr {
SocketAddr::new(pieces.0.into(), pieces.1)
}
//! ```
#![stable(feature = "rust1", since = "1.0.0")]
-#![allow(deprecated)] // for mpsc_select
// A description of how Rust's channel implementation works
//
// believe that there is anything fundamental that needs to change about these
// channels, however, in order to support a more efficient select().
//
+// FIXME: Select is now removed, so these factors are ready to be cleaned up!
+//
// # Conclusion
//
// And now that you've seen all the races that I found and attempted to fix,
use crate::cell::UnsafeCell;
use crate::time::{Duration, Instant};
-#[unstable(feature = "mpsc_select", issue = "27800")]
-pub use self::select::{Select, Handle};
-use self::select::StartResult;
-use self::select::StartResult::*;
-use self::blocking::SignalToken;
-
-#[cfg(all(test, not(target_os = "emscripten")))]
-mod select_tests;
-
mod blocking;
mod oneshot;
-mod select;
mod shared;
mod stream;
mod sync;
}
-impl<T> select::Packet for Receiver<T> {
- fn can_recv(&self) -> bool {
- loop {
- let new_port = match *unsafe { self.inner() } {
- Flavor::Oneshot(ref p) => {
- match p.can_recv() {
- Ok(ret) => return ret,
- Err(upgrade) => upgrade,
- }
- }
- Flavor::Stream(ref p) => {
- match p.can_recv() {
- Ok(ret) => return ret,
- Err(upgrade) => upgrade,
- }
- }
- Flavor::Shared(ref p) => return p.can_recv(),
- Flavor::Sync(ref p) => return p.can_recv(),
- };
- unsafe {
- mem::swap(self.inner_mut(),
- new_port.inner_mut());
- }
- }
- }
-
- fn start_selection(&self, mut token: SignalToken) -> StartResult {
- loop {
- let (t, new_port) = match *unsafe { self.inner() } {
- Flavor::Oneshot(ref p) => {
- match p.start_selection(token) {
- oneshot::SelSuccess => return Installed,
- oneshot::SelCanceled => return Abort,
- oneshot::SelUpgraded(t, rx) => (t, rx),
- }
- }
- Flavor::Stream(ref p) => {
- match p.start_selection(token) {
- stream::SelSuccess => return Installed,
- stream::SelCanceled => return Abort,
- stream::SelUpgraded(t, rx) => (t, rx),
- }
- }
- Flavor::Shared(ref p) => return p.start_selection(token),
- Flavor::Sync(ref p) => return p.start_selection(token),
- };
- token = t;
- unsafe {
- mem::swap(self.inner_mut(), new_port.inner_mut());
- }
- }
- }
-
- fn abort_selection(&self) -> bool {
- let mut was_upgrade = false;
- loop {
- let result = match *unsafe { self.inner() } {
- Flavor::Oneshot(ref p) => p.abort_selection(),
- Flavor::Stream(ref p) => p.abort_selection(was_upgrade),
- Flavor::Shared(ref p) => return p.abort_selection(was_upgrade),
- Flavor::Sync(ref p) => return p.abort_selection(),
- };
- let new_port = match result { Ok(b) => return b, Err(p) => p };
- was_upgrade = true;
- unsafe {
- mem::swap(self.inner_mut(),
- new_port.inner_mut());
- }
- }
- }
-}
-
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> Iterator for Iter<'a, T> {
type Item = T;
pub use self::Failure::*;
pub use self::UpgradeResult::*;
-pub use self::SelectionResult::*;
use self::MyUpgrade::*;
use crate::sync::mpsc::Receiver;
UpWoke(SignalToken),
}
-pub enum SelectionResult<T> {
- SelCanceled,
- SelUpgraded(SignalToken, Receiver<T>),
- SelSuccess,
-}
-
enum MyUpgrade<T> {
NothingSent,
SendUsed,
// select implementation
////////////////////////////////////////////////////////////////////////////
- // If Ok, the value is whether this port has data, if Err, then the upgraded
- // port needs to be checked instead of this one.
- pub fn can_recv(&self) -> Result<bool, Receiver<T>> {
- unsafe {
- match self.state.load(Ordering::SeqCst) {
- EMPTY => Ok(false), // Welp, we tried
- DATA => Ok(true), // we have some un-acquired data
- DISCONNECTED if (*self.data.get()).is_some() => Ok(true), // we have data
- DISCONNECTED => {
- match ptr::replace(self.upgrade.get(), SendUsed) {
- // The other end sent us an upgrade, so we need to
- // propagate upwards whether the upgrade can receive
- // data
- GoUp(upgrade) => Err(upgrade),
-
- // If the other end disconnected without sending an
- // upgrade, then we have data to receive (the channel is
- // disconnected).
- up => { ptr::write(self.upgrade.get(), up); Ok(true) }
- }
- }
- _ => unreachable!(), // we're the "one blocker"
- }
- }
- }
-
- // Attempts to start selection on this port. This can either succeed, fail
- // because there is data, or fail because there is an upgrade pending.
- pub fn start_selection(&self, token: SignalToken) -> SelectionResult<T> {
- unsafe {
- let ptr = token.cast_to_usize();
- match self.state.compare_and_swap(EMPTY, ptr, Ordering::SeqCst) {
- EMPTY => SelSuccess,
- DATA => {
- drop(SignalToken::cast_from_usize(ptr));
- SelCanceled
- }
- DISCONNECTED if (*self.data.get()).is_some() => {
- drop(SignalToken::cast_from_usize(ptr));
- SelCanceled
- }
- DISCONNECTED => {
- match ptr::replace(self.upgrade.get(), SendUsed) {
- // The other end sent us an upgrade, so we need to
- // propagate upwards whether the upgrade can receive
- // data
- GoUp(upgrade) => {
- SelUpgraded(SignalToken::cast_from_usize(ptr), upgrade)
- }
-
- // If the other end disconnected without sending an
- // upgrade, then we have data to receive (the channel is
- // disconnected).
- up => {
- ptr::write(self.upgrade.get(), up);
- drop(SignalToken::cast_from_usize(ptr));
- SelCanceled
- }
- }
- }
- _ => unreachable!(), // we're the "one blocker"
- }
- }
- }
-
// Remove a previous selecting thread from this port. This ensures that the
// blocked thread will no longer be visible to any other threads.
//
+++ /dev/null
-//! Selection over an array of receivers
-//!
-//! This module contains the implementation machinery necessary for selecting
-//! over a number of receivers. One large goal of this module is to provide an
-//! efficient interface to selecting over any receiver of any type.
-//!
-//! This is achieved through an architecture of a "receiver set" in which
-//! receivers are added to a set and then the entire set is waited on at once.
-//! The set can be waited on multiple times to prevent re-adding each receiver
-//! to the set.
-//!
-//! Usage of this module is currently encouraged to go through the use of the
-//! `select!` macro. This macro allows naturally binding of variables to the
-//! received values of receivers in a much more natural syntax then usage of the
-//! `Select` structure directly.
-//!
-//! # Examples
-//!
-//! ```rust
-//! #![feature(mpsc_select)]
-//!
-//! use std::sync::mpsc::channel;
-//!
-//! let (tx1, rx1) = channel();
-//! let (tx2, rx2) = channel();
-//!
-//! tx1.send(1).unwrap();
-//! tx2.send(2).unwrap();
-//!
-//! select! {
-//! val = rx1.recv() => {
-//! assert_eq!(val.unwrap(), 1);
-//! },
-//! val = rx2.recv() => {
-//! assert_eq!(val.unwrap(), 2);
-//! }
-//! }
-//! ```
-
-#![allow(dead_code)]
-#![unstable(feature = "mpsc_select",
- reason = "This implementation, while likely sufficient, is unsafe and \
- likely to be error prone. At some point in the future this \
- module will be removed.",
- issue = "27800")]
-#![rustc_deprecated(since = "1.32.0",
- reason = "channel selection will be removed in a future release")]
-
-use core::cell::{Cell, UnsafeCell};
-use core::marker;
-use core::ptr;
-use core::usize;
-
-use crate::fmt;
-use crate::sync::mpsc::{Receiver, RecvError};
-use crate::sync::mpsc::blocking::{self, SignalToken};
-
-/// The "receiver set" of the select interface. This structure is used to manage
-/// a set of receivers which are being selected over.
-pub struct Select {
- inner: UnsafeCell<SelectInner>,
- next_id: Cell<usize>,
-}
-
-struct SelectInner {
- head: *mut Handle<'static, ()>,
- tail: *mut Handle<'static, ()>,
-}
-
-impl !marker::Send for Select {}
-
-/// A handle to a receiver which is currently a member of a `Select` set of
-/// receivers. This handle is used to keep the receiver in the set as well as
-/// interact with the underlying receiver.
-pub struct Handle<'rx, T:Send+'rx> {
- /// The ID of this handle, used to compare against the return value of
- /// `Select::wait()`.
- id: usize,
- selector: *mut SelectInner,
- next: *mut Handle<'static, ()>,
- prev: *mut Handle<'static, ()>,
- added: bool,
- packet: &'rx (dyn Packet+'rx),
-
- // due to our fun transmutes, we be sure to place this at the end. (nothing
- // previous relies on T)
- rx: &'rx Receiver<T>,
-}
-
-struct Packets { cur: *mut Handle<'static, ()> }
-
-#[doc(hidden)]
-#[derive(PartialEq, Eq)]
-pub enum StartResult {
- Installed,
- Abort,
-}
-
-#[doc(hidden)]
-pub trait Packet {
- fn can_recv(&self) -> bool;
- fn start_selection(&self, token: SignalToken) -> StartResult;
- fn abort_selection(&self) -> bool;
-}
-
-impl Select {
- /// Creates a new selection structure. This set is initially empty.
- ///
- /// Usage of this struct directly can sometimes be burdensome, and usage is much easier through
- /// the `select!` macro.
- ///
- /// # Examples
- ///
- /// ```
- /// #![feature(mpsc_select)]
- ///
- /// use std::sync::mpsc::Select;
- ///
- /// let select = Select::new();
- /// ```
- pub fn new() -> Select {
- Select {
- inner: UnsafeCell::new(SelectInner {
- head: ptr::null_mut(),
- tail: ptr::null_mut(),
- }),
- next_id: Cell::new(1),
- }
- }
-
- /// Creates a new handle into this receiver set for a new receiver. Note
- /// that this does *not* add the receiver to the receiver set, for that you
- /// must call the `add` method on the handle itself.
- pub fn handle<'a, T: Send>(&'a self, rx: &'a Receiver<T>) -> Handle<'a, T> {
- let id = self.next_id.get();
- self.next_id.set(id + 1);
- Handle {
- id,
- selector: self.inner.get(),
- next: ptr::null_mut(),
- prev: ptr::null_mut(),
- added: false,
- rx,
- packet: rx,
- }
- }
-
- /// Waits for an event on this receiver set. The returned value is *not* an
- /// index, but rather an ID. This ID can be queried against any active
- /// `Handle` structures (each one has an `id` method). The handle with
- /// the matching `id` will have some sort of event available on it. The
- /// event could either be that data is available or the corresponding
- /// channel has been closed.
- pub fn wait(&self) -> usize {
- self.wait2(true)
- }
-
- /// Helper method for skipping the preflight checks during testing
- pub(super) fn wait2(&self, do_preflight_checks: bool) -> usize {
- // Note that this is currently an inefficient implementation. We in
- // theory have knowledge about all receivers in the set ahead of time,
- // so this method shouldn't really have to iterate over all of them yet
- // again. The idea with this "receiver set" interface is to get the
- // interface right this time around, and later this implementation can
- // be optimized.
- //
- // This implementation can be summarized by:
- //
- // fn select(receivers) {
- // if any receiver ready { return ready index }
- // deschedule {
- // block on all receivers
- // }
- // unblock on all receivers
- // return ready index
- // }
- //
- // Most notably, the iterations over all of the receivers shouldn't be
- // necessary.
- unsafe {
- // Stage 1: preflight checks. Look for any packets ready to receive
- if do_preflight_checks {
- for handle in self.iter() {
- if (*handle).packet.can_recv() {
- return (*handle).id();
- }
- }
- }
-
- // Stage 2: begin the blocking process
- //
- // Create a number of signal tokens, and install each one
- // sequentially until one fails. If one fails, then abort the
- // selection on the already-installed tokens.
- let (wait_token, signal_token) = blocking::tokens();
- for (i, handle) in self.iter().enumerate() {
- match (*handle).packet.start_selection(signal_token.clone()) {
- StartResult::Installed => {}
- StartResult::Abort => {
- // Go back and abort the already-begun selections
- for handle in self.iter().take(i) {
- (*handle).packet.abort_selection();
- }
- return (*handle).id;
- }
- }
- }
-
- // Stage 3: no messages available, actually block
- wait_token.wait();
-
- // Stage 4: there *must* be message available; find it.
- //
- // Abort the selection process on each receiver. If the abort
- // process returns `true`, then that means that the receiver is
- // ready to receive some data. Note that this also means that the
- // receiver may have yet to have fully read the `to_wake` field and
- // woken us up (although the wakeup is guaranteed to fail).
- //
- // This situation happens in the window of where a sender invokes
- // increment(), sees -1, and then decides to wake up the thread. After
- // all this is done, the sending thread will set `selecting` to
- // `false`. Until this is done, we cannot return. If we were to
- // return, then a sender could wake up a receiver which has gone
- // back to sleep after this call to `select`.
- //
- // Note that it is a "fairly small window" in which an increment()
- // views that it should wake a thread up until the `selecting` bit
- // is set to false. For now, the implementation currently just spins
- // in a yield loop. This is very distasteful, but this
- // implementation is already nowhere near what it should ideally be.
- // A rewrite should focus on avoiding a yield loop, and for now this
- // implementation is tying us over to a more efficient "don't
- // iterate over everything every time" implementation.
- let mut ready_id = usize::MAX;
- for handle in self.iter() {
- if (*handle).packet.abort_selection() {
- ready_id = (*handle).id;
- }
- }
-
- // We must have found a ready receiver
- assert!(ready_id != usize::MAX);
- return ready_id;
- }
- }
-
- fn iter(&self) -> Packets { Packets { cur: unsafe { &*self.inner.get() }.head } }
-}
-
-impl<'rx, T: Send> Handle<'rx, T> {
- /// Retrieves the ID of this handle.
- #[inline]
- pub fn id(&self) -> usize { self.id }
-
- /// Blocks to receive a value on the underlying receiver, returning `Some` on
- /// success or `None` if the channel disconnects. This function has the same
- /// semantics as `Receiver.recv`
- pub fn recv(&mut self) -> Result<T, RecvError> { self.rx.recv() }
-
- /// Adds this handle to the receiver set that the handle was created from. This
- /// method can be called multiple times, but it has no effect if `add` was
- /// called previously.
- ///
- /// This method is unsafe because it requires that the `Handle` is not moved
- /// while it is added to the `Select` set.
- pub unsafe fn add(&mut self) {
- if self.added { return }
- let selector = &mut *self.selector;
- let me = self as *mut Handle<'rx, T> as *mut Handle<'static, ()>;
-
- if selector.head.is_null() {
- selector.head = me;
- selector.tail = me;
- } else {
- (*me).prev = selector.tail;
- assert!((*me).next.is_null());
- (*selector.tail).next = me;
- selector.tail = me;
- }
- self.added = true;
- }
-
- /// Removes this handle from the `Select` set. This method is unsafe because
- /// it has no guarantee that the `Handle` was not moved since `add` was
- /// called.
- pub unsafe fn remove(&mut self) {
- if !self.added { return }
-
- let selector = &mut *self.selector;
- let me = self as *mut Handle<'rx, T> as *mut Handle<'static, ()>;
-
- if self.prev.is_null() {
- assert_eq!(selector.head, me);
- selector.head = self.next;
- } else {
- (*self.prev).next = self.next;
- }
- if self.next.is_null() {
- assert_eq!(selector.tail, me);
- selector.tail = self.prev;
- } else {
- (*self.next).prev = self.prev;
- }
-
- self.next = ptr::null_mut();
- self.prev = ptr::null_mut();
-
- self.added = false;
- }
-}
-
-impl Drop for Select {
- fn drop(&mut self) {
- unsafe {
- assert!((&*self.inner.get()).head.is_null());
- assert!((&*self.inner.get()).tail.is_null());
- }
- }
-}
-
-impl<T: Send> Drop for Handle<'_, T> {
- fn drop(&mut self) {
- unsafe { self.remove() }
- }
-}
-
-impl Iterator for Packets {
- type Item = *mut Handle<'static, ()>;
-
- fn next(&mut self) -> Option<*mut Handle<'static, ()>> {
- if self.cur.is_null() {
- None
- } else {
- let ret = Some(self.cur);
- unsafe { self.cur = (*self.cur).next; }
- ret
- }
- }
-}
-
-impl fmt::Debug for Select {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("Select").finish()
- }
-}
-
-impl<T: Send> fmt::Debug for Handle<'_, T> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.debug_struct("Handle").finish()
- }
-}
+++ /dev/null
-#![allow(unused_imports)]
-
-/// This file exists to hack around https://github.com/rust-lang/rust/issues/47238
-
-use crate::thread;
-use crate::sync::mpsc::*;
-
-// Don't use the libstd version so we can pull in the right Select structure
-// (std::comm points at the wrong one)
-macro_rules! select {
- (
- $($name:pat = $rx:ident.$meth:ident() => $code:expr),+
- ) => ({
- let sel = Select::new();
- $( let mut $rx = sel.handle(&$rx); )+
- unsafe {
- $( $rx.add(); )+
- }
- let ret = sel.wait();
- $( if ret == $rx.id() { let $name = $rx.$meth(); $code } else )+
- { unreachable!() }
- })
-}
-
-#[test]
-fn smoke() {
- let (tx1, rx1) = channel::<i32>();
- let (tx2, rx2) = channel::<i32>();
- tx1.send(1).unwrap();
- select! {
- foo = rx1.recv() => { assert_eq!(foo.unwrap(), 1); },
- _bar = rx2.recv() => { panic!() }
- }
- tx2.send(2).unwrap();
- select! {
- _foo = rx1.recv() => { panic!() },
- bar = rx2.recv() => { assert_eq!(bar.unwrap(), 2) }
- }
- drop(tx1);
- select! {
- foo = rx1.recv() => { assert!(foo.is_err()); },
- _bar = rx2.recv() => { panic!() }
- }
- drop(tx2);
- select! {
- bar = rx2.recv() => { assert!(bar.is_err()); }
- }
-}
-
-#[test]
-fn smoke2() {
- let (_tx1, rx1) = channel::<i32>();
- let (_tx2, rx2) = channel::<i32>();
- let (_tx3, rx3) = channel::<i32>();
- let (_tx4, rx4) = channel::<i32>();
- let (tx5, rx5) = channel::<i32>();
- tx5.send(4).unwrap();
- select! {
- _foo = rx1.recv() => { panic!("1") },
- _foo = rx2.recv() => { panic!("2") },
- _foo = rx3.recv() => { panic!("3") },
- _foo = rx4.recv() => { panic!("4") },
- foo = rx5.recv() => { assert_eq!(foo.unwrap(), 4); }
- }
-}
-
-#[test]
-fn closed() {
- let (_tx1, rx1) = channel::<i32>();
- let (tx2, rx2) = channel::<i32>();
- drop(tx2);
-
- select! {
- _a1 = rx1.recv() => { panic!() },
- a2 = rx2.recv() => { assert!(a2.is_err()); }
- }
-}
-
-#[test]
-fn unblocks() {
- let (tx1, rx1) = channel::<i32>();
- let (_tx2, rx2) = channel::<i32>();
- let (tx3, rx3) = channel::<i32>();
-
- let _t = thread::spawn(move|| {
- for _ in 0..20 { thread::yield_now(); }
- tx1.send(1).unwrap();
- rx3.recv().unwrap();
- for _ in 0..20 { thread::yield_now(); }
- });
-
- select! {
- a = rx1.recv() => { assert_eq!(a.unwrap(), 1); },
- _b = rx2.recv() => { panic!() }
- }
- tx3.send(1).unwrap();
- select! {
- a = rx1.recv() => { assert!(a.is_err()) },
- _b = rx2.recv() => { panic!() }
- }
-}
-
-#[test]
-fn both_ready() {
- let (tx1, rx1) = channel::<i32>();
- let (tx2, rx2) = channel::<i32>();
- let (tx3, rx3) = channel::<()>();
-
- let _t = thread::spawn(move|| {
- for _ in 0..20 { thread::yield_now(); }
- tx1.send(1).unwrap();
- tx2.send(2).unwrap();
- rx3.recv().unwrap();
- });
-
- select! {
- a = rx1.recv() => { assert_eq!(a.unwrap(), 1); },
- a = rx2.recv() => { assert_eq!(a.unwrap(), 2); }
- }
- select! {
- a = rx1.recv() => { assert_eq!(a.unwrap(), 1); },
- a = rx2.recv() => { assert_eq!(a.unwrap(), 2); }
- }
- assert_eq!(rx1.try_recv(), Err(TryRecvError::Empty));
- assert_eq!(rx2.try_recv(), Err(TryRecvError::Empty));
- tx3.send(()).unwrap();
-}
-
-#[test]
-fn stress() {
- const AMT: i32 = 10000;
- let (tx1, rx1) = channel::<i32>();
- let (tx2, rx2) = channel::<i32>();
- let (tx3, rx3) = channel::<()>();
-
- let _t = thread::spawn(move|| {
- for i in 0..AMT {
- if i % 2 == 0 {
- tx1.send(i).unwrap();
- } else {
- tx2.send(i).unwrap();
- }
- rx3.recv().unwrap();
- }
- });
-
- for i in 0..AMT {
- select! {
- i1 = rx1.recv() => { assert!(i % 2 == 0 && i == i1.unwrap()); },
- i2 = rx2.recv() => { assert!(i % 2 == 1 && i == i2.unwrap()); }
- }
- tx3.send(()).unwrap();
- }
-}
-
-#[allow(unused_must_use)]
-#[test]
-fn cloning() {
- let (tx1, rx1) = channel::<i32>();
- let (_tx2, rx2) = channel::<i32>();
- let (tx3, rx3) = channel::<()>();
-
- let _t = thread::spawn(move|| {
- rx3.recv().unwrap();
- tx1.clone();
- assert_eq!(rx3.try_recv(), Err(TryRecvError::Empty));
- tx1.send(2).unwrap();
- rx3.recv().unwrap();
- });
-
- tx3.send(()).unwrap();
- select! {
- _i1 = rx1.recv() => {},
- _i2 = rx2.recv() => panic!()
- }
- tx3.send(()).unwrap();
-}
-
-#[allow(unused_must_use)]
-#[test]
-fn cloning2() {
- let (tx1, rx1) = channel::<i32>();
- let (_tx2, rx2) = channel::<i32>();
- let (tx3, rx3) = channel::<()>();
-
- let _t = thread::spawn(move|| {
- rx3.recv().unwrap();
- tx1.clone();
- assert_eq!(rx3.try_recv(), Err(TryRecvError::Empty));
- tx1.send(2).unwrap();
- rx3.recv().unwrap();
- });
-
- tx3.send(()).unwrap();
- select! {
- _i1 = rx1.recv() => {},
- _i2 = rx2.recv() => panic!()
- }
- tx3.send(()).unwrap();
-}
-
-#[test]
-fn cloning3() {
- let (tx1, rx1) = channel::<()>();
- let (tx2, rx2) = channel::<()>();
- let (tx3, rx3) = channel::<()>();
- let _t = thread::spawn(move|| {
- let s = Select::new();
- let mut h1 = s.handle(&rx1);
- let mut h2 = s.handle(&rx2);
- unsafe { h2.add(); }
- unsafe { h1.add(); }
- assert_eq!(s.wait(), h2.id());
- tx3.send(()).unwrap();
- });
-
- for _ in 0..1000 { thread::yield_now(); }
- drop(tx1.clone());
- tx2.send(()).unwrap();
- rx3.recv().unwrap();
-}
-
-#[test]
-fn preflight1() {
- let (tx, rx) = channel();
- tx.send(()).unwrap();
- select! {
- _n = rx.recv() => {}
- }
-}
-
-#[test]
-fn preflight2() {
- let (tx, rx) = channel();
- tx.send(()).unwrap();
- tx.send(()).unwrap();
- select! {
- _n = rx.recv() => {}
- }
-}
-
-#[test]
-fn preflight3() {
- let (tx, rx) = channel();
- drop(tx.clone());
- tx.send(()).unwrap();
- select! {
- _n = rx.recv() => {}
- }
-}
-
-#[test]
-fn preflight4() {
- let (tx, rx) = channel();
- tx.send(()).unwrap();
- let s = Select::new();
- let mut h = s.handle(&rx);
- unsafe { h.add(); }
- assert_eq!(s.wait2(false), h.id());
-}
-
-#[test]
-fn preflight5() {
- let (tx, rx) = channel();
- tx.send(()).unwrap();
- tx.send(()).unwrap();
- let s = Select::new();
- let mut h = s.handle(&rx);
- unsafe { h.add(); }
- assert_eq!(s.wait2(false), h.id());
-}
-
-#[test]
-fn preflight6() {
- let (tx, rx) = channel();
- drop(tx.clone());
- tx.send(()).unwrap();
- let s = Select::new();
- let mut h = s.handle(&rx);
- unsafe { h.add(); }
- assert_eq!(s.wait2(false), h.id());
-}
-
-#[test]
-fn preflight7() {
- let (tx, rx) = channel::<()>();
- drop(tx);
- let s = Select::new();
- let mut h = s.handle(&rx);
- unsafe { h.add(); }
- assert_eq!(s.wait2(false), h.id());
-}
-
-#[test]
-fn preflight8() {
- let (tx, rx) = channel();
- tx.send(()).unwrap();
- drop(tx);
- rx.recv().unwrap();
- let s = Select::new();
- let mut h = s.handle(&rx);
- unsafe { h.add(); }
- assert_eq!(s.wait2(false), h.id());
-}
-
-#[test]
-fn preflight9() {
- let (tx, rx) = channel();
- drop(tx.clone());
- tx.send(()).unwrap();
- drop(tx);
- rx.recv().unwrap();
- let s = Select::new();
- let mut h = s.handle(&rx);
- unsafe { h.add(); }
- assert_eq!(s.wait2(false), h.id());
-}
-
-#[test]
-fn oneshot_data_waiting() {
- let (tx1, rx1) = channel();
- let (tx2, rx2) = channel();
- let _t = thread::spawn(move|| {
- select! {
- _n = rx1.recv() => {}
- }
- tx2.send(()).unwrap();
- });
-
- for _ in 0..100 { thread::yield_now() }
- tx1.send(()).unwrap();
- rx2.recv().unwrap();
-}
-
-#[test]
-fn stream_data_waiting() {
- let (tx1, rx1) = channel();
- let (tx2, rx2) = channel();
- tx1.send(()).unwrap();
- tx1.send(()).unwrap();
- rx1.recv().unwrap();
- rx1.recv().unwrap();
- let _t = thread::spawn(move|| {
- select! {
- _n = rx1.recv() => {}
- }
- tx2.send(()).unwrap();
- });
-
- for _ in 0..100 { thread::yield_now() }
- tx1.send(()).unwrap();
- rx2.recv().unwrap();
-}
-
-#[test]
-fn shared_data_waiting() {
- let (tx1, rx1) = channel();
- let (tx2, rx2) = channel();
- drop(tx1.clone());
- tx1.send(()).unwrap();
- rx1.recv().unwrap();
- let _t = thread::spawn(move|| {
- select! {
- _n = rx1.recv() => {}
- }
- tx2.send(()).unwrap();
- });
-
- for _ in 0..100 { thread::yield_now() }
- tx1.send(()).unwrap();
- rx2.recv().unwrap();
-}
-
-#[test]
-fn sync1() {
- let (tx, rx) = sync_channel::<i32>(1);
- tx.send(1).unwrap();
- select! {
- n = rx.recv() => { assert_eq!(n.unwrap(), 1); }
- }
-}
-
-#[test]
-fn sync2() {
- let (tx, rx) = sync_channel::<i32>(0);
- let _t = thread::spawn(move|| {
- for _ in 0..100 { thread::yield_now() }
- tx.send(1).unwrap();
- });
- select! {
- n = rx.recv() => { assert_eq!(n.unwrap(), 1); }
- }
-}
-
-#[test]
-fn sync3() {
- let (tx1, rx1) = sync_channel::<i32>(0);
- let (tx2, rx2): (Sender<i32>, Receiver<i32>) = channel();
- let _t = thread::spawn(move|| { tx1.send(1).unwrap(); });
- let _t = thread::spawn(move|| { tx2.send(2).unwrap(); });
- select! {
- n = rx1.recv() => {
- let n = n.unwrap();
- assert_eq!(n, 1);
- assert_eq!(rx2.recv().unwrap(), 2);
- },
- n = rx2.recv() => {
- let n = n.unwrap();
- assert_eq!(n, 2);
- assert_eq!(rx1.recv().unwrap(), 1);
- }
- }
-}
/// channels are quite similar, and this is no coincidence!
pub use self::Failure::*;
+use self::StartResult::*;
use core::cmp;
use core::intrinsics::abort;
use crate::sync::atomic::{AtomicUsize, AtomicIsize, AtomicBool, Ordering};
use crate::sync::mpsc::blocking::{self, SignalToken};
use crate::sync::mpsc::mpsc_queue as mpsc;
-use crate::sync::mpsc::select::StartResult::*;
-use crate::sync::mpsc::select::StartResult;
use crate::sync::{Mutex, MutexGuard};
use crate::thread;
use crate::time::Instant;
Disconnected,
}
+#[derive(PartialEq, Eq)]
+enum StartResult {
+ Installed,
+ Abort,
+}
+
impl<T> Packet<T> {
// Creation of a packet *must* be followed by a call to postinit_lock
// and later by inherit_blocker
// select implementation
////////////////////////////////////////////////////////////////////////////
- // Helper function for select, tests whether this port can receive without
- // blocking (obviously not an atomic decision).
- //
- // This is different than the stream version because there's no need to peek
- // at the queue, we can just look at the local count.
- pub fn can_recv(&self) -> bool {
- let cnt = self.cnt.load(Ordering::SeqCst);
- cnt == DISCONNECTED || cnt - unsafe { *self.steals.get() } > 0
- }
-
// increment the count on the channel (used for selection)
fn bump(&self, amt: isize) -> isize {
match self.cnt.fetch_add(amt, Ordering::SeqCst) {
}
}
- // Inserts the signal token for selection on this port, returning true if
- // blocking should proceed.
- //
- // The code here is the same as in stream.rs, except that it doesn't need to
- // peek at the channel to see if an upgrade is pending.
- pub fn start_selection(&self, token: SignalToken) -> StartResult {
- match self.decrement(token) {
- Installed => Installed,
- Abort => {
- let prev = self.bump(1);
- assert!(prev == DISCONNECTED || prev >= 0);
- Abort
- }
- }
- }
-
// Cancels a previous thread waiting on this port, returning whether there's
// data on the port.
//
pub use self::Failure::*;
pub use self::UpgradeResult::*;
-pub use self::SelectionResult::*;
use self::Message::*;
use core::cmp;
UpWoke(SignalToken),
}
-pub enum SelectionResult<T> {
- SelSuccess,
- SelCanceled,
- SelUpgraded(SignalToken, Receiver<T>),
-}
-
// Any message could contain an "upgrade request" to a new shared port, so the
// internal queue it's a queue of T, but rather Message<T>
enum Message<T> {
// select implementation
////////////////////////////////////////////////////////////////////////////
- // Tests to see whether this port can receive without blocking. If Ok is
- // returned, then that's the answer. If Err is returned, then the returned
- // port needs to be queried instead (an upgrade happened)
- pub fn can_recv(&self) -> Result<bool, Receiver<T>> {
- // We peek at the queue to see if there's anything on it, and we use
- // this return value to determine if we should pop from the queue and
- // upgrade this channel immediately. If it looks like we've got an
- // upgrade pending, then go through the whole recv rigamarole to update
- // the internal state.
- match self.queue.peek() {
- Some(&mut GoUp(..)) => {
- match self.recv(None) {
- Err(Upgraded(port)) => Err(port),
- _ => unreachable!(),
- }
- }
- Some(..) => Ok(true),
- None => Ok(false)
- }
- }
-
// increment the count on the channel (used for selection)
fn bump(&self, amt: isize) -> isize {
match self.queue.producer_addition().cnt.fetch_add(amt, Ordering::SeqCst) {
}
}
- // Attempts to start selecting on this port. Like a oneshot, this can fail
- // immediately because of an upgrade.
- pub fn start_selection(&self, token: SignalToken) -> SelectionResult<T> {
- match self.decrement(token) {
- Ok(()) => SelSuccess,
- Err(token) => {
- let ret = match self.queue.peek() {
- Some(&mut GoUp(..)) => {
- match self.queue.pop() {
- Some(GoUp(port)) => SelUpgraded(token, port),
- _ => unreachable!(),
- }
- }
- Some(..) => SelCanceled,
- None => SelCanceled,
- };
- // Undo our decrement above, and we should be guaranteed that the
- // previous value is positive because we're not going to sleep
- let prev = self.bump(1);
- assert!(prev == DISCONNECTED || prev >= 0);
- ret
- }
- }
- }
-
// Removes a previous thread from being blocked in this port
pub fn abort_selection(&self,
was_upgrade: bool) -> Result<bool, Receiver<T>> {
use crate::sync::atomic::{Ordering, AtomicUsize};
use crate::sync::mpsc::blocking::{self, WaitToken, SignalToken};
-use crate::sync::mpsc::select::StartResult::{self, Installed, Abort};
use crate::sync::{Mutex, MutexGuard};
use crate::time::Instant;
while let Some(token) = queue.dequeue() { token.signal(); }
waiter.map(|t| t.signal());
}
-
- ////////////////////////////////////////////////////////////////////////////
- // select implementation
- ////////////////////////////////////////////////////////////////////////////
-
- // If Ok, the value is whether this port has data, if Err, then the upgraded
- // port needs to be checked instead of this one.
- pub fn can_recv(&self) -> bool {
- let guard = self.lock.lock().unwrap();
- guard.disconnected || guard.buf.size() > 0
- }
-
- // Attempts to start selection on this port. This can either succeed or fail
- // because there is data waiting.
- pub fn start_selection(&self, token: SignalToken) -> StartResult {
- let mut guard = self.lock.lock().unwrap();
- if guard.disconnected || guard.buf.size() > 0 {
- Abort
- } else {
- match mem::replace(&mut guard.blocker, BlockedReceiver(token)) {
- NoneBlocked => {}
- BlockedSender(..) => unreachable!(),
- BlockedReceiver(..) => unreachable!(),
- }
- Installed
- }
- }
-
- // Remove a previous selecting thread from this port. This ensures that the
- // blocked thread will no longer be visible to any other threads.
- //
- // The return value indicates whether there's data on this port.
- pub fn abort_selection(&self) -> bool {
- let mut guard = self.lock.lock().unwrap();
- abort_selection(&mut guard)
- }
}
impl<T> Drop for Packet<T> {
impl<T> From<T> for Mutex<T> {
/// Creates a new mutex in an unlocked state ready for use.
/// This is equivalent to [`Mutex::new`].
+ ///
+ /// [`Mutex::new`]: ../../std/sync/struct.Mutex.html#method.new
fn from(t: T) -> Self {
Mutex::new(t)
}
impl<T> From<T> for RwLock<T> {
/// Creates a new instance of an `RwLock<T>` which is unlocked.
/// This is equivalent to [`RwLock::new`].
+ ///
+ /// [`RwLock::new`]: ../../std/sync/struct.RwLock.html#method.new
fn from(t: T) -> Self {
RwLock::new(t)
}
match cvt(syscall::clone(0))? {
0 => {
drop(input);
- let err = self.do_exec(theirs);
+ let Err(err) = self.do_exec(theirs);
let errno = err.raw_os_error().unwrap_or(syscall::EINVAL) as u32;
let bytes = [
(errno >> 24) as u8,
}
match self.setup_io(default, true) {
- Ok((_, theirs)) => unsafe { self.do_exec(theirs) },
+ Ok((_, theirs)) => unsafe {
+ let Err(e) = self.do_exec(theirs);
+ e
+ },
Err(e) => e,
}
}
// allocation). Instead we just close it manually. This will never
// have the drop glue anyway because this code never returns (the
// child will either exec() or invoke syscall::exit)
- unsafe fn do_exec(&mut self, stdio: ChildPipes) -> io::Error {
- macro_rules! t {
- ($e:expr) => (match $e {
- Ok(e) => e,
- Err(e) => return e,
- })
- }
-
+ unsafe fn do_exec(&mut self, stdio: ChildPipes) -> Result<!, io::Error> {
if let Some(fd) = stdio.stderr.fd() {
- t!(cvt(syscall::dup2(fd, 2, &[])));
- let mut flags = t!(cvt(syscall::fcntl(2, syscall::F_GETFD, 0)));
+ cvt(syscall::dup2(fd, 2, &[]))?;
+ let mut flags = cvt(syscall::fcntl(2, syscall::F_GETFD, 0))?;
flags &= ! syscall::O_CLOEXEC;
- t!(cvt(syscall::fcntl(2, syscall::F_SETFD, flags)));
+ cvt(syscall::fcntl(2, syscall::F_SETFD, flags))?;
}
if let Some(fd) = stdio.stdout.fd() {
- t!(cvt(syscall::dup2(fd, 1, &[])));
- let mut flags = t!(cvt(syscall::fcntl(1, syscall::F_GETFD, 0)));
+ cvt(syscall::dup2(fd, 1, &[]))?;
+ let mut flags = cvt(syscall::fcntl(1, syscall::F_GETFD, 0))?;
flags &= ! syscall::O_CLOEXEC;
- t!(cvt(syscall::fcntl(1, syscall::F_SETFD, flags)));
+ cvt(syscall::fcntl(1, syscall::F_SETFD, flags))?;
}
if let Some(fd) = stdio.stdin.fd() {
- t!(cvt(syscall::dup2(fd, 0, &[])));
- let mut flags = t!(cvt(syscall::fcntl(0, syscall::F_GETFD, 0)));
+ cvt(syscall::dup2(fd, 0, &[]))?;
+ let mut flags = cvt(syscall::fcntl(0, syscall::F_GETFD, 0))?;
flags &= ! syscall::O_CLOEXEC;
- t!(cvt(syscall::fcntl(0, syscall::F_SETFD, flags)));
+ cvt(syscall::fcntl(0, syscall::F_SETFD, flags))?;
}
if let Some(g) = self.gid {
- t!(cvt(syscall::setregid(g as usize, g as usize)));
+ cvt(syscall::setregid(g as usize, g as usize))?;
}
if let Some(u) = self.uid {
- t!(cvt(syscall::setreuid(u as usize, u as usize)));
+ cvt(syscall::setreuid(u as usize, u as usize))?;
}
if let Some(ref cwd) = self.cwd {
- t!(cvt(syscall::chdir(cwd)));
+ cvt(syscall::chdir(cwd))?;
}
for callback in self.closures.iter_mut() {
- t!(callback());
+ callback()?;
}
self.env.apply();
};
let mut file = if let Some(program) = program {
- t!(File::open(program.as_os_str()))
+ File::open(program.as_os_str())?
} else {
- return io::Error::from_raw_os_error(syscall::ENOENT);
+ return Err(io::Error::from_raw_os_error(syscall::ENOENT));
};
// Push all the arguments
let mut shebang = [0; 2];
let mut read = 0;
loop {
- match t!(reader.read(&mut shebang[read..])) {
+ match reader.read(&mut shebang[read..])? {
0 => break,
n => read += n,
}
// First of all, since we'll be passing another file to
// fexec(), we need to manually check that we have permission
// to execute this file:
- let uid = t!(cvt(syscall::getuid()));
- let gid = t!(cvt(syscall::getgid()));
- let meta = t!(file.metadata());
+ let uid = cvt(syscall::getuid())?;
+ let gid = cvt(syscall::getgid())?;
+ let meta = file.metadata()?;
let mode = if uid == meta.uid() as usize {
meta.mode() >> 3*2 & 0o7
meta.mode() & 0o7
};
if mode & 1 == 0 {
- return io::Error::from_raw_os_error(syscall::EPERM);
+ return Err(io::Error::from_raw_os_error(syscall::EPERM));
}
// Second of all, we need to actually read which interpreter it wants
let mut interpreter = Vec::new();
- t!(reader.read_until(b'\n', &mut interpreter));
+ reader.read_until(b'\n', &mut interpreter)?;
// Pop one trailing newline, if any
if interpreter.ends_with(&[b'\n']) {
interpreter.pop().unwrap();
};
if let Some(ref interpreter) = interpreter {
let path: &OsStr = OsStr::from_bytes(&interpreter);
- file = t!(File::open(path));
+ file = File::open(path)?;
args.push([interpreter.as_ptr() as usize, interpreter.len()]);
} else {
- t!(file.seek(SeekFrom::Start(0)));
+ file.seek(SeekFrom::Start(0))?;
}
args.push([self.program.as_ptr() as usize, self.program.len()]);
}
if let Err(err) = syscall::fexec(file.as_raw_fd(), &args, &vars) {
- io::Error::from_raw_os_error(err.errno as i32)
+ Err(io::Error::from_raw_os_error(err.errno as i32))
} else {
panic!("return from exec without err");
}
}
-
fn setup_io(&self, default: Stdio, needs_stdin: bool)
-> io::Result<(StdioPipes, ChildPipes)> {
let null = Stdio::Null;
match result {
0 => {
drop(input);
- let err = self.do_exec(theirs, envp.as_ref());
+ let Err(err) = self.do_exec(theirs, envp.as_ref());
let errno = err.raw_os_error().unwrap_or(libc::EINVAL) as u32;
let bytes = [
(errno >> 24) as u8,
// environment lock before we try to exec.
let _lock = sys::os::env_lock();
- self.do_exec(theirs, envp.as_ref())
+ let Err(e) = self.do_exec(theirs, envp.as_ref());
+ e
}
}
Err(e) => e,
&mut self,
stdio: ChildPipes,
maybe_envp: Option<&CStringArray>
- ) -> io::Error {
+ ) -> Result<!, io::Error> {
use crate::sys::{self, cvt_r};
- macro_rules! t {
- ($e:expr) => (match $e {
- Ok(e) => e,
- Err(e) => return e,
- })
- }
-
if let Some(fd) = stdio.stdin.fd() {
- t!(cvt_r(|| libc::dup2(fd, libc::STDIN_FILENO)));
+ cvt_r(|| libc::dup2(fd, libc::STDIN_FILENO))?;
}
if let Some(fd) = stdio.stdout.fd() {
- t!(cvt_r(|| libc::dup2(fd, libc::STDOUT_FILENO)));
+ cvt_r(|| libc::dup2(fd, libc::STDOUT_FILENO))?;
}
if let Some(fd) = stdio.stderr.fd() {
- t!(cvt_r(|| libc::dup2(fd, libc::STDERR_FILENO)));
+ cvt_r(|| libc::dup2(fd, libc::STDERR_FILENO))?;
}
if cfg!(not(any(target_os = "l4re"))) {
if let Some(u) = self.get_gid() {
- t!(cvt(libc::setgid(u as gid_t)));
+ cvt(libc::setgid(u as gid_t))?;
}
if let Some(u) = self.get_uid() {
// When dropping privileges from root, the `setgroups` call
// privilege dropping function.
let _ = libc::setgroups(0, ptr::null());
- t!(cvt(libc::setuid(u as uid_t)));
+ cvt(libc::setuid(u as uid_t))?;
}
}
if let Some(ref cwd) = *self.get_cwd() {
- t!(cvt(libc::chdir(cwd.as_ptr())));
+ cvt(libc::chdir(cwd.as_ptr()))?;
}
// emscripten has no signal support.
0,
mem::size_of::<libc::sigset_t>());
} else {
- t!(cvt(libc::sigemptyset(&mut set)));
+ cvt(libc::sigemptyset(&mut set))?;
}
- t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &set,
- ptr::null_mut())));
+ cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &set,
+ ptr::null_mut()))?;
let ret = sys::signal(libc::SIGPIPE, libc::SIG_DFL);
if ret == libc::SIG_ERR {
- return io::Error::last_os_error()
+ return Err(io::Error::last_os_error())
}
}
for callback in self.get_closures().iter_mut() {
- t!(callback());
+ callback()?;
}
// Although we're performing an exec here we may also return with an
}
libc::execvp(self.get_argv()[0], self.get_argv().as_ptr());
- io::Error::last_os_error()
+ Err(io::Error::last_os_error())
}
#[cfg(not(any(target_os = "macos", target_os = "freebsd",
let err = errno() as libc::c_int;
if err == libc::EINTR {
continue;
- } else if err == libc::ENOSYS {
+ } else if err == libc::ENOSYS || err == libc::EPERM {
+ // Fall back to reading /dev/urandom if `getrandom` is not
+ // supported on the current kernel.
+ //
+ // Also fall back in case it is disabled by something like
+ // seccomp or inside of virtual machines.
GETRANDOM_UNAVAILABLE.store(true, Ordering::Relaxed);
return false;
} else if err == libc::EAGAIN {
/// [`Builder::spawn`]: ../../std/thread/struct.Builder.html#method.spawn
/// [`io::Result`]: ../../std/io/type.Result.html
/// [`JoinHandle`]: ../../std/thread/struct.JoinHandle.html
+ /// [`JoinHandle::join`]: ../../std/thread/struct.JoinHandle.html#method.join
#[unstable(feature = "thread_spawn_unchecked", issue = "55132")]
pub unsafe fn spawn_unchecked<'a, F, T>(self, f: F) -> io::Result<JoinHandle<T>> where
F: FnOnce() -> T, F: Send + 'a, T: Send + 'a
use rustc_data_structures::indexed_vec::Idx;
#[cfg(target_arch = "x86_64")]
-use rustc_data_structures::static_assert;
+use rustc_data_structures::static_assert_size;
use rustc_target::spec::abi::Abi;
use syntax_pos::{Span, DUMMY_SP};
impl PartialEq<Symbol> for Path {
fn eq(&self, symbol: &Symbol) -> bool {
self.segments.len() == 1 && {
- let name = self.segments[0].ident.name;
- // Make sure these symbols are pure strings
- debug_assert!(!symbol.is_gensymed());
- debug_assert!(!name.is_gensymed());
- name == *symbol
+ self.segments[0].ident.name == *symbol
}
}
}
// `Expr` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")]
-static_assert!(MEM_SIZE_OF_EXPR: std::mem::size_of::<Expr>() == 96);
+static_assert_size!(Expr, 96);
impl Expr {
/// Whether this expression would be valid somewhere that expects a value; for example, an `if`
use crate::parse::{self, ParseSess, PResult};
use crate::parse::token::{self, Token};
use crate::ptr::P;
-use crate::symbol::{keywords, Symbol};
+use crate::symbol::{keywords, Symbol, sym};
use crate::ThinVec;
use crate::tokenstream::{TokenStream, TokenTree, DelimSpan};
use crate::GLOBALS;
if self.is_sugared_doc {
let comment = self.value_str().unwrap();
let meta = mk_name_value_item_str(
- Ident::from_str("doc"),
+ Ident::with_empty_ctxt(sym::doc),
dummy_spanned(Symbol::intern(&strip_doc_comment_decoration(&comment.as_str()))));
let mut attr = if self.style == ast::AttrStyle::Outer {
mk_attr_outer(self.span, self.id, meta)
Attribute {
id,
style,
- path: Path::from_ident(Ident::from_str("doc").with_span_pos(span)),
+ path: Path::from_ident(Ident::with_empty_ctxt(sym::doc).with_span_pos(span)),
tokens: MetaItemKind::NameValue(lit).tokens(span),
is_sugared_doc: true,
span,
use crate::ext::build::AstBuilder;
use crate::parse::token;
use crate::ptr::P;
-use crate::symbol::{keywords, Symbol};
+use crate::symbol::keywords;
use crate::tokenstream::{TokenTree};
use smallvec::smallvec;
let span = span.apply_mark(ecx.current_expansion.mark);
- let sym = Ident::new(Symbol::gensym(&format!("__register_diagnostic_{}", code)), span);
+ let name = Ident::from_str_and_span(&format!("__register_diagnostic_{}", code), span).gensym();
MacEager::items(smallvec![
ecx.item_mod(
span,
span,
- sym,
+ name,
vec![],
vec![],
)
use crate::source_map::{SourceMap, Spanned, respan};
use crate::edition::Edition;
use crate::ext::expand::{self, AstFragment, Invocation};
-use crate::ext::hygiene::{self, Mark, SyntaxContext, Transparency};
+use crate::ext::hygiene::{Mark, SyntaxContext, Transparency};
use crate::mut_visit::{self, MutVisitor};
use crate::parse::{self, parser, DirectoryOwnership};
use crate::parse::token;
}
}
- pub fn edition(&self) -> Edition {
+ pub fn edition(&self, default_edition: Edition) -> Edition {
match *self {
SyntaxExtension::NormalTT { edition, .. } |
SyntaxExtension::DeclMacro { edition, .. } |
SyntaxExtension::IdentTT { .. } |
SyntaxExtension::MultiDecorator(..) |
SyntaxExtension::MultiModifier(..) |
- SyntaxExtension::BuiltinDerive(..) => hygiene::default_edition(),
+ SyntaxExtension::BuiltinDerive(..) => default_edition,
}
}
}
pub trait Resolver {
fn next_node_id(&mut self) -> ast::NodeId;
+
fn get_module_scope(&mut self, id: ast::NodeId) -> Mark;
fn resolve_dollar_crates(&mut self, fragment: &AstFragment);
impl Resolver for DummyResolver {
fn next_node_id(&mut self) -> ast::NodeId { ast::DUMMY_NODE_ID }
+
fn get_module_scope(&mut self, _id: ast::NodeId) -> Mark { Mark::root() }
fn resolve_dollar_crates(&mut self, _fragment: &AstFragment) {}
use crate::attr::HasAttrs;
use crate::ast;
-use crate::source_map::{hygiene, ExpnInfo, ExpnFormat};
+use crate::source_map::{ExpnInfo, ExpnFormat};
use crate::ext::base::ExtCtxt;
use crate::ext::build::AstBuilder;
use crate::parse::parser::PathStyle;
].into()),
allow_internal_unsafe: false,
local_inner_macros: false,
- edition: hygiene::default_edition(),
+ edition: cx.parse_sess.edition,
});
let span = span.with_ctxt(cx.backtrace());
use crate::config::StripUnconfigured;
use crate::ext::base::*;
use crate::ext::derive::{add_derived_markers, collect_derives};
-use crate::ext::hygiene::{self, Mark, SyntaxContext};
+use crate::ext::hygiene::{Mark, SyntaxContext};
use crate::ext::placeholders::{placeholder, PlaceholderExpander};
use crate::feature_gate::{self, Features, GateIssue, is_builtin_attr, emit_feature_err};
use crate::mut_visit::*;
allow_internal_unstable: None,
allow_internal_unsafe: false,
local_inner_macros: false,
- edition: ext.edition(),
+ edition: ext.edition(self.cx.parse_sess.edition),
});
match *ext {
allow_internal_unstable: allow_internal_unstable.clone(),
allow_internal_unsafe: false,
local_inner_macros: false,
- edition: hygiene::default_edition(),
+ edition: self.cx.parse_sess.edition,
});
let input: Vec<_> = mac.node.stream().into_trees().collect();
allow_internal_unstable: None,
allow_internal_unsafe: false,
local_inner_macros: false,
- edition: ext.edition(),
+ edition: ext.edition(self.cx.parse_sess.edition),
};
match *ext {
let include_info = vec![
ast::NestedMetaItem::MetaItem(
attr::mk_name_value_item_str(
- Ident::from_str("file"),
+ Ident::with_empty_ctxt(sym::file),
dummy_spanned(file),
),
),
ast::NestedMetaItem::MetaItem(
attr::mk_name_value_item_str(
- Ident::from_str("contents"),
+ Ident::with_empty_ctxt(sym::contents),
dummy_spanned(src_interned),
),
),
];
- let include_ident = Ident::from_str("include");
+ let include_ident = Ident::with_empty_ctxt(sym::include);
let item = attr::mk_list_item(DUMMY_SP, include_ident, include_info);
items.push(ast::NestedMetaItem::MetaItem(item));
}
}
}
- let meta = attr::mk_list_item(DUMMY_SP, Ident::from_str("doc"), items);
+ let meta = attr::mk_list_item(DUMMY_SP, Ident::with_empty_ctxt(sym::doc), items);
match at.style {
ast::AttrStyle::Inner => *at = attr::mk_spanned_attr_inner(at.span, at.id, meta),
ast::AttrStyle::Outer => *at = attr::mk_spanned_attr_outer(at.span, at.id, meta),
def: &ast::Item,
edition: Edition
) -> SyntaxExtension {
- let lhs_nm = ast::Ident::with_empty_ctxt(Symbol::gensym("lhs"));
- let rhs_nm = ast::Ident::with_empty_ctxt(Symbol::gensym("rhs"));
+ let lhs_nm = ast::Ident::from_str("lhs").gensym();
+ let rhs_nm = ast::Ident::from_str("rhs").gensym();
// Parse the macro_rules! invocation
let body = match def.node {
(sym::repr, Normal, template!(List: "C, packed, ..."), Ungated),
(sym::path, Normal, template!(NameValueStr: "file"), Ungated),
(sym::automatically_derived, Normal, template!(Word), Ungated),
- (sym::no_mangle, Normal, template!(Word), Ungated),
+ (sym::no_mangle, Whitelisted, template!(Word), Ungated),
(sym::no_link, Normal, template!(Word), Ungated),
(sym::derive, Normal, template!(List: "Trait1, Trait2, ..."), Ungated),
(
use rustc_data_structures::bit_set::GrowableBitSet;
pub use rustc_data_structures::thin_vec::ThinVec;
use ast::AttrId;
+use syntax_pos::edition::Edition;
// A variant of 'try!' that panics on an Err. This is used as a crutch on the
// way towards a non-panic!-prone parser. It should be used for fatal parsing
}
impl Globals {
- fn new() -> Globals {
+ fn new(edition: Edition) -> Globals {
Globals {
// We have no idea how many attributes their will be, so just
// initiate the vectors with 0 bits. We'll grow them as necessary.
used_attrs: Lock::new(GrowableBitSet::new_empty()),
known_attrs: Lock::new(GrowableBitSet::new_empty()),
- syntax_pos_globals: syntax_pos::Globals::new(),
+ syntax_pos_globals: syntax_pos::Globals::new(edition),
}
}
}
-pub fn with_globals<F, R>(f: F) -> R
+pub fn with_globals<F, R>(edition: Edition, f: F) -> R
where F: FnOnce() -> R
{
- let globals = Globals::new();
+ let globals = Globals::new(edition);
GLOBALS.set(&globals, || {
syntax_pos::GLOBALS.set(&globals.syntax_pos_globals, f)
})
}
+pub fn with_default_globals<F, R>(f: F) -> R
+ where F: FnOnce() -> R
+{
+ with_globals(edition::DEFAULT_EDITION, f)
+}
+
scoped_tls::scoped_thread_local!(pub static GLOBALS: Globals);
#[macro_use]
use crate::util::parser_testing::{string_to_crate, matches_codepattern};
use crate::print::pprust;
use crate::mut_visit;
- use crate::with_globals;
+ use crate::with_default_globals;
use super::*;
// this version doesn't care about getting comments or docstrings in.
// make sure idents get transformed everywhere
#[test] fn ident_transformation () {
- with_globals(|| {
+ with_default_globals(|| {
let mut zz_visitor = ToZzIdentMutVisitor;
let mut krate = string_to_crate(
"#[a] mod b {fn c (d : e, f : g) {h!(i,j,k);l;m}}".to_string());
// even inside macro defs....
#[test] fn ident_transformation_in_defs () {
- with_globals(|| {
+ with_default_globals(|| {
let mut zz_visitor = ToZzIdentMutVisitor;
let mut krate = string_to_crate(
"macro_rules! a {(b $c:expr $(d $e:token)f+ => \
use crate::ast;
-use crate::ast::{Expr, ExprKind, Item, ItemKind, Pat, PatKind, QSelf, Ty, TyKind};
-use crate::parse::parser::PathStyle;
+use crate::ast::{BlockCheckMode, Expr, ExprKind, Item, ItemKind, Pat, PatKind, QSelf, Ty, TyKind};
+use crate::parse::parser::{BlockMode, PathStyle, TokenType, SemiColonMode};
use crate::parse::token;
use crate::parse::PResult;
use crate::parse::Parser;
use crate::print::pprust;
use crate::ptr::P;
+use crate::symbol::keywords;
use crate::ThinVec;
-use errors::Applicability;
+use errors::{Applicability, DiagnosticBuilder};
use syntax_pos::Span;
+use log::debug;
pub trait RecoverQPath: Sized + 'static {
const PATH_STYLE: PathStyle = PathStyle::Expr;
false
}
}
+
+ /// Consume alternative await syntaxes like `await <expr>`, `await? <expr>`, `await(<expr>)`
+ /// and `await { <expr> }`.
+ crate fn parse_incorrect_await_syntax(
+ &mut self,
+ lo: Span,
+ await_sp: Span,
+ ) -> PResult<'a, (Span, ExprKind)> {
+ let is_question = self.eat(&token::Question); // Handle `await? <expr>`.
+ let expr = if self.token == token::OpenDelim(token::Brace) {
+ // Handle `await { <expr> }`.
+ // This needs to be handled separatedly from the next arm to avoid
+ // interpreting `await { <expr> }?` as `<expr>?.await`.
+ self.parse_block_expr(
+ None,
+ self.span,
+ BlockCheckMode::Default,
+ ThinVec::new(),
+ )
+ } else {
+ self.parse_expr()
+ }.map_err(|mut err| {
+ err.span_label(await_sp, "while parsing this incorrect await expression");
+ err
+ })?;
+ let expr_str = self.sess.source_map().span_to_snippet(expr.span)
+ .unwrap_or_else(|_| pprust::expr_to_string(&expr));
+ let suggestion = format!("{}.await{}", expr_str, if is_question { "?" } else { "" });
+ let sp = lo.to(expr.span);
+ let app = match expr.node {
+ ExprKind::Try(_) => Applicability::MaybeIncorrect, // `await <expr>?`
+ _ => Applicability::MachineApplicable,
+ };
+ self.struct_span_err(sp, "incorrect use of `await`")
+ .span_suggestion(sp, "`await` is a postfix operation", suggestion, app)
+ .emit();
+ Ok((sp, ExprKind::Await(ast::AwaitOrigin::FieldLike, expr)))
+ }
+
+ /// If encountering `future.await()`, consume and emit error.
+ crate fn recover_from_await_method_call(&mut self) {
+ if self.token == token::OpenDelim(token::Paren) &&
+ self.look_ahead(1, |t| t == &token::CloseDelim(token::Paren))
+ {
+ // future.await()
+ let lo = self.span;
+ self.bump(); // (
+ let sp = lo.to(self.span);
+ self.bump(); // )
+ self.struct_span_err(sp, "incorrect use of `await`")
+ .span_suggestion(
+ sp,
+ "`await` is not a method call, remove the parentheses",
+ String::new(),
+ Applicability::MachineApplicable,
+ ).emit()
+ }
+ }
+
+ crate fn could_ascription_be_path(&self, node: &ast::ExprKind) -> bool {
+ self.token.is_ident() &&
+ if let ast::ExprKind::Path(..) = node { true } else { false } &&
+ !self.token.is_reserved_ident() && // v `foo:bar(baz)`
+ self.look_ahead(1, |t| t == &token::OpenDelim(token::Paren)) ||
+ self.look_ahead(1, |t| t == &token::Lt) && // `foo:bar<baz`
+ self.look_ahead(2, |t| t.is_ident()) ||
+ self.look_ahead(1, |t| t == &token::Colon) && // `foo:bar:baz`
+ self.look_ahead(2, |t| t.is_ident()) ||
+ self.look_ahead(1, |t| t == &token::ModSep) && // `foo:bar::baz`
+ self.look_ahead(2, |t| t.is_ident())
+ }
+
+ crate fn bad_type_ascription(
+ &self,
+ err: &mut DiagnosticBuilder<'a>,
+ lhs_span: Span,
+ cur_op_span: Span,
+ next_sp: Span,
+ maybe_path: bool,
+ ) {
+ err.span_label(self.span, "expecting a type here because of type ascription");
+ let cm = self.sess.source_map();
+ let next_pos = cm.lookup_char_pos(next_sp.lo());
+ let op_pos = cm.lookup_char_pos(cur_op_span.hi());
+ if op_pos.line != next_pos.line {
+ err.span_suggestion(
+ cur_op_span,
+ "try using a semicolon",
+ ";".to_string(),
+ Applicability::MaybeIncorrect,
+ );
+ } else {
+ if maybe_path {
+ err.span_suggestion(
+ cur_op_span,
+ "maybe you meant to write a path separator here",
+ "::".to_string(),
+ Applicability::MaybeIncorrect,
+ );
+ } else {
+ err.note("type ascription is a nightly-only feature that lets \
+ you annotate an expression with a type: `<expr>: <type>`")
+ .span_note(
+ lhs_span,
+ "this expression expects an ascribed type after the colon",
+ )
+ .help("this might be indicative of a syntax error elsewhere");
+ }
+ }
+ }
+
+ crate fn recover_seq_parse_error(
+ &mut self,
+ delim: token::DelimToken,
+ lo: Span,
+ result: PResult<'a, P<Expr>>,
+ ) -> P<Expr> {
+ match result {
+ Ok(x) => x,
+ Err(mut err) => {
+ err.emit();
+ // recover from parse error
+ self.consume_block(delim);
+ self.mk_expr(lo.to(self.prev_span), ExprKind::Err, ThinVec::new())
+ }
+ }
+ }
+
+ crate fn recover_closing_delimiter(
+ &mut self,
+ tokens: &[token::Token],
+ mut err: DiagnosticBuilder<'a>,
+ ) -> PResult<'a, bool> {
+ let mut pos = None;
+ // we want to use the last closing delim that would apply
+ for (i, unmatched) in self.unclosed_delims.iter().enumerate().rev() {
+ if tokens.contains(&token::CloseDelim(unmatched.expected_delim))
+ && Some(self.span) > unmatched.unclosed_span
+ {
+ pos = Some(i);
+ }
+ }
+ match pos {
+ Some(pos) => {
+ // Recover and assume that the detected unclosed delimiter was meant for
+ // this location. Emit the diagnostic and act as if the delimiter was
+ // present for the parser's sake.
+
+ // Don't attempt to recover from this unclosed delimiter more than once.
+ let unmatched = self.unclosed_delims.remove(pos);
+ let delim = TokenType::Token(token::CloseDelim(unmatched.expected_delim));
+
+ // We want to suggest the inclusion of the closing delimiter where it makes
+ // the most sense, which is immediately after the last token:
+ //
+ // {foo(bar {}}
+ // - ^
+ // | |
+ // | help: `)` may belong here (FIXME: #58270)
+ // |
+ // unclosed delimiter
+ if let Some(sp) = unmatched.unclosed_span {
+ err.span_label(sp, "unclosed delimiter");
+ }
+ err.span_suggestion_short(
+ self.sess.source_map().next_point(self.prev_span),
+ &format!("{} may belong here", delim.to_string()),
+ delim.to_string(),
+ Applicability::MaybeIncorrect,
+ );
+ err.emit();
+ self.expected_tokens.clear(); // reduce errors
+ Ok(true)
+ }
+ _ => Err(err),
+ }
+ }
+
+ /// Recover from `pub` keyword in places where it seems _reasonable_ but isn't valid.
+ crate fn eat_bad_pub(&mut self) {
+ if self.token.is_keyword(keywords::Pub) {
+ match self.parse_visibility(false) {
+ Ok(vis) => {
+ self.diagnostic()
+ .struct_span_err(vis.span, "unnecessary visibility qualifier")
+ .span_label(vis.span, "`pub` not permitted here")
+ .emit();
+ }
+ Err(mut err) => err.emit(),
+ }
+ }
+ }
+
+ // Eat tokens until we can be relatively sure we reached the end of the
+ // statement. This is something of a best-effort heuristic.
+ //
+ // We terminate when we find an unmatched `}` (without consuming it).
+ crate fn recover_stmt(&mut self) {
+ self.recover_stmt_(SemiColonMode::Ignore, BlockMode::Ignore)
+ }
+
+ // If `break_on_semi` is `Break`, then we will stop consuming tokens after
+ // finding (and consuming) a `;` outside of `{}` or `[]` (note that this is
+ // approximate - it can mean we break too early due to macros, but that
+ // should only lead to sub-optimal recovery, not inaccurate parsing).
+ //
+ // If `break_on_block` is `Break`, then we will stop consuming tokens
+ // after finding (and consuming) a brace-delimited block.
+ crate fn recover_stmt_(&mut self, break_on_semi: SemiColonMode, break_on_block: BlockMode) {
+ let mut brace_depth = 0;
+ let mut bracket_depth = 0;
+ let mut in_block = false;
+ debug!("recover_stmt_ enter loop (semi={:?}, block={:?})",
+ break_on_semi, break_on_block);
+ loop {
+ debug!("recover_stmt_ loop {:?}", self.token);
+ match self.token {
+ token::OpenDelim(token::DelimToken::Brace) => {
+ brace_depth += 1;
+ self.bump();
+ if break_on_block == BlockMode::Break &&
+ brace_depth == 1 &&
+ bracket_depth == 0 {
+ in_block = true;
+ }
+ }
+ token::OpenDelim(token::DelimToken::Bracket) => {
+ bracket_depth += 1;
+ self.bump();
+ }
+ token::CloseDelim(token::DelimToken::Brace) => {
+ if brace_depth == 0 {
+ debug!("recover_stmt_ return - close delim {:?}", self.token);
+ break;
+ }
+ brace_depth -= 1;
+ self.bump();
+ if in_block && bracket_depth == 0 && brace_depth == 0 {
+ debug!("recover_stmt_ return - block end {:?}", self.token);
+ break;
+ }
+ }
+ token::CloseDelim(token::DelimToken::Bracket) => {
+ bracket_depth -= 1;
+ if bracket_depth < 0 {
+ bracket_depth = 0;
+ }
+ self.bump();
+ }
+ token::Eof => {
+ debug!("recover_stmt_ return - Eof");
+ break;
+ }
+ token::Semi => {
+ self.bump();
+ if break_on_semi == SemiColonMode::Break &&
+ brace_depth == 0 &&
+ bracket_depth == 0 {
+ debug!("recover_stmt_ return - Semi");
+ break;
+ }
+ }
+ token::Comma if break_on_semi == SemiColonMode::Comma &&
+ brace_depth == 0 &&
+ bracket_depth == 0 =>
+ {
+ debug!("recover_stmt_ return - Semi");
+ break;
+ }
+ _ => {
+ self.bump()
+ }
+ }
+ }
+ }
+
+ crate fn consume_block(&mut self, delim: token::DelimToken) {
+ let mut brace_depth = 0;
+ loop {
+ if self.eat(&token::OpenDelim(delim)) {
+ brace_depth += 1;
+ } else if self.eat(&token::CloseDelim(delim)) {
+ if brace_depth == 0 {
+ return;
+ } else {
+ brace_depth -= 1;
+ continue;
+ }
+ } else if self.token == token::Eof || self.eat(&token::CloseDelim(token::NoDelim)) {
+ return;
+ } else {
+ self.bump();
+ }
+ }
+ }
+
}
use crate::feature_gate::UnstableFeatures;
use crate::parse::token;
use crate::diagnostics::plugin::ErrorMap;
- use crate::with_globals;
+ use crate::with_default_globals;
use std::io;
use std::path::PathBuf;
- use syntax_pos::{BytePos, Span, NO_EXPANSION};
+ use syntax_pos::{BytePos, Span, NO_EXPANSION, edition::Edition};
use rustc_data_structures::fx::{FxHashSet, FxHashMap};
use rustc_data_structures::sync::Lock;
raw_identifier_spans: Lock::new(Vec::new()),
registered_diagnostics: Lock::new(ErrorMap::new()),
buffered_lints: Lock::new(vec![]),
+ edition: Edition::from_session(),
ambiguous_block_expr_parse: Lock::new(FxHashMap::default()),
}
}
#[test]
fn t1() {
- with_globals(|| {
+ with_default_globals(|| {
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
let sh = mk_sess(sm.clone());
let mut string_reader = setup(&sm,
#[test]
fn doublecolonparsing() {
- with_globals(|| {
+ with_default_globals(|| {
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
let sh = mk_sess(sm.clone());
check_tokenization(setup(&sm, &sh, "a b".to_string()),
#[test]
fn dcparsing_2() {
- with_globals(|| {
+ with_default_globals(|| {
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
let sh = mk_sess(sm.clone());
check_tokenization(setup(&sm, &sh, "a::b".to_string()),
#[test]
fn dcparsing_3() {
- with_globals(|| {
+ with_default_globals(|| {
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
let sh = mk_sess(sm.clone());
check_tokenization(setup(&sm, &sh, "a ::b".to_string()),
#[test]
fn dcparsing_4() {
- with_globals(|| {
+ with_default_globals(|| {
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
let sh = mk_sess(sm.clone());
check_tokenization(setup(&sm, &sh, "a:: b".to_string()),
#[test]
fn character_a() {
- with_globals(|| {
+ with_default_globals(|| {
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
let sh = mk_sess(sm.clone());
assert_eq!(setup(&sm, &sh, "'a'".to_string()).next_token().tok,
#[test]
fn character_space() {
- with_globals(|| {
+ with_default_globals(|| {
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
let sh = mk_sess(sm.clone());
assert_eq!(setup(&sm, &sh, "' '".to_string()).next_token().tok,
#[test]
fn character_escaped() {
- with_globals(|| {
+ with_default_globals(|| {
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
let sh = mk_sess(sm.clone());
assert_eq!(setup(&sm, &sh, "'\\n'".to_string()).next_token().tok,
#[test]
fn lifetime_name() {
- with_globals(|| {
+ with_default_globals(|| {
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
let sh = mk_sess(sm.clone());
assert_eq!(setup(&sm, &sh, "'abc".to_string()).next_token().tok,
#[test]
fn raw_string() {
- with_globals(|| {
+ with_default_globals(|| {
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
let sh = mk_sess(sm.clone());
assert_eq!(setup(&sm, &sh, "r###\"\"#a\\b\x00c\"\"###".to_string())
#[test]
fn literal_suffixes() {
- with_globals(|| {
+ with_default_globals(|| {
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
let sh = mk_sess(sm.clone());
macro_rules! test {
#[test]
fn nested_block_comments() {
- with_globals(|| {
+ with_default_globals(|| {
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
let sh = mk_sess(sm.clone());
let mut lexer = setup(&sm, &sh, "/* /* */ */'a'".to_string());
#[test]
fn crlf_comments() {
- with_globals(|| {
+ with_default_globals(|| {
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
let sh = mk_sess(sm.clone());
let mut lexer = setup(&sm, &sh, "// test\r\n/// test\r\n".to_string());
use errors::{Applicability, FatalError, Level, Handler, ColorConfig, Diagnostic, DiagnosticBuilder};
use rustc_data_structures::sync::{Lrc, Lock};
use syntax_pos::{Span, SourceFile, FileName, MultiSpan};
+use syntax_pos::edition::Edition;
use rustc_data_structures::fx::{FxHashSet, FxHashMap};
use std::borrow::Cow;
pub span_diagnostic: Handler,
pub unstable_features: UnstableFeatures,
pub config: CrateConfig,
+ pub edition: Edition,
pub missing_fragment_specifiers: Lock<FxHashSet<Span>>,
/// Places where raw identifiers were used. This is used for feature-gating raw identifiers.
pub raw_identifier_spans: Lock<Vec<Span>>,
included_mod_stack: Lock::new(vec![]),
source_map,
buffered_lints: Lock::new(vec![]),
+ edition: Edition::from_session(),
ambiguous_block_expr_parse: Lock::new(FxHashMap::default()),
}
}
use crate::tokenstream::{DelimSpan, TokenTree};
use crate::util::parser_testing::string_to_stream;
use crate::util::parser_testing::{string_to_expr, string_to_item};
- use crate::with_globals;
+ use crate::with_default_globals;
use syntax_pos::{Span, BytePos, Pos, NO_EXPANSION};
/// Parses an item.
#[should_panic]
#[test] fn bad_path_expr_1() {
- with_globals(|| {
+ with_default_globals(|| {
string_to_expr("::abc::def::return".to_string());
})
}
// check the token-tree-ization of macros
#[test]
fn string_to_tts_macro () {
- with_globals(|| {
+ with_default_globals(|| {
use crate::symbol::sym;
let tts: Vec<_> =
#[test]
fn string_to_tts_1() {
- with_globals(|| {
+ with_default_globals(|| {
let tts = string_to_stream("fn a (b : i32) { b; }".to_string());
let expected = TokenStream::new(vec![
}
#[test] fn parse_use() {
- with_globals(|| {
+ with_default_globals(|| {
let use_s = "use foo::bar::baz;";
let vitem = string_to_item(use_s.to_string()).unwrap();
let vitem_s = item_to_string(&vitem);
}
#[test] fn parse_extern_crate() {
- with_globals(|| {
+ with_default_globals(|| {
let ex_s = "extern crate foo;";
let vitem = string_to_item(ex_s.to_string()).unwrap();
let vitem_s = item_to_string(&vitem);
}
#[test] fn span_of_self_arg_pat_idents_are_correct() {
- with_globals(|| {
+ with_default_globals(|| {
let srcs = ["impl z { fn a (&self, &myarg: i32) {} }",
"impl z { fn a (&mut self, &myarg: i32) {} }",
}
#[test] fn parse_exprs () {
- with_globals(|| {
+ with_default_globals(|| {
// just make sure that they parse....
string_to_expr("3 + 4".to_string());
string_to_expr("a::z.froob(b,&(987+3))".to_string());
}
#[test] fn attrs_fix_bug () {
- with_globals(|| {
+ with_default_globals(|| {
string_to_item("pub fn mk_file_writer(path: &Path, flags: &[FileFlag])
-> Result<Box<Writer>, String> {
#[cfg(windows)]
}
#[test] fn crlf_doc_comments() {
- with_globals(|| {
+ with_default_globals(|| {
use crate::symbol::sym;
let sess = ParseSess::new(FilePathMapping::empty());
new_parser_from_source_str(sess, name, source).parse_expr()
}
- with_globals(|| {
+ with_default_globals(|| {
let sess = ParseSess::new(FilePathMapping::empty());
let expr = parse_expr_from_source_str(PathBuf::from("foo").into(),
"foo!( fn main() { body } )".to_string(), &sess).unwrap();
// See `recurse_into_file_modules` in the parser.
#[test]
fn out_of_line_mod() {
- with_globals(|| {
+ with_default_globals(|| {
let sess = ParseSess::new(FilePathMapping::empty());
let item = parse_item_from_source_str(
PathBuf::from("foo").into(),
}
#[derive(Clone, Copy, PartialEq, Debug)]
-enum SemiColonMode {
+crate enum SemiColonMode {
Break,
Ignore,
Comma,
}
#[derive(Clone, Copy, PartialEq, Debug)]
-enum BlockMode {
+crate enum BlockMode {
Break,
Ignore,
}
let body = TokenTree::Delimited(
delim_span,
token::Bracket,
- [TokenTree::Token(sp, token::Ident(ast::Ident::from_str("doc"), false)),
+ [TokenTree::Token(sp, token::Ident(ast::Ident::with_empty_ctxt(sym::doc), false)),
TokenTree::Token(sp, token::Eq),
TokenTree::Token(sp, token::Literal(
token::StrRaw(Symbol::intern(&stripped), num_of_hashes), None))
}
impl TokenType {
- fn to_string(&self) -> String {
+ crate fn to_string(&self) -> String {
match *self {
TokenType::Token(ref t) => format!("`{}`", pprust::token_to_string(t)),
TokenType::Keyword(kw) => format!("`{}`", kw.name()),
}
}
- fn recover_closing_delimiter(
- &mut self,
- tokens: &[token::Token],
- mut err: DiagnosticBuilder<'a>,
- ) -> PResult<'a, bool> {
- let mut pos = None;
- // we want to use the last closing delim that would apply
- for (i, unmatched) in self.unclosed_delims.iter().enumerate().rev() {
- if tokens.contains(&token::CloseDelim(unmatched.expected_delim))
- && Some(self.span) > unmatched.unclosed_span
- {
- pos = Some(i);
- }
- }
- match pos {
- Some(pos) => {
- // Recover and assume that the detected unclosed delimiter was meant for
- // this location. Emit the diagnostic and act as if the delimiter was
- // present for the parser's sake.
-
- // Don't attempt to recover from this unclosed delimiter more than once.
- let unmatched = self.unclosed_delims.remove(pos);
- let delim = TokenType::Token(token::CloseDelim(unmatched.expected_delim));
-
- // We want to suggest the inclusion of the closing delimiter where it makes
- // the most sense, which is immediately after the last token:
- //
- // {foo(bar {}}
- // - ^
- // | |
- // | help: `)` may belong here (FIXME: #58270)
- // |
- // unclosed delimiter
- if let Some(sp) = unmatched.unclosed_span {
- err.span_label(sp, "unclosed delimiter");
- }
- err.span_suggestion_short(
- self.sess.source_map().next_point(self.prev_span),
- &format!("{} may belong here", delim.to_string()),
- delim.to_string(),
- Applicability::MaybeIncorrect,
- );
- err.emit();
- self.expected_tokens.clear(); // reduce errors
- Ok(true)
- }
- _ => Err(err),
- }
- }
-
/// Expect next token to be edible or inedible token. If edible,
/// then consume it; if inedible, then return without consuming
/// anything. Signal a fatal error if next token is unexpected.
})
}
- fn mk_expr(&self, span: Span, node: ExprKind, attrs: ThinVec<Attribute>) -> P<Expr> {
+ crate fn mk_expr(&self, span: Span, node: ExprKind, attrs: ThinVec<Attribute>) -> P<Expr> {
P(Expr { node, span, attrs, id: ast::DUMMY_NODE_ID })
}
db.note("variable declaration using `let` is a statement");
return Err(db);
} else if self.span.rust_2018() && self.eat_keyword(keywords::Await) {
- // FIXME: remove this branch when `await!` is no longer supported
- // https://github.com/rust-lang/rust/issues/60610
- self.expect(&token::Not)?;
- self.expect(&token::OpenDelim(token::Paren))?;
- let expr = self.parse_expr()?;
- self.expect(&token::CloseDelim(token::Paren))?;
- hi = self.prev_span;
- ex = ExprKind::Await(ast::AwaitOrigin::MacroLike, expr);
+ let (await_hi, e_kind) = self.parse_await_macro_or_alt(lo, self.prev_span)?;
+ hi = await_hi;
+ ex = e_kind;
} else if self.token.is_path_start() {
let path = self.parse_path(PathStyle::Expr)?;
self.maybe_recover_from_bad_qpath(expr, true)
}
+ /// Parse `await!(<expr>)` calls, or alternatively recover from incorrect but reasonable
+ /// alternative syntaxes `await <expr>`, `await? <expr>`, `await(<expr>)` and
+ /// `await { <expr> }`.
+ fn parse_await_macro_or_alt(
+ &mut self,
+ lo: Span,
+ await_sp: Span,
+ ) -> PResult<'a, (Span, ExprKind)> {
+ if self.token == token::Not {
+ // Handle correct `await!(<expr>)`.
+ // FIXME: make this an error when `await!` is no longer supported
+ // https://github.com/rust-lang/rust/issues/60610
+ self.expect(&token::Not)?;
+ self.expect(&token::OpenDelim(token::Paren))?;
+ let expr = self.parse_expr().map_err(|mut err| {
+ err.span_label(await_sp, "while parsing this await macro call");
+ err
+ })?;
+ self.expect(&token::CloseDelim(token::Paren))?;
+ Ok((self.prev_span, ExprKind::Await(ast::AwaitOrigin::MacroLike, expr)))
+ } else { // Handle `await <expr>`.
+ self.parse_incorrect_await_syntax(lo, await_sp)
+ }
+ }
+
fn maybe_parse_struct_expr(
&mut self,
lo: Span,
}
/// Parses a block or unsafe block.
- fn parse_block_expr(&mut self, opt_label: Option<Label>,
- lo: Span, blk_mode: BlockCheckMode,
- outer_attrs: ThinVec<Attribute>)
- -> PResult<'a, P<Expr>> {
+ crate fn parse_block_expr(
+ &mut self,
+ opt_label: Option<Label>,
+ lo: Span,
+ blk_mode: BlockCheckMode,
+ outer_attrs: ThinVec<Attribute>,
+ ) -> PResult<'a, P<Expr>> {
self.expect(&token::OpenDelim(token::Brace))?;
let mut attrs = outer_attrs;
ExprKind::Await(ast::AwaitOrigin::FieldLike, self_arg),
ThinVec::new(),
);
+ self.recover_from_await_method_call();
return Ok(await_expr);
}
let segment = self.parse_path_segment(PathStyle::Expr)?;
return Ok(e);
}
- fn recover_seq_parse_error(
- &mut self,
- delim: token::DelimToken,
- lo: Span,
- result: PResult<'a, P<Expr>>,
- ) -> P<Expr> {
- match result {
- Ok(x) => x,
- Err(mut err) => {
- err.emit();
- // recover from parse error
- self.consume_block(delim);
- self.mk_expr(lo.to(self.prev_span), ExprKind::Err, ThinVec::new())
- }
- }
- }
-
crate fn process_potential_macro_variable(&mut self) {
let (token, span) = match self.token {
token::Dollar if self.span.ctxt() != syntax_pos::hygiene::SyntaxContext::empty() &&
let binary = self.mk_binary(source_map::respan(cur_op_span, ast_op), lhs, rhs);
self.mk_expr(span, binary, ThinVec::new())
}
- AssocOp::Assign =>
- self.mk_expr(span, ExprKind::Assign(lhs, rhs), ThinVec::new()),
+ AssocOp::Assign => self.mk_expr(span, ExprKind::Assign(lhs, rhs), ThinVec::new()),
AssocOp::ObsoleteInPlace =>
self.mk_expr(span, ExprKind::ObsoleteInPlace(lhs, rhs), ThinVec::new()),
AssocOp::AssignOp(k) => {
Ok(lhs)
}
- fn could_ascription_be_path(&self, node: &ast::ExprKind) -> bool {
- self.token.is_ident() &&
- if let ast::ExprKind::Path(..) = node { true } else { false } &&
- !self.token.is_reserved_ident() && // v `foo:bar(baz)`
- self.look_ahead(1, |t| t == &token::OpenDelim(token::Paren)) ||
- self.look_ahead(1, |t| t == &token::Lt) && // `foo:bar<baz`
- self.look_ahead(2, |t| t.is_ident()) ||
- self.look_ahead(1, |t| t == &token::Colon) && // `foo:bar:baz`
- self.look_ahead(2, |t| t.is_ident()) ||
- self.look_ahead(1, |t| t == &token::ModSep) && // `foo:bar::baz`
- self.look_ahead(2, |t| t.is_ident())
- }
-
- fn bad_type_ascription(
- &self,
- err: &mut DiagnosticBuilder<'a>,
- lhs_span: Span,
- cur_op_span: Span,
- next_sp: Span,
- maybe_path: bool,
- ) {
- err.span_label(self.span, "expecting a type here because of type ascription");
- let cm = self.sess.source_map();
- let next_pos = cm.lookup_char_pos(next_sp.lo());
- let op_pos = cm.lookup_char_pos(cur_op_span.hi());
- if op_pos.line != next_pos.line {
- err.span_suggestion(
- cur_op_span,
- "try using a semicolon",
- ";".to_string(),
- Applicability::MaybeIncorrect,
- );
- } else {
- if maybe_path {
- err.span_suggestion(
- cur_op_span,
- "maybe you meant to write a path separator here",
- "::".to_string(),
- Applicability::MaybeIncorrect,
- );
- } else {
- err.note("type ascription is a nightly-only feature that lets \
- you annotate an expression with a type: `<expr>: <type>`");
- err.span_note(
- lhs_span,
- "this expression expects an ascribed type after the colon",
- );
- err.help("this might be indicative of a syntax error elsewhere");
- }
- }
- }
-
fn parse_assoc_op_cast(&mut self, lhs: P<Expr>, lhs_span: Span,
expr_kind: fn(P<Expr>, P<Ty>) -> ExprKind)
-> PResult<'a, P<Expr>> {
Ok(self.parse_stmt_(true))
}
- // Eat tokens until we can be relatively sure we reached the end of the
- // statement. This is something of a best-effort heuristic.
- //
- // We terminate when we find an unmatched `}` (without consuming it).
- fn recover_stmt(&mut self) {
- self.recover_stmt_(SemiColonMode::Ignore, BlockMode::Ignore)
- }
-
- // If `break_on_semi` is `Break`, then we will stop consuming tokens after
- // finding (and consuming) a `;` outside of `{}` or `[]` (note that this is
- // approximate - it can mean we break too early due to macros, but that
- // should only lead to sub-optimal recovery, not inaccurate parsing).
- //
- // If `break_on_block` is `Break`, then we will stop consuming tokens
- // after finding (and consuming) a brace-delimited block.
- fn recover_stmt_(&mut self, break_on_semi: SemiColonMode, break_on_block: BlockMode) {
- let mut brace_depth = 0;
- let mut bracket_depth = 0;
- let mut in_block = false;
- debug!("recover_stmt_ enter loop (semi={:?}, block={:?})",
- break_on_semi, break_on_block);
- loop {
- debug!("recover_stmt_ loop {:?}", self.token);
- match self.token {
- token::OpenDelim(token::DelimToken::Brace) => {
- brace_depth += 1;
- self.bump();
- if break_on_block == BlockMode::Break &&
- brace_depth == 1 &&
- bracket_depth == 0 {
- in_block = true;
- }
- }
- token::OpenDelim(token::DelimToken::Bracket) => {
- bracket_depth += 1;
- self.bump();
- }
- token::CloseDelim(token::DelimToken::Brace) => {
- if brace_depth == 0 {
- debug!("recover_stmt_ return - close delim {:?}", self.token);
- break;
- }
- brace_depth -= 1;
- self.bump();
- if in_block && bracket_depth == 0 && brace_depth == 0 {
- debug!("recover_stmt_ return - block end {:?}", self.token);
- break;
- }
- }
- token::CloseDelim(token::DelimToken::Bracket) => {
- bracket_depth -= 1;
- if bracket_depth < 0 {
- bracket_depth = 0;
- }
- self.bump();
- }
- token::Eof => {
- debug!("recover_stmt_ return - Eof");
- break;
- }
- token::Semi => {
- self.bump();
- if break_on_semi == SemiColonMode::Break &&
- brace_depth == 0 &&
- bracket_depth == 0 {
- debug!("recover_stmt_ return - Semi");
- break;
- }
- }
- token::Comma => {
- if break_on_semi == SemiColonMode::Comma &&
- brace_depth == 0 &&
- bracket_depth == 0 {
- debug!("recover_stmt_ return - Semi");
- break;
- } else {
- self.bump();
- }
- }
- _ => {
- self.bump()
- }
- }
- }
- }
-
fn parse_stmt_(&mut self, macro_legacy_warnings: bool) -> Option<Stmt> {
self.parse_stmt_without_recovery(macro_legacy_warnings).unwrap_or_else(|mut e| {
e.emit();
Ok((class_name, ItemKind::Union(vdata, generics), None))
}
- fn consume_block(&mut self, delim: token::DelimToken) {
- let mut brace_depth = 0;
- loop {
- if self.eat(&token::OpenDelim(delim)) {
- brace_depth += 1;
- } else if self.eat(&token::CloseDelim(delim)) {
- if brace_depth == 0 {
- return;
- } else {
- brace_depth -= 1;
- continue;
- }
- } else if self.token == token::Eof || self.eat(&token::CloseDelim(token::NoDelim)) {
- return;
- } else {
- self.bump();
- }
- }
- }
-
fn parse_record_struct_body(
&mut self,
) -> PResult<'a, (Vec<StructField>, /* recovered */ bool)> {
let attr = Attribute {
id: attr::mk_attr_id(),
style: ast::AttrStyle::Outer,
- path: ast::Path::from_ident(Ident::from_str("warn_directory_ownership")),
+ path: ast::Path::from_ident(
+ Ident::with_empty_ctxt(sym::warn_directory_ownership)),
tokens: TokenStream::empty(),
is_sugared_doc: false,
span: syntax_pos::DUMMY_SP,
).emit();
}
- /// Recover from `pub` keyword in places where it seems _reasonable_ but isn't valid.
- fn eat_bad_pub(&mut self) {
- if self.token.is_keyword(keywords::Pub) {
- match self.parse_visibility(false) {
- Ok(vis) => {
- let mut err = self.diagnostic()
- .struct_span_err(vis.span, "unnecessary visibility qualifier");
- err.span_label(vis.span, "`pub` not permitted here");
- err.emit();
- }
- Err(mut err) => err.emit(),
- }
- }
- }
-
/// When lowering a `async fn` to the HIR, we need to move all of the arguments of the function
/// into the generated closure so that they are dropped when the future is polled and not when
/// it is created.
use std::fmt;
use std::mem;
#[cfg(target_arch = "x86_64")]
-use rustc_data_structures::static_assert;
+use rustc_data_structures::static_assert_size;
use rustc_data_structures::sync::Lrc;
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
}
#[cfg(target_arch = "x86_64")]
-static_assert!(MEM_SIZE_OF_LIT: mem::size_of::<Lit>() == 8);
+static_assert_size!(Lit, 8);
impl Lit {
crate fn literal_name(&self) -> &'static str {
// `Token` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")]
-static_assert!(MEM_SIZE_OF_STATEMENT: mem::size_of::<Token>() == 16);
+static_assert_size!(Token, 16);
impl Token {
/// Recovers a `Token` from an `ast::Ident`. This creates a raw identifier if necessary.
use crate::print::pp::Breaks::{Consistent, Inconsistent};
use crate::ptr::P;
use crate::std_inject;
-use crate::symbol::keywords;
+use crate::symbol::{keywords, sym};
use crate::tokenstream::{self, TokenStream, TokenTree};
use rustc_target::spec::abi::{self, Abi};
// of the feature gate, so we fake them up here.
// #![feature(prelude_import)]
- let pi_nested = attr::mk_nested_word_item(ast::Ident::from_str("prelude_import"));
- let list = attr::mk_list_item(DUMMY_SP, ast::Ident::from_str("feature"), vec![pi_nested]);
+ let pi_nested = attr::mk_nested_word_item(ast::Ident::with_empty_ctxt(sym::prelude_import));
+ let list = attr::mk_list_item(
+ DUMMY_SP, ast::Ident::with_empty_ctxt(sym::feature), vec![pi_nested]);
let fake_attr = attr::mk_attr_inner(DUMMY_SP, attr::mk_attr_id(), list);
s.print_attribute(&fake_attr)?;
// #![no_std]
- let no_std_meta = attr::mk_word_item(ast::Ident::from_str("no_std"));
+ let no_std_meta = attr::mk_word_item(ast::Ident::with_empty_ctxt(sym::no_std));
let fake_attr = attr::mk_attr_inner(DUMMY_SP, attr::mk_attr_id(), no_std_meta);
s.print_attribute(&fake_attr)?;
}
use crate::ast;
use crate::source_map;
- use crate::with_globals;
+ use crate::with_default_globals;
use syntax_pos;
#[test]
fn test_fun_to_string() {
- with_globals(|| {
+ with_default_globals(|| {
let abba_ident = ast::Ident::from_str("abba");
let decl = ast::FnDecl {
#[test]
fn test_variant_to_string() {
- with_globals(|| {
+ with_default_globals(|| {
let ident = ast::Ident::from_str("principal_skinner");
let var = source_map::respan(syntax_pos::DUMMY_SP, ast::Variant_ {
allow_internal_unstable,
allow_internal_unsafe: false,
local_inner_macros: false,
- edition: hygiene::default_edition(),
+ edition: edition::Edition::from_session(),
});
span.with_ctxt(SyntaxContext::empty().apply_mark(mark))
}
use crate::attr;
use crate::edition::Edition;
use crate::ext::hygiene::{Mark, SyntaxContext};
-use crate::symbol::{Symbol, keywords, sym};
-use crate::source_map::{ExpnInfo, MacroAttribute, dummy_spanned, hygiene, respan};
+use crate::symbol::{Ident, Symbol, keywords, sym};
+use crate::source_map::{ExpnInfo, MacroAttribute, dummy_spanned, respan};
use crate::ptr::P;
use crate::tokenstream::TokenStream;
/// Craft a span that will be ignored by the stability lint's
/// call to source_map's `is_internal` check.
/// The expanded code uses the unstable `#[prelude_import]` attribute.
-fn ignored_span(sp: Span) -> Span {
+fn ignored_span(sp: Span, edition: Edition) -> Span {
let mark = Mark::fresh(Mark::root());
mark.set_expn_info(ExpnInfo {
call_site: DUMMY_SP,
].into()),
allow_internal_unsafe: false,
local_inner_macros: false,
- edition: hygiene::default_edition(),
+ edition,
});
sp.with_ctxt(SyntaxContext::empty().apply_mark(mark))
}
// .rev() to preserve ordering above in combination with insert(0, ...)
let alt_std_name = alt_std_name.map(Symbol::intern);
- for orig_name in names.iter().rev() {
- let orig_name = Symbol::intern(orig_name);
- let mut rename = orig_name;
+ for orig_name_str in names.iter().rev() {
// HACK(eddyb) gensym the injected crates on the Rust 2018 edition,
// so they don't accidentally interfere with the new import paths.
- if rust_2018 {
- rename = orig_name.gensymed();
- }
- let orig_name = if rename != orig_name {
- Some(orig_name)
+ let orig_name_sym = Symbol::intern(orig_name_str);
+ let orig_name_ident = Ident::with_empty_ctxt(orig_name_sym);
+ let (rename, orig_name) = if rust_2018 {
+ (orig_name_ident.gensym(), Some(orig_name_sym))
} else {
- None
+ (orig_name_ident, None)
};
krate.module.items.insert(0, P(ast::Item {
- attrs: vec![attr::mk_attr_outer(DUMMY_SP,
- attr::mk_attr_id(),
- attr::mk_word_item(ast::Ident::from_str("macro_use")))],
+ attrs: vec![attr::mk_attr_outer(
+ DUMMY_SP,
+ attr::mk_attr_id(),
+ attr::mk_word_item(ast::Ident::with_empty_ctxt(sym::macro_use))
+ )],
vis: dummy_spanned(ast::VisibilityKind::Inherited),
node: ast::ItemKind::ExternCrate(alt_std_name.or(orig_name)),
- ident: ast::Ident::with_empty_ctxt(rename),
+ ident: rename,
id: ast::DUMMY_NODE_ID,
span: DUMMY_SP,
tokens: None,
INJECTED_CRATE_NAME.with(|opt_name| opt_name.set(Some(name)));
- let span = ignored_span(DUMMY_SP);
+ let span = ignored_span(DUMMY_SP, edition);
krate.module.items.insert(0, P(ast::Item {
attrs: vec![ast::Attribute {
style: ast::AttrStyle::Outer,
EntryPointType::MainAttr |
EntryPointType::Start =>
item.map(|ast::Item {id, ident, attrs, node, vis, span, tokens}| {
- let allow_ident = Ident::from_str("allow");
+ let allow_ident = Ident::with_empty_ctxt(sym::allow);
let dc_nested = attr::mk_nested_word_item(Ident::from_str("dead_code"));
let allow_dead_code_item = attr::mk_list_item(DUMMY_SP, allow_ident,
vec![dc_nested]);
tests: Vec<Ident>,
tested_submods: Vec<(Ident, Ident)>)
-> (P<ast::Item>, Ident) {
- let super_ = Ident::from_str("super");
+ let super_ = Ident::with_empty_ctxt(keywords::Super.name());
let items = tests.into_iter().map(|r| {
cx.ext_cx.item_use_simple(DUMMY_SP, dummy_spanned(ast::VisibilityKind::Public),
items,
};
- let sym = Ident::with_empty_ctxt(Symbol::gensym("__test_reexports"));
+ let name = Ident::from_str("__test_reexports").gensym();
let parent = if parent == ast::DUMMY_NODE_ID { ast::CRATE_NODE_ID } else { parent };
cx.ext_cx.current_expansion.mark = cx.ext_cx.resolver.get_module_scope(parent);
let it = cx.ext_cx.monotonic_expander().flat_map_item(P(ast::Item {
- ident: sym,
+ ident: name,
attrs: Vec::new(),
id: ast::DUMMY_NODE_ID,
node: ast::ItemKind::Mod(reexport_mod),
tokens: None,
})).pop().unwrap();
- (it, sym)
+ (it, name)
}
/// Crawl over the crate, inserting test reexports and the test main function
].into()),
allow_internal_unsafe: false,
local_inner_macros: false,
- edition: hygiene::default_edition(),
+ edition: sess.edition,
});
TestHarnessGenerator {
main_body);
// Honor the reexport_test_harness_main attribute
- let main_id = Ident::new(
- cx.reexport_test_harness_main.unwrap_or(Symbol::gensym("main")),
- sp);
+ let main_id = match cx.reexport_test_harness_main {
+ Some(sym) => Ident::new(sym, sp),
+ None => Ident::from_str_and_span("main", sp).gensym(),
+ };
P(ast::Item {
ident: main_id,
use crate::source_map::{SourceMap, FilePathMapping};
-use crate::with_globals;
+use crate::with_default_globals;
use errors::Handler;
use errors::emitter::EmitterWriter;
}
fn test_harness(file_text: &str, span_labels: Vec<SpanLabel>, expected_output: &str) {
- with_globals(|| {
+ with_default_globals(|| {
let output = Arc::new(Mutex::new(Vec::new()));
let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty()));
use syntax_pos::{BytePos, Mark, Span, DUMMY_SP};
#[cfg(target_arch = "x86_64")]
-use rustc_data_structures::static_assert;
+use rustc_data_structures::static_assert_size;
use rustc_data_structures::sync::Lrc;
use serialize::{Decoder, Decodable, Encoder, Encodable};
use smallvec::{SmallVec, smallvec};
// `TokenStream` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")]
-static_assert!(MEM_SIZE_OF_TOKEN_STREAM: mem::size_of::<TokenStream>() == 8);
+static_assert_size!(TokenStream, 8);
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum IsJoint {
mod tests {
use super::*;
use crate::syntax::ast::Ident;
- use crate::with_globals;
+ use crate::with_default_globals;
use crate::parse::token::Token;
use crate::util::parser_testing::string_to_stream;
use syntax_pos::{Span, BytePos, NO_EXPANSION};
#[test]
fn test_concat() {
- with_globals(|| {
+ with_default_globals(|| {
let test_res = string_to_ts("foo::bar::baz");
let test_fst = string_to_ts("foo::bar");
let test_snd = string_to_ts("::baz");
#[test]
fn test_to_from_bijection() {
- with_globals(|| {
+ with_default_globals(|| {
let test_start = string_to_ts("foo::bar(baz)");
let test_end = test_start.trees().collect();
assert_eq!(test_start, test_end)
#[test]
fn test_eq_0() {
- with_globals(|| {
+ with_default_globals(|| {
let test_res = string_to_ts("foo");
let test_eqs = string_to_ts("foo");
assert_eq!(test_res, test_eqs)
#[test]
fn test_eq_1() {
- with_globals(|| {
+ with_default_globals(|| {
let test_res = string_to_ts("::bar::baz");
let test_eqs = string_to_ts("::bar::baz");
assert_eq!(test_res, test_eqs)
#[test]
fn test_eq_3() {
- with_globals(|| {
+ with_default_globals(|| {
let test_res = string_to_ts("");
let test_eqs = string_to_ts("");
assert_eq!(test_res, test_eqs)
#[test]
fn test_diseq_0() {
- with_globals(|| {
+ with_default_globals(|| {
let test_res = string_to_ts("::bar::baz");
let test_eqs = string_to_ts("bar::baz");
assert_eq!(test_res == test_eqs, false)
#[test]
fn test_diseq_1() {
- with_globals(|| {
+ with_default_globals(|| {
let test_res = string_to_ts("(bar,baz)");
let test_eqs = string_to_ts("bar,baz");
assert_eq!(test_res == test_eqs, false)
#[test]
fn test_is_empty() {
- with_globals(|| {
+ with_default_globals(|| {
let test0: TokenStream = Vec::<TokenTree>::new().into_iter().collect();
let test1: TokenStream =
TokenTree::Token(sp(0, 1), Token::Ident(Ident::from_str("a"), false)).into();
#[test]
fn test_dotdotdot() {
- let mut builder = TokenStreamBuilder::new();
- builder.push(TokenTree::Token(sp(0, 1), Token::Dot).joint());
- builder.push(TokenTree::Token(sp(1, 2), Token::Dot).joint());
- builder.push(TokenTree::Token(sp(2, 3), Token::Dot));
- let stream = builder.build();
- assert!(stream.eq_unspanned(&string_to_ts("...")));
- assert_eq!(stream.trees().count(), 1);
+ with_default_globals(|| {
+ let mut builder = TokenStreamBuilder::new();
+ builder.push(TokenTree::Token(sp(0, 1), Token::Dot).joint());
+ builder.push(TokenTree::Token(sp(1, 2), Token::Dot).joint());
+ builder.push(TokenTree::Token(sp(2, 3), Token::Dot));
+ let stream = builder.build();
+ assert!(stream.eq_unspanned(&string_to_ts("...")));
+ assert_eq!(stream.trees().count(), 1);
+ })
}
}
#[test]
fn test_find_best_match_for_name() {
- use crate::with_globals;
- with_globals(|| {
+ use crate::with_default_globals;
+ with_default_globals(|| {
let input = vec![Symbol::intern("aaab"), Symbol::intern("aaabc")];
assert_eq!(
find_best_match_for_name(input.iter(), "aaaa", None),
use syntax::ast::{self, Ident, GenericArg};
use syntax::ext::base::{self, *};
use syntax::ext::build::AstBuilder;
-use syntax::symbol::{keywords, Symbol};
+use syntax::symbol::{keywords, Symbol, sym};
use syntax_pos::Span;
use syntax::tokenstream;
true,
cx.std_path(&["option", "Option", "None"]),
vec![GenericArg::Type(cx.ty_rptr(sp,
- cx.ty_ident(sp, Ident::from_str("str")),
+ cx.ty_ident(sp,
+ Ident::with_empty_ctxt(sym::str)),
Some(lt),
ast::Mutability::Immutable))],
vec![]))
use rustc_data_structures::sync::Lrc;
use syntax::ast;
use syntax::ext::base::{MacroExpanderFn, NormalTT, NamedSyntaxExtension, MultiModifier};
-use syntax::ext::hygiene;
use syntax::symbol::Symbol;
+use syntax::edition::Edition;
pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver,
- user_exts: Vec<NamedSyntaxExtension>) {
+ user_exts: Vec<NamedSyntaxExtension>,
+ edition: Edition) {
deriving::register_builtin_derives(resolver);
let mut register = |name, ext| {
resolver.add_builtin(ast::Ident::with_empty_ctxt(name), Lrc::new(ext));
};
-
macro_rules! register {
($( $name:ident: $f:expr, )*) => { $(
register(Symbol::intern(stringify!($name)),
allow_internal_unsafe: false,
local_inner_macros: false,
unstable_feature: None,
- edition: hygiene::default_edition(),
+ edition,
});
)* }
}
allow_internal_unsafe: false,
local_inner_macros: false,
unstable_feature: None,
- edition: hygiene::default_edition(),
+ edition,
});
register(Symbol::intern("format_args_nl"),
NormalTT {
allow_internal_unsafe: false,
local_inner_macros: false,
unstable_feature: None,
- edition: hygiene::default_edition(),
+ edition,
});
for (name, ext) in user_exts {
use syntax::ast::{self, Ident};
use syntax::attr;
-use syntax::source_map::{ExpnInfo, MacroAttribute, hygiene, respan};
+use syntax::source_map::{ExpnInfo, MacroAttribute, respan};
use syntax::ext::base::ExtCtxt;
use syntax::ext::build::AstBuilder;
use syntax::ext::expand::ExpansionConfig;
].into()),
allow_internal_unsafe: false,
local_inner_macros: false,
- edition: hygiene::default_edition(),
+ edition: cx.parse_sess.edition,
});
let span = DUMMY_SP.apply_mark(mark);
- let hidden = cx.meta_list_item_word(span, Symbol::intern("hidden"));
- let doc = cx.meta_list(span, Symbol::intern("doc"), vec![hidden]);
+ let hidden = cx.meta_list_item_word(span, sym::hidden);
+ let doc = cx.meta_list(span, sym::doc, vec![hidden]);
let doc_hidden = cx.attribute(span, doc);
- let proc_macro = Ident::from_str("proc_macro");
+ let proc_macro = Ident::with_empty_ctxt(sym::proc_macro);
let krate = cx.item(span,
proc_macro,
Vec::new(),
let module = cx.item_mod(
span,
span,
- ast::Ident::with_empty_ctxt(Symbol::gensym("decls")),
+ ast::Ident::from_str("decls").gensym(),
vec![doc_hidden],
vec![krate, decls_static],
).map(|mut i| {
use syntax::ext::base::*;
use syntax::ext::build::AstBuilder;
-use syntax::ext::hygiene::{self, Mark, SyntaxContext};
+use syntax::ext::hygiene::{Mark, SyntaxContext};
use syntax::attr;
use syntax::ast;
use syntax::print::pprust;
].into()),
allow_internal_unsafe: false,
local_inner_macros: false,
- edition: hygiene::default_edition(),
+ edition: cx.parse_sess.edition,
});
(item.span.with_ctxt(SyntaxContext::empty().apply_mark(mark)),
attr_sp.with_ctxt(SyntaxContext::empty().apply_mark(mark)))
])
};
- let mut test_const = cx.item(sp, ast::Ident::new(item.ident.name.gensymed(), sp),
+ let mut test_const = cx.item(sp, ast::Ident::new(item.ident.name, sp).gensym(),
vec![
// #[cfg(test)]
cx.attribute(attr_sp, cx.meta_list(attr_sp, Symbol::intern("cfg"), vec![
use syntax::ext::base::*;
use syntax::ext::build::AstBuilder;
-use syntax::ext::hygiene::{self, Mark, SyntaxContext};
+use syntax::ext::hygiene::{Mark, SyntaxContext};
use syntax::ast;
use syntax::source_map::respan;
use syntax::symbol::{Symbol, sym};
].into()),
allow_internal_unsafe: false,
local_inner_macros: false,
- edition: hygiene::default_edition(),
+ edition: ecx.parse_sess.edition,
});
attr_sp.with_ctxt(SyntaxContext::empty().apply_mark(mark))
};
use crate::symbol::{Symbol, sym};
use std::fmt;
use std::str::FromStr;
+use crate::GLOBALS;
/// The edition of the compiler (RFC 2052)
#[derive(Clone, Copy, Hash, PartialEq, PartialOrd, Debug, RustcEncodable, RustcDecodable, Eq)]
}
impl Edition {
+ pub fn from_session() -> Edition {
+ GLOBALS.with(|globals| globals.edition)
+ }
+
pub fn lint_name(&self) -> &'static str {
match *self {
Edition::Edition2015 => "rust_2015_compatibility",
use crate::GLOBALS;
use crate::Span;
-use crate::edition::{Edition, DEFAULT_EDITION};
+use crate::edition::Edition;
use crate::symbol::{keywords, Symbol};
use serialize::{Encodable, Decodable, Encoder, Decoder};
marks: Vec<MarkData>,
syntax_contexts: Vec<SyntaxContextData>,
markings: FxHashMap<(SyntaxContext, Mark, Transparency), SyntaxContext>,
- default_edition: Edition,
}
impl HygieneData {
dollar_crate_name: keywords::DollarCrate.name(),
}],
markings: FxHashMap::default(),
- default_edition: DEFAULT_EDITION,
}
}
}
}
-pub fn default_edition() -> Edition {
- HygieneData::with(|data| data.default_edition)
-}
-
-pub fn set_default_edition(edition: Edition) {
- HygieneData::with(|data| data.default_edition = edition);
-}
-
pub fn clear_markings() {
HygieneData::with(|data| data.markings = FxHashMap::default());
}
extern crate serialize as rustc_serialize; // used by deriving
pub mod edition;
+use edition::Edition;
pub mod hygiene;
pub use hygiene::{Mark, SyntaxContext, ExpnInfo, ExpnFormat, CompilerDesugaringKind};
symbol_interner: Lock<symbol::Interner>,
span_interner: Lock<span_encoding::SpanInterner>,
hygiene_data: Lock<hygiene::HygieneData>,
+ edition: Edition,
}
impl Globals {
- pub fn new() -> Globals {
+ pub fn new(edition: Edition) -> Globals {
Globals {
symbol_interner: Lock::new(symbol::Interner::fresh()),
span_interner: Lock::new(span_encoding::SpanInterner::default()),
hygiene_data: Lock::new(hygiene::HygieneData::new()),
+ edition,
}
}
}
/// Edition of the crate from which this span came.
pub fn edition(self) -> edition::Edition {
- self.ctxt().outer().expn_info().map_or_else(|| hygiene::default_edition(),
- |einfo| einfo.edition)
+ self.ctxt().outer().expn_info().map_or_else(|| {
+ Edition::from_session()
+ }, |einfo| einfo.edition)
}
#[inline]
document_private_items,
dotdoteq_in_patterns,
dotdot_in_tuple_patterns,
+ double_braced_crate: "{{crate}}",
+ double_braced_impl: "{{impl}}",
+ double_braced_misc: "{{misc}}",
+ double_braced_closure: "{{closure}}",
+ double_braced_constructor: "{{constructor}}",
+ double_braced_constant: "{{constant}}",
+ double_braced_opaque: "{{opaque}}",
dropck_eyepatch,
dropck_parametricity,
drop_types_in_const,
eh_personality,
eh_unwind_resume,
enable,
+ err,
Err,
except,
exclusive_range_pattern,
fundamental,
future,
Future,
+ gen_future,
generators,
generic_associated_types,
generic_param_attrs,
match_default_bindings,
may_dangle,
message,
+ meta,
min_const_fn,
min_const_unsafe_fn,
mips_target_feature,
never,
never_type,
next,
+ __next,
nll,
no_builtins,
no_core,
option,
Option,
opt_out_copy,
+ Output,
overlapping_marker_traits,
packed,
panic_handler,
Pending,
pin,
Pin,
+ pinned,
platform_intrinsics,
plugin,
plugin_registrar,
static_nobundle,
static_recursion,
std,
+ str,
stmt_expr_attributes,
stop_after_dataflow,
struct_field_attributes,
trivial_bounds,
Try,
try_blocks,
+ try_trait,
tuple_indexing,
ty,
type_alias_enum_variants,
uniform_paths,
universal_impl_trait,
unmarked_api,
+ unreachable_code,
unrestricted_attribute_tokens,
unsafe_destructor_blind_to_params,
unsafe_no_drop_flag,
use_nested_groups,
usize,
v1,
+ val,
vis,
visible_private_types,
volatile,
impl Ident {
#[inline]
+ /// Constructs a new identifier from a symbol and a span.
pub const fn new(name: Symbol, span: Span) -> Ident {
Ident { name, span }
}
+ /// Constructs a new identifier with an empty syntax context.
#[inline]
pub const fn with_empty_ctxt(name: Symbol) -> Ident {
Ident::new(name, DUMMY_SP)
Ident::with_empty_ctxt(string.as_symbol())
}
- /// Maps a string to an identifier with an empty syntax context.
+ /// Maps a string to an identifier with an empty span.
pub fn from_str(string: &str) -> Ident {
Ident::with_empty_ctxt(Symbol::intern(string))
}
+ /// Maps a string and a span to an identifier.
+ pub fn from_str_and_span(string: &str, span: Span) -> Ident {
+ Ident::new(Symbol::intern(string), span)
+ }
+
/// Replaces `lo` and `hi` with those from `span`, but keep hygiene context.
pub fn with_span_pos(self, span: Span) -> Ident {
Ident::new(self.name, span.with_ctxt(self.span.ctxt()))
Ident::new(self.name, self.span.modern_and_legacy())
}
+ /// Transforms an identifier into one with the same name, but gensymed.
pub fn gensym(self) -> Ident {
- Ident::new(self.name.gensymed(), self.span)
+ let name = with_interner(|interner| interner.gensymed(self.name));
+ Ident::new(name, self.span)
}
+ /// Transforms an underscore identifier into one with the same name, but
+ /// gensymed. Leaves non-underscore identifiers unchanged.
pub fn gensym_if_underscore(self) -> Ident {
if self.name == keywords::Underscore.name() { self.gensym() } else { self }
}
+ // WARNING: this function is deprecated and will be removed in the future.
+ pub fn is_gensymed(self) -> bool {
+ with_interner(|interner| interner.is_gensymed(self.name))
+ }
+
pub fn as_str(self) -> LocalInternedString {
self.name.as_str()
}
Ok(if !string.starts_with('#') {
Ident::from_str(&string)
} else { // FIXME(jseyfried): intercrate hygiene
- Ident::with_empty_ctxt(Symbol::gensym(&string[1..]))
+ Ident::from_str(&string[1..]).gensym()
})
}
}
/// A symbol is an interned or gensymed string. A gensym is a symbol that is
-/// never equal to any other symbol. E.g.:
-/// ```
-/// assert_eq!(Symbol::intern("x"), Symbol::intern("x"))
-/// assert_ne!(Symbol::gensym("x"), Symbol::intern("x"))
-/// assert_ne!(Symbol::gensym("x"), Symbol::gensym("x"))
-/// ```
+/// never equal to any other symbol.
+///
/// Conceptually, a gensym can be thought of as a normal symbol with an
/// invisible unique suffix. Gensyms are useful when creating new identifiers
/// that must not match any existing identifiers, e.g. during macro expansion
-/// and syntax desugaring.
+/// and syntax desugaring. Because gensyms should always be identifiers, all
+/// gensym operations are on `Ident` rather than `Symbol`. (Indeed, in the
+/// future the gensym-ness may be moved from `Symbol` to hygiene data.)
///
-/// Internally, a Symbol is implemented as an index, and all operations
+/// Examples:
+/// ```
+/// assert_eq!(Ident::from_str("x"), Ident::from_str("x"))
+/// assert_ne!(Ident::from_str("x").gensym(), Ident::from_str("x"))
+/// assert_ne!(Ident::from_str("x").gensym(), Ident::from_str("x").gensym())
+/// ```
+/// Internally, a symbol is implemented as an index, and all operations
/// (including hashing, equality, and ordering) operate on that index. The use
/// of `newtype_index!` means that `Option<Symbol>` only takes up 4 bytes,
/// because `newtype_index!` reserves the last 256 values for tagging purposes.
///
-/// Note that `Symbol` cannot directly be a `newtype_index!` because it implements
-/// `fmt::Debug`, `Encodable`, and `Decodable` in special ways.
+/// Note that `Symbol` cannot directly be a `newtype_index!` because it
+/// implements `fmt::Debug`, `Encodable`, and `Decodable` in special ways.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Symbol(SymbolIndex);
with_interner(|interner| interner.intern(string))
}
- /// Gensyms a new `usize`, using the current interner.
- pub fn gensym(string: &str) -> Self {
- with_interner(|interner| interner.gensym(string))
- }
-
- pub fn gensymed(self) -> Self {
- with_interner(|interner| interner.gensymed(self))
- }
-
- // WARNING: this function is deprecated and will be removed in the future.
- pub fn is_gensymed(self) -> bool {
- with_interner(|interner| interner.is_gensymed(self))
- }
-
pub fn as_str(self) -> LocalInternedString {
with_interner(|interner| unsafe {
LocalInternedString {
}
}
- fn gensym(&mut self, string: &str) -> Symbol {
- let symbol = self.intern(string);
- self.gensymed(symbol)
- }
-
fn gensymed(&mut self, symbol: Symbol) -> Symbol {
self.gensyms.push(symbol);
Symbol::new(SymbolIndex::MAX_AS_U32 - self.gensyms.len() as u32 + 1)
}
impl LocalInternedString {
+ /// Maps a string to its interned representation.
+ pub fn intern(string: &str) -> Self {
+ let string = with_interner(|interner| {
+ let symbol = interner.intern(string);
+ interner.strings[symbol.0.as_usize()]
+ });
+ LocalInternedString {
+ string: unsafe { std::mem::transmute::<&str, &str>(string) }
+ }
+ }
+
pub fn as_interned_str(self) -> InternedString {
InternedString {
symbol: Symbol::intern(self.string)
impl Decodable for LocalInternedString {
fn decode<D: Decoder>(d: &mut D) -> Result<LocalInternedString, D::Error> {
- Ok(Symbol::intern(&d.read_str()?).as_str())
+ Ok(LocalInternedString::intern(&d.read_str()?))
}
}
}
impl InternedString {
+ /// Maps a string to its interned representation.
+ pub fn intern(string: &str) -> Self {
+ InternedString {
+ symbol: Symbol::intern(string)
+ }
+ }
+
pub fn with<F: FnOnce(&str) -> R, R>(self, f: F) -> R {
let str = with_interner(|interner| {
interner.get(self.symbol) as *const str
impl Decodable for InternedString {
fn decode<D: Decoder>(d: &mut D) -> Result<InternedString, D::Error> {
- Ok(Symbol::intern(&d.read_str()?).as_interned_str())
+ Ok(InternedString::intern(&d.read_str()?))
}
}
mod tests {
use super::*;
use crate::Globals;
+ use crate::edition;
#[test]
fn interner_tests() {
assert_eq!(i.intern("cat"), Symbol::new(1));
// dog is still at zero
assert_eq!(i.intern("dog"), Symbol::new(0));
- assert_eq!(i.gensym("zebra"), Symbol::new(SymbolIndex::MAX_AS_U32));
+ let z = i.intern("zebra");
+ assert_eq!(i.gensymed(z), Symbol::new(SymbolIndex::MAX_AS_U32));
// gensym of same string gets new number:
- assert_eq!(i.gensym("zebra"), Symbol::new(SymbolIndex::MAX_AS_U32 - 1));
+ assert_eq!(i.gensymed(z), Symbol::new(SymbolIndex::MAX_AS_U32 - 1));
// gensym of *existing* string gets new number:
- assert_eq!(i.gensym("dog"), Symbol::new(SymbolIndex::MAX_AS_U32 - 2));
+ let d = i.intern("dog");
+ assert_eq!(i.gensymed(d), Symbol::new(SymbolIndex::MAX_AS_U32 - 2));
}
#[test]
fn without_first_quote_test() {
- GLOBALS.set(&Globals::new(), || {
+ GLOBALS.set(&Globals::new(edition::DEFAULT_EDITION), || {
let i = Ident::from_str("'break");
assert_eq!(i.without_first_quote().name, keywords::Break.name());
});
use term;
// FIXME(#54291): rustc and/or LLVM don't yet support building with panic-unwind
-// on aarch64-pc-windows-msvc, so we don't link libtest against
-// libunwind (for the time being), even though it means that
-// libtest won't be fully functional on this platform.
+// on aarch64-pc-windows-msvc, or thumbv7a-pc-windows-msvc
+// so we don't link libtest against libunwind (for the time being)
+// even though it means that libtest won't be fully functional on
+// these platforms.
//
// See also: https://github.com/rust-lang/rust/issues/54190#issuecomment-422904437
-#[cfg(not(all(windows, target_arch = "aarch64")))]
+#[cfg(not(all(windows, any(target_arch = "aarch64", target_arch = "arm"))))]
extern crate panic_unwind;
pub use self::ColorConfig::*;
cfg.flag("-std=c99");
cfg.flag("-std=c++11");
cfg.flag("-nostdinc++");
- if cfg.is_flag_supported("-funwind-tables").unwrap_or_default() &&
- cfg.is_flag_supported("-fno-exceptions").unwrap_or_default() {
- cfg.flag("-funwind-tables");
- cfg.flag("-fno-exceptions");
- }
+ cfg.flag("-fno-exceptions");
cfg.flag("-fno-rtti");
cfg.flag("-fstrict-aliasing");
+ cfg.flag("-funwind-tables");
}
let mut unwind_sources = vec![
-Subproject commit eb38a1888d1d29b2d2c6b31428a5201cd8fba0ff
+Subproject commit 2c5656ae593851d0b2336a727cc14b77a06b8ac0
// compile-flags: -O
#![crate_type="lib"]
-#![feature(maybe_uninit)]
use std::mem::MaybeUninit;
// ignore-netbsd
// ignore-openbsd
// ignore-solaris
+// ignore-sgx no dynamic linking
// aux-build:dummy.rs
// aux-build:wrapper.rs
// CHECK: {{.*}}DIDerivedType{{.*}}tag: DW_TAG_member,{{.*}}name: "Error",{{.*}}extraData: i64 0{{[,)].*}}
#![feature(never_type)]
-#![feature(nll)]
#[derive(Copy, Clone)]
pub struct Entity {
// ignore-netbsd
// ignore-openbsd
// ignore-solaris
+// ignore-sgx
// compile-flags: -C no-prepopulate-passes -C panic=abort -O
// Test what happens we save incremental compilation state that makes
// use of foreign items. This used to ICE (#34991).
+// ignore-sgx no libc
// revisions: rpass1
// Change parameter pattern ----------------------------------------------------
#[cfg(cfail1)]
pub fn change_parameter_pattern() {
- let _ = |x: &u32| x;
+ let _ = |x: (u32,)| x;
}
#[cfg(not(cfail1))]
#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, typeck_tables_of")]
#[rustc_clean(cfg="cfail3")]
pub fn change_parameter_pattern() {
- let _ = |&x: &u32| x;
+ let _ = |(x,): (u32,)| x;
}
--- /dev/null
+// revisions:rpass1 rpass2
+// compile-flags: --crate-type cdylib
+// skip-codegen
+
+#![deny(unused_attributes)]
+
+#[no_mangle]
+pub extern "C" fn rust_no_mangle() -> i32 {
+ 42
+}
--- /dev/null
+fn main() {
+ let x: u32 = [0, 1, 2, 3][2];
+}
+
+// END RUST SOURCE
+// START rustc.main.ConstProp.before.mir
+// bb0: {
+// ...
+// _2 = [const 0u32, const 1u32, const 2u32, const 3u32];
+// ...
+// _3 = const 2usize;
+// _4 = const 4usize;
+// _5 = Lt(_3, _4);
+// assert(move _5, "index out of bounds: the len is move _4 but the index is _3") -> bb1;
+// }
+// bb1: {
+// _1 = _2[_3];
+// ...
+// return;
+// }
+// END rustc.main.ConstProp.before.mir
+// START rustc.main.ConstProp.after.mir
+// bb0: {
+// ...
+// _5 = const true;
+// assert(const true, "index out of bounds: the len is move _4 but the index is _3") -> bb1;
+// }
+// bb1: {
+// _1 = _2[_3];
+// ...
+// return;
+// }
+// END rustc.main.ConstProp.after.mir
--- /dev/null
+// compile-flags: -C overflow-checks=on
+
+fn main() {
+ let x: u32 = 1 + 1;
+}
+
+// END RUST SOURCE
+// START rustc.main.ConstProp.before.mir
+// bb0: {
+// ...
+// _2 = CheckedAdd(const 1u32, const 1u32);
+// assert(!move (_2.1: bool), "attempt to add with overflow") -> bb1;
+// }
+// END rustc.main.ConstProp.before.mir
+// START rustc.main.ConstProp.after.mir
+// bb0: {
+// ...
+// _2 = (const 2u32, const false);
+// assert(!const false, "attempt to add with overflow") -> bb1;
+// }
+// END rustc.main.ConstProp.after.mir
--- /dev/null
+#[inline(never)]
+fn read(_: usize) { }
+
+fn main() {
+ const FOO: &i32 = &1;
+ let x = FOO as *const i32 as usize;
+ read(x);
+}
+
+// END RUST SOURCE
+// START rustc.main.ConstProp.before.mir
+// bb0: {
+// ...
+// _3 = _4;
+// _2 = move _3 as *const i32 (Misc);
+// ...
+// _1 = move _2 as usize (Misc);
+// ...
+// _6 = _1;
+// _5 = const read(move _6) -> bb1;
+// }
+// END rustc.main.ConstProp.before.mir
+// START rustc.main.ConstProp.after.mir
+// bb0: {
+// ...
+// _3 = _4;
+// _2 = move _3 as *const i32 (Misc);
+// ...
+// _1 = move _2 as usize (Misc);
+// ...
+// _6 = _1;
+// _5 = const read(move _6) -> bb1;
+// }
+// END rustc.main.ConstProp.after.mir
--- /dev/null
+fn test() -> &'static [u32] {
+ &[1, 2]
+}
+
+fn main() {
+ let x = test()[0];
+}
+
+// END RUST SOURCE
+// START rustc.main.ConstProp.before.mir
+// bb1: {
+// ...
+// _3 = const 0usize;
+// _4 = Len((*_2));
+// _5 = Lt(_3, _4);
+// assert(move _5, "index out of bounds: the len is move _4 but the index is _3") -> bb2;
+// }
+// bb2: {
+// _1 = (*_2)[_3];
+// ...
+// return;
+// }
+// END rustc.main.ConstProp.before.mir
+// START rustc.main.ConstProp.after.mir
+// bb0: {
+// ...
+// _3 = const 0usize;
+// _4 = Len((*_2));
+// _5 = Lt(_3, _4);
+// assert(move _5, "index out of bounds: the len is move _4 but the index is _3") -> bb2;
+// }
+// bb2: {
+// _1 = (*_2)[_3];
+// ...
+// return;
+// }
+// END rustc.main.ConstProp.after.mir
--- /dev/null
+#[inline(never)]
+fn foo(_: i32) { }
+
+fn main() {
+ match 1 {
+ 1 => foo(0),
+ _ => foo(-1),
+ }
+}
+
+// END RUST SOURCE
+// START rustc.main.ConstProp.before.mir
+// bb0: {
+// ...
+// _1 = const 1i32;
+// switchInt(_1) -> [1i32: bb1, otherwise: bb2];
+// }
+// END rustc.main.ConstProp.before.mir
+// START rustc.main.ConstProp.after.mir
+// bb0: {
+// ...
+// switchInt(const 1i32) -> [1i32: bb1, otherwise: bb2];
+// }
+// END rustc.main.ConstProp.after.mir
+// START rustc.main.SimplifyBranches-after-const-prop.before.mir
+// bb0: {
+// ...
+// _1 = const 1i32;
+// switchInt(const 1i32) -> [1i32: bb1, otherwise: bb2];
+// }
+// END rustc.main.SimplifyBranches-after-const-prop.before.mir
+// START rustc.main.SimplifyBranches-after-const-prop.after.mir
+// bb0: {
+// ...
+// _1 = const 1i32;
+// goto -> bb1;
+// }
+// END rustc.main.SimplifyBranches-after-const-prop.after.mir
// ignore-wasm32-bare
-#![feature(nll)]
-
fn match_guard(x: Option<&&i32>, c: bool) -> i32 {
match x {
Some(0) if c => 0,
}
// END RUST SOURCE
-// START rustc.main.SimplifyBranches-after-copy-prop.before.mir
+// START rustc.main.SimplifyBranches-after-const-prop.before.mir
// bb0: {
// ...
// switchInt(const false) -> [false: bb3, otherwise: bb1];
// }
-// END rustc.main.SimplifyBranches-after-copy-prop.before.mir
-// START rustc.main.SimplifyBranches-after-copy-prop.after.mir
+// END rustc.main.SimplifyBranches-after-const-prop.before.mir
+// START rustc.main.SimplifyBranches-after-const-prop.after.mir
// bb0: {
// ...
// goto -> bb3;
// }
-// END rustc.main.SimplifyBranches-after-copy-prop.after.mir
+// END rustc.main.SimplifyBranches-after-const-prop.after.mir
// error-pattern: thread 'main' panicked at 'explicit panic'
-#![feature(nll)]
-
fn main() {
let mut vec = vec![];
vec.push((vec.len(), panic!()));
}
fn main() {
- syntax::with_globals(|| run());
+ syntax::with_default_globals(|| run());
}
fn run() {
allow_internal_unsafe: false,
local_inner_macros: false,
unstable_feature: None,
- edition: hygiene::default_edition(),
+ edition: reg.sess.edition(),
});
}
mod gravy;
pub fn main() {
- syntax::with_globals(|| parse());
+ syntax::with_default_globals(|| parse());
assert_eq!(gravy::foo(), 10);
}
}
fn main() {
- syntax::with_globals(|| run());
+ syntax::with_default_globals(|| run());
}
fn run() {
// no-prefer-dynamic
// ignore-cloudabi
// ignore-emscripten
+// ignore-sgx no processes
// ignore-macos this needs valgrind 3.11 or higher; see
// https://github.com/rust-lang/rust/pull/30365#issuecomment-165763679
// ignore-cloudabi no env and process
// ignore-emscripten no processes
+// ignore-sgx no processes
use std::{env, panic};
use std::io::prelude::*;
+++ /dev/null
-#![feature(arbitrary_self_types, unsize, coerce_unsized, dispatch_from_dyn)]
-#![feature(rustc_attrs)]
-
-use std::{
- ops::{Deref, CoerceUnsized, DispatchFromDyn},
- marker::Unsize,
-};
-
-struct Ptr<T: ?Sized>(Box<T>);
-
-impl<T: ?Sized> Deref for Ptr<T> {
- type Target = T;
-
- fn deref(&self) -> &T {
- &*self.0
- }
-}
-
-impl<T: Unsize<U> + ?Sized, U: ?Sized> CoerceUnsized<Ptr<U>> for Ptr<T> {}
-impl<T: Unsize<U> + ?Sized, U: ?Sized> DispatchFromDyn<Ptr<U>> for Ptr<T> {}
-
-struct Wrapper<T: ?Sized>(T);
-
-impl<T: ?Sized> Deref for Wrapper<T> {
- type Target = T;
-
- fn deref(&self) -> &T {
- &self.0
- }
-}
-
-impl<T: CoerceUnsized<U>, U> CoerceUnsized<Wrapper<U>> for Wrapper<T> {}
-impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<Wrapper<U>> for Wrapper<T> {}
-
-
-trait Trait {
- // This method isn't object-safe yet. Unsized by-value `self` is object-safe (but not callable
- // without unsized_locals), but wrappers arond `Self` currently are not.
- // FIXME (mikeyhew) uncomment this when unsized rvalues object-safety is implemented
- // fn wrapper(self: Wrapper<Self>) -> i32;
- fn ptr_wrapper(self: Ptr<Wrapper<Self>>) -> i32;
- fn wrapper_ptr(self: Wrapper<Ptr<Self>>) -> i32;
- fn wrapper_ptr_wrapper(self: Wrapper<Ptr<Wrapper<Self>>>) -> i32;
-}
-
-impl Trait for i32 {
- fn ptr_wrapper(self: Ptr<Wrapper<Self>>) -> i32 {
- **self
- }
- fn wrapper_ptr(self: Wrapper<Ptr<Self>>) -> i32 {
- **self
- }
- fn wrapper_ptr_wrapper(self: Wrapper<Ptr<Wrapper<Self>>>) -> i32 {
- ***self
- }
-}
-
-fn main() {
- let pw = Ptr(Box::new(Wrapper(5))) as Ptr<Wrapper<dyn Trait>>;
- assert_eq!(pw.ptr_wrapper(), 5);
-
- let wp = Wrapper(Ptr(Box::new(6))) as Wrapper<Ptr<dyn Trait>>;
- assert_eq!(wp.wrapper_ptr(), 6);
-
- let wpw = Wrapper(Ptr(Box::new(Wrapper(7)))) as Wrapper<Ptr<Wrapper<dyn Trait>>>;
- assert_eq!(wpw.wrapper_ptr_wrapper(), 7);
-}
+++ /dev/null
-#![feature(arbitrary_self_types)]
-#![feature(rustc_attrs)]
-
-use std::{
- rc::Rc,
- sync::Arc,
- pin::Pin,
-};
-
-trait Trait {
- fn by_rc(self: Rc<Self>) -> i64;
- fn by_arc(self: Arc<Self>) -> i64;
- fn by_pin_mut(self: Pin<&mut Self>) -> i64;
- fn by_pin_box(self: Pin<Box<Self>>) -> i64;
- fn by_pin_pin_pin_ref(self: Pin<Pin<Pin<&Self>>>) -> i64;
-}
-
-impl Trait for i64 {
- fn by_rc(self: Rc<Self>) -> i64 {
- *self
- }
- fn by_arc(self: Arc<Self>) -> i64 {
- *self
- }
- fn by_pin_mut(self: Pin<&mut Self>) -> i64 {
- *self
- }
- fn by_pin_box(self: Pin<Box<Self>>) -> i64 {
- *self
- }
- fn by_pin_pin_pin_ref(self: Pin<Pin<Pin<&Self>>>) -> i64 {
- *self
- }
-}
-
-fn main() {
- let rc = Rc::new(1i64) as Rc<dyn Trait>;
- assert_eq!(1, rc.by_rc());
-
- let arc = Arc::new(2i64) as Arc<dyn Trait>;
- assert_eq!(2, arc.by_arc());
-
- let mut value = 3i64;
- let pin_mut = Pin::new(&mut value) as Pin<&mut dyn Trait>;
- assert_eq!(3, pin_mut.by_pin_mut());
-
- let pin_box = Into::<Pin<Box<i64>>>::into(Box::new(4i64)) as Pin<Box<dyn Trait>>;
- assert_eq!(4, pin_box.by_pin_box());
-
- let value = 5i64;
- let pin_pin_pin_ref = Pin::new(Pin::new(Pin::new(&value))) as Pin<Pin<Pin<&dyn Trait>>>;
- assert_eq!(5, pin_pin_pin_ref.by_pin_pin_pin_ref());
-}
#![allow(deprecated)]
// ignore-cloudabi no process support
// ignore-emscripten no threads support
+// ignore-sgx no processes
use std::{env, fmt, process, sync, thread};
// ignore-cloudabi spawning processes is not supported
// ignore-emscripten spawning processes is not supported
// normalize-stderr-test ".*\n" -> ""
+// ignore-sgx no processes
// Note that above `-opt-bisect-limit=0` is used to basically disable
// optimizations. It creates tons of output on stderr, hence we normalize
// ignore-cloudabi spawning processes is not supported
// ignore-emscripten spawning processes is not supported
// ignore-openbsd no support for libbacktrace without filename
+// ignore-sgx no processes
// compile-flags:-g
use std::env;
#![allow(unused_variables)]
// Test case from #39963.
-#![feature(nll)]
-
#[derive(Clone)]
struct Foo(Option<Box<Foo>>, Option<Box<Foo>>);
// run-pass
-#![feature(nll)]
#![deny(unused_mut)]
#[derive(Debug)]
// run-pass
-// revisions: lxl nll
-
-#![cfg_attr(nll, feature(nll))]
-
use std::ops::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign};
use std::ops::{BitAndAssign, BitOrAssign, BitXorAssign, ShlAssign, ShrAssign};
// ignore-wasm32-bare no libc to test with
+// ignore-sgx no libc
#![feature(rustc_private)]
// pretty-expanded FIXME #23616
// ignore-cloudabi no target_family
// ignore-wasm32-bare no target_family
+// ignore-sgx
#[cfg(windows)]
pub fn main() {
// run-pass
// ignore-cloudabi no target_family
// ignore-wasm32-bare no target_family
+// ignore-sgx
// pretty-expanded FIXME #23616
// ignore-pretty issue #37199
// ignore-cloudabi no processes
// ignore-emscripten no processes
+// ignore-sgx no processes
#![feature(process_exec)]
// ignore-windows - this is a unix-specific test
// ignore-cloudabi no processes
// ignore-emscripten no processes
+// ignore-sgx no processes
#![feature(process_exec, rustc_private)]
extern crate libc;
// compile-flags:--test
// ignore-cloudabi no processes
// ignore-emscripten no processes
+// ignore-sgx no processes
// N.B., these tests kill child processes. Valgrind sees these children as leaking
// memory, which makes for some *confusing* logs. That's why these are here
// ignore-cloudabi no processes
// ignore-emscripten no processes
+// ignore-sgx no processes
use std::alloc::{Layout, handle_alloc_error};
use std::env;
// ignore-cloudabi no processes
// ignore-emscripten no processes
+// ignore-sgx no processes
use std::env::args;
use std::process::Command;
// ignore-windows
// ignore-cloudabi no execve
// ignore-emscripten no execve
+// ignore-sgx no execve
// no-prefer-dynamic
#![feature(rustc_private)]
#![allow(deprecated)]
// ignore-cloudabi no environment variables present
// ignore-emscripten env vars don't work?
+// ignore-sgx env vars cannot be modified
use std::env::*;
use std::path::PathBuf;
// exec-env:TEST_EXEC_ENV=22
// ignore-cloudabi no env vars
// ignore-emscripten FIXME: issue #31622
+// ignore-sgx unsupported
use std::env;
// ignore-cloudabi no processes
// ignore-emscripten no processes
// ignore-haiku
+// ignore-sgx no processes
#![feature(rustc_private)]
// run-pass
// ignore-wasm32-bare no libc to test ffi with
+// ignore-sgx no libc
#![feature(rustc_private)]
// ignore-emscripten
// ignore-wasm32
+// ignore-sgx no processes
use std::env;
use std::process::Command;
}
}
+#[cfg(target_env = "sgx")]
+mod m {
+ #[main]
+ #[cfg(target_arch = "x86_64")]
+ pub fn main() {
+ unsafe {
+ assert_eq!(::rusti::pref_align_of::<u64>(), 8);
+ assert_eq!(::rusti::min_align_of::<u64>(), 8);
+ }
+ }
+}
+
#[cfg(target_os = "windows")]
mod m {
#[main]
#![allow(unused_mut)]
// ignore-wasm32
// ignore-emscripten
+// ignore-sgx no processes
// compile-flags: -C debug_assertions=yes
// edition:2018
// run-pass
// ignore-emscripten no threads support
+// ignore-sgx no thread sleep support
use std::thread;
use std::time::Duration;
// run-pass
// ignore-cloudabi no processes
// ignore-emscripten no processes
+// ignore-sgx no processes
// Make sure that if a process doesn't have its stdio/stderr descriptors set up
// that we don't die in a large ball of fire
// ignore-cloudabi no dylib support
// ignore-emscripten no dylib support
// ignore-musl
+// ignore-sgx no dylib support
// pretty-expanded FIXME #23616
// run-pass
// ignore-wasm32-bare can't block the thread
+// ignore-sgx not supported
#![allow(deprecated)]
use std::thread;
#![allow(unused_mut)]
// ignore-cloudabi no processes
// ignore-emscripten no processes
+// ignore-sgx no processes
use std::env;
use std::io::prelude::*;
+++ /dev/null
-// run-pass
-#![allow(unused_must_use)]
-// ignore-emscripten no threads support
-
-// This test may not always fail, but it can be flaky if the race it used to
-// expose is still present.
-
-#![feature(mpsc_select)]
-#![allow(deprecated)]
-
-use std::sync::mpsc::{channel, Sender, Receiver};
-use std::thread;
-
-fn helper(rx: Receiver<Sender<()>>) {
- for tx in rx.iter() {
- let _ = tx.send(());
- }
-}
-
-fn main() {
- let (tx, rx) = channel();
- let t = thread::spawn(move|| { helper(rx) });
- let (snd, rcv) = channel::<isize>();
- for _ in 1..100000 {
- snd.send(1).unwrap();
- let (tx2, rx2) = channel();
- tx.send(tx2).unwrap();
- select! {
- _ = rx2.recv() => (),
- _ = rcv.recv() => ()
- }
- }
- drop(tx);
- t.join();
-}
#![allow(unused_mut)]
// ignore-cloudabi no processes
// ignore-emscripten no processes
+// ignore-sgx no processes
use std::env;
use std::io::prelude::*;
// run-pass
// ignore-cloudabi no processes
// ignore-emscripten no processes
+// ignore-sgx no processes
use std::env;
use std::process::Command;
// run-pass
// ignore-cloudabi no processes
// ignore-emscripten no processes
+// ignore-sgx no processes
use std::process::Command;
use std::env;
// run-pass
// ignore-wasm32-bare no libc to test ffi with
-
+// ignore-sgx no libc
#![feature(rustc_private)]
extern crate libc;
// run-pass
// ignore-cloudabi no processes
// ignore-emscripten no threads
+// ignore-sgx no processes
use std::thread;
use std::env;
// See further discussion on rust-lang/rust#24535,
// rust-lang/rfcs#1006, and rust-lang/rfcs#107
-#![feature(nll)]
#![feature(bind_by_move_pattern_guards)]
fn main() {
// run-pass
// ignore-cloudabi no processes
// ignore-emscripten no processes
+// ignore-sgx no processes
// Previously libstd would set stdio descriptors of a child process
// by `dup`ing the requested descriptors to inherit directly into the
// run-pass
// ignore-cloudabi no processes
// ignore-emscripten no processes
+// ignore-sgx no processes
use std::process::{Command, Stdio};
use std::env;
// run-pass
#![allow(unused_must_use)]
// Test that we are able to reinitialize box with moved referent
-#![feature(nll)]
static mut ORDER: [usize; 3] = [0, 0, 0];
static mut INDEX: usize = 0;
// run-pass
#![allow(unreachable_code)]
-#![feature(nll)]
fn main() {
let mut v = Vec::new();
#![allow(unused_must_use)]
#![allow(deprecated)]
// ignore-emscripten no threads support
+// ignore-sgx no thread sleep support
use std::sync::mpsc::{TryRecvError, channel};
use std::thread;
// ignore-windows
// ignore-macos
// ignore-emscripten doesn't support this linkage
+// ignore-sgx weak linkage not permitted
// aux-build:linkage1.rs
#![feature(linkage)]
println!("hello {}", "world",);
}
-// select! is too troublesome and unlikely to be stabilized
-
// stringify! is N/A
#[cfg(std)]
// compile-flags:--test
// ignore-emscripten
+// ignore-sgx no thread sleep support
use std::sync::mpsc::channel;
use std::sync::mpsc::TryRecvError;
// ignore-cloudabi no processes
// ignore-emscripten no processes
+// ignore-sgx no processes
fn check_for_no_backtrace(test: std::process::Output) {
assert!(!test.status.success());
// Regression test for #47153: constants in a generic context (such as
// a trait) used to ICE.
-#![feature(nll)]
#![allow(warnings)]
trait Foo {
// run-pass
-#![feature(nll)]
-
pub struct DescriptorSet<'a> {
pub slots: Vec<AttachInfo<'a, Resources>>
}
#![allow(path_statements)]
#![allow(dead_code)]
-#![feature(nll)]
-
struct WithDrop;
impl Drop for WithDrop {
#![allow(path_statements)]
#![allow(dead_code)]
-#![feature(nll)]
#![feature(generators, generator_trait)]
struct WithDrop;
// run-pass
-#![feature(nll)]
#![deny(unused_mut)]
fn main() {
// run-pass
-#![feature(nll)]
#![deny(unused_mut)]
struct Foo {
// run-pass
-#![feature(nll)]
#![allow(unused_variables)]
pub trait TryTransform {
// run-pass
-#![feature(nll)]
-
struct List<T> {
value: T,
next: Option<Box<List<T>>>,
// run-pass
-#![feature(nll)]
-
use std::collections::HashMap;
fn process_or_insert_default(map: &mut HashMap<usize, String>, key: usize) {
// `x`. The lexical checker makes this very painful. The NLL checker
// does not.
-#![feature(nll)]
-
use std::rc::Rc;
#[derive(Debug, PartialEq, Eq)]
// ignore-android
// ignore-cloudabi no processes
// ignore-emscripten no processes
+// ignore-sgx no processes
#![feature(rustc_private)]
// ignore-musl
// ignore-cloudabi no processes
// ignore-emscripten no processes
+// ignore-sgx no processes
#![feature(asm)]
#![feature(rustc_private)]
// no-prefer-dynamic
// ignore-cloudabi no processes
// ignore-emscripten no processes
+// ignore-sgx no processes
// ignore-macos
extern crate exit_success_if_unwind;
// no-prefer-dynamic
// ignore-cloudabi no processes
// ignore-emscripten no processes
+// ignore-sgx no processes
// ignore-macos
use std::process::Command;
// no-prefer-dynamic
// ignore-cloudabi no processes
// ignore-emscripten no processes
+// ignore-sgx no processes
use std::process::Command;
use std::env;
// no-prefer-dynamic
// ignore-cloudabi no processes
// ignore-emscripten no processes
+// ignore-sgx no processes
use std::process::Command;
use std::env;
// This test checks that instantiating an uninhabited type via `mem::{uninitialized,zeroed}` results
// in a runtime panic.
-#![feature(never_type, maybe_uninit)]
+#![feature(never_type)]
use std::{mem, panic};
// ignore-cloudabi no files or I/O
// ignore-wasm32-bare no files or I/O
// ignore-emscripten no files
+// ignore-sgx no files
use std::fs;
use std::io;
// ignore-cloudabi spawning processes is not supported
// ignore-emscripten spawning processes is not supported
+// ignore-sgx no processes
use std::{env, process};
// run-pass
// ignore-cloudabi no processes
// ignore-emscripten no processes
+// ignore-sgx no processes
use std::process::Command;
use std::env;
#![allow(unused_imports)]
// ignore-cloudabi no processes
// ignore-emscripten no processes
+// ignore-sgx no processes
use std::env;
use std::process::{self, Command, Stdio};
// run-pass
// ignore-cloudabi no processes
// ignore-emscripten no processes
+// ignore-sgx no processes
use std::process::Command;
use std::env;
// run-pass
// ignore-cloudabi no processes
// ignore-emscripten no processes
+// ignore-sgx no processes
use std::io::ErrorKind;
use std::process::Command;
// ignore-cloudabi no processes
// ignore-emscripten no processes
+// ignore-sgx no processes
use std::io::prelude::*;
use std::io;
// run-pass
// ignore-cloudabi no processes
// ignore-emscripten no processes
+// ignore-sgx no processes
use std::env;
use std::io;
#![allow(dead_code)]
// ignore-cloudabi stdout does not map to file descriptor 1 by default
// ignore-wasm32-bare no libc
+// ignore-sgx no libc
#![feature(rustc_private)]
// ignore-cloudabi spawning processes is not supported
// ignore-emscripten spawning processes is not supported
+// ignore-sgx no processes
#![feature(start)]
#![allow(unused_imports)]
// ignore-cloudabi can't run commands
// ignore-emscripten can't run commands
+// ignore-sgx no processes
#![feature(rustc_private)]
+++ /dev/null
-// run-pass
-#![feature(arbitrary_self_types)]
-
-use std::rc::Rc;
-
-struct Foo(String);
-
-impl Foo {
- unsafe fn foo(self: *const Self) -> *const str {
- (*self).0.as_ref()
- }
-
- fn complicated_1(self: *const Rc<Self>) -> &'static str {
- "Foo::complicated_1"
- }
-
- unsafe fn complicated_2(self: Rc<*const Self>) -> *const str {
- (**self).0.as_ref()
- }
-}
-
-fn main() {
- let foo = Foo("abc123".into());
- assert_eq!("abc123", unsafe { &*(&foo as *const Foo).foo() });
- assert_eq!("Foo::complicated_1", std::ptr::null::<Rc<Foo>>().complicated_1());
- let rc = Rc::new(&foo as *const Foo);
- assert_eq!("abc123", unsafe { &*rc.complicated_2()});
-}
+++ /dev/null
-// run-pass
-#![feature(arbitrary_self_types)]
-
-use std::ptr;
-
-trait Foo {
- fn foo(self: *const Self) -> &'static str;
-
- unsafe fn bar(self: *const Self) -> i64;
-
- unsafe fn complicated(self: *const *const Self) -> i64 where Self: Sized {
- (*self).bar()
- }
-}
-
-impl Foo for i32 {
- fn foo(self: *const Self) -> &'static str {
- "I'm an i32!"
- }
-
- unsafe fn bar(self: *const Self) -> i64 {
- *self as i64
- }
-}
-
-impl Foo for u32 {
- fn foo(self: *const Self) -> &'static str {
- "I'm a u32!"
- }
-
- unsafe fn bar(self: *const Self) -> i64 {
- *self as i64
- }
-}
-
-fn main() {
- let null_i32 = ptr::null::<i32>() as *const Foo;
- let null_u32 = ptr::null::<u32>() as *const Foo;
-
- assert_eq!("I'm an i32!", null_i32.foo());
- assert_eq!("I'm a u32!", null_u32.foo());
-
- let valid_i32 = 5i32;
- let valid_i32_thin = &valid_i32 as *const i32;
- assert_eq!("I'm an i32!", valid_i32_thin.foo());
- assert_eq!(5, unsafe { valid_i32_thin.bar() });
- assert_eq!(5, unsafe { (&valid_i32_thin as *const *const i32).complicated() });
- let valid_i32_fat = valid_i32_thin as *const Foo;
- assert_eq!("I'm an i32!", valid_i32_fat.foo());
- assert_eq!(5, unsafe { valid_i32_fat.bar() });
-
- let valid_u32 = 18u32;
- let valid_u32_thin = &valid_u32 as *const u32;
- assert_eq!("I'm a u32!", valid_u32_thin.foo());
- assert_eq!(18, unsafe { valid_u32_thin.bar() });
- assert_eq!(18, unsafe { (&valid_u32_thin as *const *const u32).complicated() });
- let valid_u32_fat = valid_u32_thin as *const Foo;
- assert_eq!("I'm a u32!", valid_u32_fat.foo());
- assert_eq!(18, unsafe { valid_u32_fat.bar() });
-
-}
+++ /dev/null
-// run-pass
-#![feature(arbitrary_self_types)]
-
-struct Foo;
-struct Bar;
-
-impl std::ops::Deref for Bar {
- type Target = Foo;
-
- fn deref(&self) -> &Foo {
- &Foo
- }
-}
-
-impl Foo {
- fn bar(self: Bar) -> i32 { 3 }
-}
-
-fn main() {
- assert_eq!(3, Bar.bar());
-}
+++ /dev/null
-// run-pass
-#![feature(arbitrary_self_types)]
-
-use std::rc::Rc;
-
-struct Foo {
- x: i32,
- y: i32,
-}
-
-impl Foo {
- fn x(self: &Rc<Self>) -> i32 {
- self.x
- }
-
- fn y(self: Rc<Self>) -> i32 {
- self.y
- }
-}
-
-fn main() {
- let foo = Rc::new(Foo {x: 3, y: 4});
- assert_eq!(3, foo.x());
- assert_eq!(4, foo.y());
-}
+++ /dev/null
-// run-pass
-#![feature(arbitrary_self_types)]
-
-use std::rc::Rc;
-
-trait Trait {
- fn trait_method<'a>(self: &'a Box<Rc<Self>>) -> &'a [i32];
-}
-
-impl Trait for Vec<i32> {
- fn trait_method<'a>(self: &'a Box<Rc<Self>>) -> &'a [i32] {
- &***self
- }
-}
-
-fn main() {
- let v = vec![1,2,3];
-
- assert_eq!(&[1,2,3], Box::new(Rc::new(v)).trait_method());
-}
+++ /dev/null
-// run-pass
-#![feature(arbitrary_self_types)]
-
-use std::rc::Rc;
-
-struct Foo<T: ?Sized>(T);
-
-impl Foo<[u8]> {
- fn len(self: Rc<Self>) -> usize {
- self.0.len()
- }
-}
-
-fn main() {
- let rc = Rc::new(Foo([1u8,2,3])) as Rc<Foo<[u8]>>;
- assert_eq!(3, rc.len());
-}
+++ /dev/null
-pub trait Foo {
- #[inline(always)]
- fn f(&self);
-}
-
-pub struct Bar {
- pub x: String
-}
-
-impl Foo for Bar {
- #[inline(always)]
- fn f(&self) {
- println!("{}", (*self).x);
- }
-}
+++ /dev/null
-// run-pass
-// Tests the ability for the Self type in default methods to use
-// capabilities granted by builtin kinds as supertraits.
-
-
-use std::sync::mpsc::{Sender, channel};
-
-trait Foo : Send + Sized + 'static {
- fn foo(self, tx: Sender<Self>) {
- tx.send(self).unwrap();
- }
-}
-
-impl <T: Send + 'static> Foo for T { }
-
-pub fn main() {
- let (tx, rx) = channel();
- 1193182.foo(tx);
- assert_eq!(rx.recv().unwrap(), 1193182);
-}
+++ /dev/null
-// run-pass
-
-struct X {
- a: isize
-}
-
-trait Changer {
- fn change(self) -> Self;
-}
-
-impl Changer for X {
- fn change(mut self) -> X {
- self.a = 55;
- self
- }
-}
-
-pub fn main() {
- let x = X { a: 32 };
- let new_x = x.change();
- assert_eq!(new_x.a, 55);
-}
+++ /dev/null
-// run-pass
-#![allow(dead_code)]
-// Test to make sure that explicit self params work inside closures
-
-// pretty-expanded FIXME #23616
-
-struct Box {
- x: usize
-}
-
-impl Box {
- pub fn set_many(&mut self, xs: &[usize]) {
- for x in xs { self.x = *x; }
- }
-}
-
-pub fn main() {}
+++ /dev/null
-// run-pass
-#![allow(dead_code)]
-#![feature(box_syntax)]
-
-#[derive(Copy, Clone)]
-struct LM { resize_at: usize, size: usize }
-
-enum HashMap<K,V> {
- HashMap_(LM, Vec<(K,V)>)
-}
-
-fn linear_map<K,V>() -> HashMap<K,V> {
- HashMap::HashMap_(LM{
- resize_at: 32,
- size: 0}, Vec::new())
-}
-
-impl<K,V> HashMap<K,V> {
- pub fn len(&mut self) -> usize {
- match *self {
- HashMap::HashMap_(ref l, _) => l.size
- }
- }
-}
-
-pub fn main() {
- let mut m: Box<_> = box linear_map::<(),()>();
- assert_eq!(m.len(), 0);
-}
+++ /dev/null
-// run-pass
-#![feature(box_syntax)]
-
-trait Foo {
- fn f(self: Box<Self>);
-}
-
-struct S {
- x: isize
-}
-
-impl Foo for S {
- fn f(self: Box<S>) {
- assert_eq!(self.x, 3);
- }
-}
-
-pub fn main() {
- let x = box S { x: 3 };
- let y = x as Box<Foo>;
- y.f();
-}
+++ /dev/null
-// run-pass
-#![allow(dead_code)]
-#![allow(non_camel_case_types)]
-#![allow(non_upper_case_globals)]
-
-#![feature(box_syntax)]
-
-static tau: f64 = 2.0*3.14159265358979323;
-
-struct Point {x: f64, y: f64}
-struct Size {w: f64, h: f64}
-enum shape {
- circle(Point, f64),
- rectangle(Point, Size)
-}
-
-
-fn compute_area(shape: &shape) -> f64 {
- match *shape {
- shape::circle(_, radius) => 0.5 * tau * radius * radius,
- shape::rectangle(_, ref size) => size.w * size.h
- }
-}
-
-impl shape {
- // self is in the implicit self region
- pub fn select<'r, T>(&self, threshold: f64, a: &'r T, b: &'r T)
- -> &'r T {
- if compute_area(self) > threshold {a} else {b}
- }
-}
-
-fn select_based_on_unit_circle<'r, T>(
- threshold: f64, a: &'r T, b: &'r T) -> &'r T {
-
- let shape = &shape::circle(Point{x: 0.0, y: 0.0}, 1.0);
- shape.select(threshold, a, b)
-}
-
-#[derive(Clone)]
-struct thing {
- x: A
-}
-
-#[derive(Clone)]
-struct A {
- a: isize
-}
-
-fn thing(x: A) -> thing {
- thing {
- x: x
- }
-}
-
-impl thing {
- pub fn bar(self: Box<thing>) -> isize { self.x.a }
- pub fn quux(&self) -> isize { self.x.a }
- pub fn baz<'a>(&'a self) -> &'a A { &self.x }
- pub fn spam(self) -> isize { self.x.a }
-}
-
-trait Nus { fn f(&self); }
-impl Nus for thing { fn f(&self) {} }
-
-pub fn main() {
- let y: Box<_> = box thing(A {a: 10});
- assert_eq!(y.clone().bar(), 10);
- assert_eq!(y.quux(), 10);
-
- let z = thing(A {a: 11});
- assert_eq!(z.spam(), 11);
-}
+++ /dev/null
-// run-pass
-// aux-build:explicit_self_xcrate.rs
-
-// pretty-expanded FIXME #23616
-
-extern crate explicit_self_xcrate;
-use explicit_self_xcrate::{Foo, Bar};
-
-pub fn main() {
- let x = Bar { x: "hello".to_string() };
- x.f();
-}
+++ /dev/null
-// run-pass
-struct S {
- x: String
-}
-
-impl S {
- pub fn foo(self) {
- self.bar();
- }
-
- pub fn bar(self) {
- println!("{}", self.x);
- }
-}
-
-pub fn main() {
- let x = S { x: "Hello!".to_string() };
- x.foo();
-}
+++ /dev/null
-// run-pass
-#![allow(unused_mut)]
-// Check that a trait is still object-safe (and usable) if it has
-// methods with by-value self so long as they require `Self : Sized`.
-
-
-trait Counter {
- fn tick(&mut self) -> u32;
- fn get(self) -> u32 where Self : Sized;
-}
-
-struct CCounter {
- c: u32
-}
-
-impl Counter for CCounter {
- fn tick(&mut self) -> u32 { self.c += 1; self.c }
- fn get(self) -> u32 where Self : Sized { self.c }
-}
-
-fn tick1<C:Counter>(mut c: C) -> u32 {
- tick2(&mut c);
- c.get()
-}
-
-fn tick2(c: &mut Counter) {
- tick3(c);
-}
-
-fn tick3<C:?Sized+Counter>(c: &mut C) {
- c.tick();
- c.tick();
-}
-
-fn main() {
- let mut c = CCounter { c: 0 };
- let value = tick1(c);
- assert_eq!(value, 2);
-}
+++ /dev/null
-// run-pass
-#![allow(unused_variables)]
-// Check that a trait is still object-safe (and usable) if it has
-// generic methods so long as they require `Self : Sized`.
-
-
-trait Counter {
- fn tick(&mut self) -> u32;
- fn with<F:FnOnce(u32)>(&self, f: F) where Self : Sized;
-}
-
-struct CCounter {
- c: u32
-}
-
-impl Counter for CCounter {
- fn tick(&mut self) -> u32 { self.c += 1; self.c }
- fn with<F:FnOnce(u32)>(&self, f: F) { f(self.c); }
-}
-
-fn tick1<C:Counter>(c: &mut C) {
- tick2(c);
- c.with(|i| ());
-}
-
-fn tick2(c: &mut Counter) {
- tick3(c);
-}
-
-fn tick3<C:?Sized+Counter>(c: &mut C) {
- c.tick();
- c.tick();
-}
-
-fn main() {
- let mut c = CCounter { c: 0 };
- tick1(&mut c);
- assert_eq!(c.tick(), 3);
-}
+++ /dev/null
-// run-pass
-// Check that a trait is still object-safe (and usable) if it has
-// methods that return `Self` so long as they require `Self : Sized`.
-
-
-trait Counter {
- fn new() -> Self where Self : Sized;
- fn tick(&mut self) -> u32;
-}
-
-struct CCounter {
- c: u32
-}
-
-impl Counter for CCounter {
- fn new() -> CCounter { CCounter { c: 0 } }
- fn tick(&mut self) -> u32 { self.c += 1; self.c }
-}
-
-fn preticked<C:Counter>() -> C {
- let mut c: C = Counter::new();
- tick(&mut c);
- c
-}
-
-fn tick(c: &mut Counter) {
- tick_generic(c);
-}
-
-fn tick_generic<C:?Sized+Counter>(c: &mut C) {
- c.tick();
- c.tick();
-}
-
-fn main() {
- let mut c = preticked::<CCounter>();
- tick(&mut c);
- assert_eq!(c.tick(), 5);
-}
+++ /dev/null
-// run-pass
-#![allow(dead_code)]
-#![allow(unused_variables)]
-// Test that we can use `Self` types in impls in the expected way.
-
-// pretty-expanded FIXME #23616
-
-#![feature(box_syntax)]
-
-struct Foo;
-
-// Test uses on inherent impl.
-impl Foo {
- fn foo(_x: Self, _y: &Self, _z: Box<Self>) -> Self {
- Foo
- }
-
- fn baz() {
- // Test that Self cannot be shadowed.
- type Foo = i32;
- // There is no empty method on i32.
- Self::empty();
-
- let _: Self = Foo;
- }
-
- fn empty() {}
-}
-
-// Test uses when implementing a trait and with a type parameter.
-pub struct Baz<X> {
- pub f: X,
-}
-
-trait SuperBar {
- type SuperQux;
-}
-
-trait Bar<X>: SuperBar {
- type Qux;
-
- fn bar(x: Self, y: &Self, z: Box<Self>, _: Self::SuperQux) -> Self;
- fn dummy(&self, x: X) { }
-}
-
-impl SuperBar for Box<Baz<isize>> {
- type SuperQux = bool;
-}
-
-impl Bar<isize> for Box<Baz<isize>> {
- type Qux = i32;
-
- fn bar(_x: Self, _y: &Self, _z: Box<Self>, _: Self::SuperQux) -> Self {
- let _: Self::Qux = 42;
- let _: <Self as Bar<isize>>::Qux = 42;
-
- let _: Self::SuperQux = true;
- let _: <Self as SuperBar>::SuperQux = true;
-
- box Baz { f: 42 }
- }
-}
-
-fn main() {
- let _: Foo = Foo::foo(Foo, &Foo, box Foo);
- let _: Box<Baz<isize>> = Bar::bar(box Baz { f: 42 },
- &box Baz { f: 42 },
- box box Baz { f: 42 },
- true);
-}
+++ /dev/null
-// run-pass
-#![feature(box_syntax)]
-
-struct X {
- a: isize
-}
-
-trait Changer : Sized {
- fn change(mut self) -> Self {
- self.set_to(55);
- self
- }
-
- fn change_again(mut self: Box<Self>) -> Box<Self> {
- self.set_to(45);
- self
- }
-
- fn set_to(&mut self, a: isize);
-}
-
-impl Changer for X {
- fn set_to(&mut self, a: isize) {
- self.a = a;
- }
-}
-
-pub fn main() {
- let x = X { a: 32 };
- let new_x = x.change();
- assert_eq!(new_x.a, 55);
-
- let x: Box<_> = box new_x;
- let new_x = x.change_again();
- assert_eq!(new_x.a, 45);
-}
+++ /dev/null
-// run-pass
-// Assert that `mut self` on an immediate value doesn't
-// allow mutating the original - issue #10615.
-
-
-#[derive(Copy, Clone)]
-struct Value {
- n: isize
-}
-
-impl Value {
- fn squared(mut self) -> Value {
- self.n *= self.n;
- self
- }
-}
-
-pub fn main() {
- let x = Value { n: 3 };
- let y = x.squared();
- assert_eq!(x.n, 3);
- assert_eq!(y.n, 9);
-}
+++ /dev/null
-// run-pass
-
-#![feature(untagged_unions)]
-
-#![allow(dead_code)]
-#![allow(unions_with_drop_fields)]
-
-enum A<'a, T: 'a>
-where
- Self: Send, T: PartialEq<Self>
-{
- Foo(&'a Self),
- Bar(T),
-}
-
-struct B<'a, T: 'a>
-where
- Self: Send, T: PartialEq<Self>
-{
- foo: &'a Self,
- bar: T,
-}
-
-union C<'a, T: 'a>
-where
- Self: Send, T: PartialEq<Self>
-{
- foo: &'a Self,
- bar: T,
-}
-
-fn main() {}
+++ /dev/null
-// run-pass
-// Ensure assigning an owned or managed variable to itself works. In particular,
-// that we do not glue_drop before we glue_take (#3290).
-
-#![feature(box_syntax)]
-
-use std::rc::Rc;
-
-pub fn main() {
- let mut x: Box<_> = box 3;
- x = x;
- assert_eq!(*x, 3);
-
- let mut x = Rc::new(3);
- x = x;
- assert_eq!(*x, 3);
-}
+++ /dev/null
-// run-pass
-
-mod a {
- pub mod b {
- pub mod a {
- pub fn foo() -> isize { return 1; }
- }
- }
-}
-
-mod c {
- use a::b::a;
- pub fn bar() { assert_eq!(a::foo(), 1); }
-}
-
-pub fn main() { c::bar(); }
+++ /dev/null
-// run-pass
-#![allow(dead_code)]
-// pretty-expanded FIXME #23616
-
-trait MyTrait {
- fn f(&self) -> Self;
-}
-
-struct S {
- x: isize
-}
-
-impl MyTrait for S {
- fn f(&self) -> S {
- S { x: 3 }
- }
-}
-
-pub fn main() {}
+++ /dev/null
-// run-pass
-pub fn main() {
- // Make sure we properly handle repeated self-appends.
- let mut a: String = "A".to_string();
- let mut i = 20;
- let mut expected_len = 1;
- while i > 0 {
- println!("{}", a.len());
- assert_eq!(a.len(), expected_len);
- a = format!("{}{}", a, a);
- i -= 1;
- expected_len *= 2;
- }
-}
+++ /dev/null
-// run-pass
-#![feature(box_syntax)]
-
-#[derive(Copy, Clone)]
-struct Foo {
- f: isize,
-}
-
-impl Foo {
- fn foo(self: Foo, x: isize) -> isize {
- self.f + x
- }
- fn bar(self: &Foo, x: isize) -> isize {
- self.f + x
- }
- fn baz(self: Box<Foo>, x: isize) -> isize {
- self.f + x
- }
-}
-
-#[derive(Copy, Clone)]
-struct Bar<T> {
- f: T,
-}
-
-impl<T> Bar<T> {
- fn foo(self: Bar<T>, x: isize) -> isize {
- x
- }
- fn bar<'a>(self: &'a Bar<T>, x: isize) -> isize {
- x
- }
- fn baz(self: Bar<T>, x: isize) -> isize {
- x
- }
-}
-
-fn main() {
- let foo: Box<_> = box Foo {
- f: 1,
- };
- println!("{} {} {}", foo.foo(2), foo.bar(2), foo.baz(2));
- let bar: Box<_> = box Bar {
- f: 1,
- };
- println!("{} {} {}", bar.foo(2), bar.bar(2), bar.baz(2));
- let bar: Box<Bar<isize>> = bar;
- println!("{} {} {}", bar.foo(2), bar.bar(2), bar.baz(2));
-}
+++ /dev/null
-// run-pass
-#![feature(box_syntax)]
-
-struct X {
- a: isize
-}
-
-trait Changer {
- fn change(self: Box<Self>) -> Box<Self>;
-}
-
-impl Changer for X {
- fn change(mut self: Box<X>) -> Box<X> {
- self.a = 55;
- self
- }
-}
-
-pub fn main() {
- let x: Box<_> = box X { a: 32 };
- let new_x = x.change();
- assert_eq!(new_x.a, 55);
-}
+++ /dev/null
-// run-pass
-// Test that we can quantify lifetimes outside a constraint (i.e., including
-// the self type) in a where clause.
-
-
-static mut COUNT: u32 = 1;
-
-trait Bar<'a> {
- fn bar(&self);
-}
-
-trait Baz<'a>
-{
- fn baz(&self);
-}
-
-impl<'a, 'b> Bar<'b> for &'a u32 {
- fn bar(&self) {
- unsafe { COUNT *= 2; }
- }
-}
-
-impl<'a, 'b> Baz<'b> for &'a u32 {
- fn baz(&self) {
- unsafe { COUNT *= 3; }
- }
-}
-
-// Test we can use the syntax for HRL including the self type.
-fn foo1<T>(x: &T)
- where for<'a, 'b> &'a T: Bar<'b>
-{
- x.bar()
-}
-
-// Test we can quantify multiple bounds (i.e., the precedence is sensible).
-fn foo2<T>(x: &T)
- where for<'a, 'b> &'a T: Bar<'b> + Baz<'b>
-{
- x.baz();
- x.bar()
-}
-
-fn main() {
- let x = 42;
- foo1(&x);
- foo2(&x);
- unsafe {
- assert_eq!(COUNT, 12);
- }
-}
// ignore-cloudabi no signal handling support
// ignore-wasm32-bare no libc
// ignore-windows
+// ignore-sgx no libc
#![feature(rustc_private)]
extern crate libc;
// ignore-cloudabi no processes
// ignore-emscripten no processes
+// ignore-sgx no processes
// ignore-windows
use std::env;
// ignore-cloudabi no processes
// ignore-emscripten no processes
+// ignore-sgx no processes
use std::env;
use std::io::prelude::*;
#![allow(overflowing_literals)]
// ignore-emscripten
+// ignore-sgx no processes
#![feature(repr_simd, target_feature, cfg_target_feature)]
#![feature(avx512_target_feature)]
// ignore-emscripten no threads support
+// ignore-sgx no thread sleep support
use std::thread::{self, sleep};
use std::time::Duration;
// ignore-wasm
// ignore-cloudabi no processes
// ignore-emscripten no processes
+// ignore-sgx no processes
// ignore-musl FIXME #31506
// ignore-pretty
// compile-flags: -C lto
// ignore-wasm
// ignore-cloudabi no processes
// ignore-emscripten no processes
+// ignore-sgx no processes
// ignore-musl FIXME #31506
use std::mem;
// ignore-cloudabi no processes
// ignore-emscripten no processes
+// ignore-sgx no processes
use std::env;
use std::io::prelude::*;
}
}
+#[cfg(target_env = "sgx")]
+mod m {
+ #[cfg(target_arch = "x86_64")]
+ pub mod m {
+ pub fn align() -> usize { 8 }
+ pub fn size() -> usize { 16 }
+ }
+}
+
#[cfg(target_os = "windows")]
mod m {
#[cfg(target_arch = "x86")]
// ignore-emscripten no threads or sockets support
// ignore-netbsd system ulimit (Too many open files)
// ignore-openbsd system ulimit (Too many open files)
+// ignore-sgx no thread sleep support
use std::io::prelude::*;
use std::net::{TcpListener, TcpStream};
// ignore-cloudabi networking not available
// ignore-wasm32-bare networking not available
+// ignore-sgx ToSocketAddrs cannot be used for DNS Resolution
use std::net::ToSocketAddrs;
#![allow(stable_features)]
// ignore-cloudabi no processes
// ignore-emscripten no processes
+// ignore-sgx no processes
#![feature(process_try_wait)]
--- /dev/null
+// run-pass
+#![allow(dead_code)]
+
+// Tests that unions aren't subject to unsafe non-zero/niche-filling optimizations.
+//
+// For example, if a union `U` can contain both a `&T` and a `*const T`, there's definitely no
+// bit-value that an `Option<U>` could reuse as `None`; this test makes sure that isn't done.
+//
+// Secondly, this tests the status quo (not a guarantee; subject to change!) to not apply such
+// optimizations to types containing unions even if they're theoretically possible. (discussion:
+// https://github.com/rust-lang/rust/issues/36394)
+//
+// Notably this nails down part of the behavior that `MaybeUninit` assumes: that a
+// `Option<MaybeUninit<&u8>>` does not take advantage of non-zero optimization, and thus is a safe
+// construct.
+
+use std::mem::{size_of, transmute};
+
+union U1<A: Copy> {
+ a: A,
+}
+
+union U2<A: Copy, B: Copy> {
+ a: A,
+ b: B,
+}
+
+// Option<E> uses a value other than 0 and 1 as None
+#[derive(Clone,Copy)]
+enum E {
+ A = 0,
+ B = 1,
+}
+
+fn main() {
+ // Unions do not participate in niche-filling/non-zero optimization...
+ assert!(size_of::<Option<U2<&u8, u8>>>() > size_of::<U2<&u8, u8>>());
+ assert!(size_of::<Option<U2<&u8, ()>>>() > size_of::<U2<&u8, ()>>());
+ assert!(size_of::<Option<U2<u8, E>>>() > size_of::<U2<u8, E>>());
+
+ // ...even when theoretically possible:
+ assert!(size_of::<Option<U1<&u8>>>() > size_of::<U1<&u8>>());
+ assert!(size_of::<Option<U2<&u8, &u8>>>() > size_of::<U2<&u8, &u8>>());
+
+ // The unused bits of the () variant can have any value.
+ let zeroed: U2<&u8, ()> = unsafe { transmute(std::ptr::null::<u8>()) };
+
+ if let None = Some(zeroed) {
+ panic!()
+ }
+}
// ignore-cloudabi no processes
// ignore-emscripten no processes
+// ignore-sgx no processes
#![feature(rustc_private)]
// ignore-wasm32-bare no libc to test ffi with
-
+// ignore-sgx no libc
// GetLastError doesn't seem to work with stack switching
#[cfg(windows)]
-//~ ERROR Missing code example in this documentation
-
-#![deny(missing_doc_code_examples)]
+#![deny(missing_doc_code_examples)] //~ ERROR Missing code example in this documentation
/// Some docs.
//~^ ERROR Missing code example in this documentation
error: Missing code example in this documentation
+ --> $DIR/doc-without-codeblock.rs:1:1
+ |
+LL | / #![deny(missing_doc_code_examples)]
+LL | |
+LL | | /// Some docs.
+LL | |
+... |
+LL | | pub fn bar() {}
+LL | | }
+ | |_^
|
note: lint level defined here
- --> $DIR/doc-without-codeblock.rs:3:9
+ --> $DIR/doc-without-codeblock.rs:1:9
|
LL | #![deny(missing_doc_code_examples)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: Missing code example in this documentation
- --> $DIR/doc-without-codeblock.rs:5:1
+ --> $DIR/doc-without-codeblock.rs:3:1
|
LL | /// Some docs.
| ^^^^^^^^^^^^^^
error: Missing code example in this documentation
- --> $DIR/doc-without-codeblock.rs:9:1
+ --> $DIR/doc-without-codeblock.rs:7:1
|
LL | /// And then, the princess died.
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: Missing code example in this documentation
- --> $DIR/doc-without-codeblock.rs:12:5
+ --> $DIR/doc-without-codeblock.rs:10:5
|
LL | /// Or maybe not because she saved herself!
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0425`.
-thread '$DIR/failed-doctest-output.rs - OtherStruct (line 17)' panicked at 'couldn't compile the test', src/librustdoc/test.rs:319:13
+thread '$DIR/failed-doctest-output.rs - OtherStruct (line 17)' panicked at 'couldn't compile the test', src/librustdoc/test.rs:320:13
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
---- $DIR/failed-doctest-output.rs - SomeStruct (line 11) stdout ----
thread 'main' panicked at 'oh no', $DIR/failed-doctest-output.rs:3:1
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
-', src/librustdoc/test.rs:341:17
+', src/librustdoc/test.rs:342:17
failures:
--- /dev/null
+#![deny(missing_docs)]
+#![deny(missing_doc_code_examples)]
+
+//! crate level doc
+//! ```
+//! println!("hello"):
+//! ```
+
+
+/// doc
+///
+/// ```
+/// println!("hello");
+/// ```
+fn test() {
+}
+
+#[allow(missing_docs)]
+mod module1 { //~ ERROR
+}
+
+#[allow(missing_doc_code_examples)]
+/// doc
+mod module2 {
+
+ /// doc
+ pub fn test() {}
+}
+
+/// doc
+///
+/// ```
+/// println!("hello");
+/// ```
+pub mod module3 {
+
+ /// doc
+ //~^ ERROR
+ pub fn test() {}
+}
--- /dev/null
+error: Missing code example in this documentation
+ --> $DIR/lint-missing-doc-code-example.rs:19:1
+ |
+LL | / mod module1 {
+LL | | }
+ | |_^
+ |
+note: lint level defined here
+ --> $DIR/lint-missing-doc-code-example.rs:2:9
+ |
+LL | #![deny(missing_doc_code_examples)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: Missing code example in this documentation
+ --> $DIR/lint-missing-doc-code-example.rs:37:3
+ |
+LL | /// doc
+ | ^^^^^^^
+
+error: aborting due to 2 previous errors
+
error: aborting due to previous error
-thread '$DIR/unparseable-doc-test.rs - foo (line 6)' panicked at 'couldn't compile the test', src/librustdoc/test.rs:319:13
+thread '$DIR/unparseable-doc-test.rs - foo (line 6)' panicked at 'couldn't compile the test', src/librustdoc/test.rs:320:13
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
--- /dev/null
+// compile-flags:--test
+// edition:2018
+
+// prior to setting the default edition for the doctest pre-parser, this doctest would fail due to
+// a fatal parsing error
+// see https://github.com/rust-lang/rust/issues/59313
+
+//! ```
+//! #![feature(async_await)]
+//!
+//! fn foo() {
+//! drop(async move {});
+//! }
+//! ```
#[export_name = "bar"]
pub extern "C" fn g() {}
-// @has foo/enum.Foo.html '//*[@class="docblock attributes"]' '#[repr(i64)]'
-// @has foo/enum.Foo.html '//*[@class="docblock attributes"]' '#[must_use]'
+// @has foo/enum.Foo.html '//*[@class="docblock attributes top-attr"]' '#[repr(i64)]'
+// @has foo/enum.Foo.html '//*[@class="docblock attributes top-attr"]' '#[must_use]'
#[repr(i64)]
#[must_use]
pub enum Foo {
--- /dev/null
+#![feature(const_generics)]
+#![crate_name = "foo"]
+
+// ignore-tidy-linelength
+
+pub enum Order {
+ Sorted,
+ Unsorted,
+}
+
+// @has foo/struct.VSet.html '//pre[@class="rust struct"]' 'pub struct VSet<T, const ORDER: Order>'
+// @has foo/struct.VSet.html '//h3[@id="impl-Send"]/code' 'impl<const ORDER: Order, T> Send for VSet<T, ORDER>'
+// @has foo/struct.VSet.html '//h3[@id="impl-Sync"]/code' 'impl<const ORDER: Order, T> Sync for VSet<T, ORDER>'
+pub struct VSet<T, const ORDER: Order> {
+ inner: Vec<T>,
+}
+
+// @has foo/struct.VSet.html '//h3[@id="impl"]/code' 'impl<T> VSet<T, { Order::Sorted }>'
+impl <T> VSet<T, {Order::Sorted}> {
+ pub fn new() -> Self {
+ Self { inner: Vec::new() }
+ }
+}
+
+// @has foo/struct.VSet.html '//h3[@id="impl-1"]/code' 'impl<T> VSet<T, { Order::Unsorted }>'
+impl <T> VSet<T, {Order::Unsorted}> {
+ pub fn new() -> Self {
+ Self { inner: Vec::new() }
+ }
+}
--- /dev/null
+#![deny(intra_doc_link_resolution_failure)]
+
+pub use std::*;
pub fn dummy() {}
// ensure that `extern crate foo;` was inserted into code snips automatically:
-// @matches foo/index.html '//a[@class="test-arrow"][@href="https://example.com/?code=%23!%5Ballow(unused)%5D%0Aextern%20crate%20foo%3B%0Afn%20main()%20%7B%0Ause%20foo%3A%3Adummy%3B%0Adummy()%3B%0A%7D"]' "Run"
+// @matches foo/index.html '//a[@class="test-arrow"][@href="https://example.com/?code=%23!%5Ballow(unused)%5D%0Aextern%20crate%20foo%3B%0Afn%20main()%20%7B%0Ause%20foo%3A%3Adummy%3B%0Adummy()%3B%0A%7D&edition=2015"]' "Run"
//! }
//! ```
-// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0Afn%20main()%20%7B%0A%20%20%20%20println!(%22Hello%2C%20world!%22)%3B%0A%7D"]' "Run"
-// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0Afn%20main()%20%7B%0Aprintln!(%22Hello%2C%20world!%22)%3B%0A%7D"]' "Run"
-// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0A%23!%5Bfeature(something)%5D%0A%0Afn%20main()%20%7B%0A%20%20%20%20println!(%22Hello%2C%20world!%22)%3B%0A%7D&version=nightly"]' "Run"
+// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0Afn%20main()%20%7B%0A%20%20%20%20println!(%22Hello%2C%20world!%22)%3B%0A%7D&edition=2015"]' "Run"
+// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0Afn%20main()%20%7B%0Aprintln!(%22Hello%2C%20world!%22)%3B%0A%7D&edition=2015"]' "Run"
+// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0A%23!%5Bfeature(something)%5D%0A%0Afn%20main()%20%7B%0A%20%20%20%20println!(%22Hello%2C%20world!%22)%3B%0A%7D&version=nightly&edition=2015"]' "Run"
+++ /dev/null
-#![feature(arbitrary_self_types)]
-
-use std::rc::Rc;
-
-trait Foo {
- fn foo(self: &Rc<Self>) -> usize;
-}
-
-trait Bar {
- fn foo(self: &Rc<Self>) -> usize where Self: Sized;
- fn bar(self: Rc<Self>) -> usize;
-}
-
-impl Foo for usize {
- fn foo(self: &Rc<Self>) -> usize {
- **self
- }
-}
-
-impl Bar for usize {
- fn foo(self: &Rc<Self>) -> usize {
- **self
- }
-
- fn bar(self: Rc<Self>) -> usize {
- *self
- }
-}
-
-fn make_foo() {
- let x = Rc::new(5usize) as Rc<Foo>;
- //~^ ERROR E0038
- //~| ERROR E0038
-}
-
-fn make_bar() {
- let x = Rc::new(5usize) as Rc<Bar>;
- x.bar();
-}
-
-fn main() {}
+++ /dev/null
-error[E0038]: the trait `Foo` cannot be made into an object
- --> $DIR/arbitrary-self-types-not-object-safe.rs:31:32
- |
-LL | let x = Rc::new(5usize) as Rc<Foo>;
- | ^^^^^^^ the trait `Foo` cannot be made into an object
- |
- = note: method `foo`'s receiver cannot be dispatched on
-
-error[E0038]: the trait `Foo` cannot be made into an object
- --> $DIR/arbitrary-self-types-not-object-safe.rs:31:13
- |
-LL | let x = Rc::new(5usize) as Rc<Foo>;
- | ^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object
- |
- = note: method `foo`'s receiver cannot be dispatched on
- = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<std::rc::Rc<dyn Foo>>` for `std::rc::Rc<usize>`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0038`.
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/associated-types-project-from-hrtb-in-fn-body.rs:22:29
+ |
+LL | fn bar<'a, 'b, I : for<'x> Foo<&'x isize>>(
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | let z: I::A = if cond { x } else { y };
+ | ^ assignment requires that `'a` must outlive `'b`
+
+error: lifetime may not live long enough
+ --> $DIR/associated-types-project-from-hrtb-in-fn-body.rs:22:40
+ |
+LL | fn bar<'a, 'b, I : for<'x> Foo<&'x isize>>(
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | let z: I::A = if cond { x } else { y };
+ | ^ assignment requires that `'b` must outlive `'a`
+
+error: aborting due to 2 previous errors
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/associated-types-subtyping-1.rs:24:12
+ |
+LL | fn method2<'a,'b,T>(x: &'a T, y: &'b T)
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | let a: <T as Trait<'a>>::Type = make_any();
+ | ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
+
+error: lifetime may not live long enough
+ --> $DIR/associated-types-subtyping-1.rs:35:13
+ |
+LL | fn method3<'a,'b,T>(x: &'a T, y: &'b T)
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | let _c: <T as Trait<'a>>::Type = b;
+ | ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
+
+error: aborting due to 2 previous errors
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/project-fn-ret-contravariant.rs:45:4
+ |
+LL | fn transmute<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | (a, b)
+ | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+
+error: lifetime may not live long enough
+ --> $DIR/project-fn-ret-contravariant.rs:45:4
+ |
+LL | fn transmute<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | (a, b)
+ | ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
+
+error: aborting due to 2 previous errors
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/project-fn-ret-contravariant.rs:38:4
+ |
+LL | fn baz<'a,'b>(x: &'a u32) -> &'static u32 {
+ | -- lifetime `'a` defined here
+LL | bar(foo, x)
+ | ^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/project-fn-ret-invariant.rs:55:4
+ |
+LL | fn transmute<'a,'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | (a, b)
+ | ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+
+error: lifetime may not live long enough
+ --> $DIR/project-fn-ret-invariant.rs:55:4
+ |
+LL | fn transmute<'a,'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | (a, b)
+ | ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
+
+error: aborting due to 2 previous errors
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/project-fn-ret-invariant.rs:38:12
+ |
+LL | fn baz<'a,'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | let f = foo; // <-- No consistent type can be inferred for `f` here.
+LL | let a = bar(f, x);
+ | ^^^^^^^^^ argument requires that `'a` must outlive `'b`
+
+error: lifetime may not live long enough
+ --> $DIR/project-fn-ret-invariant.rs:39:12
+ |
+LL | fn baz<'a,'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | let b = bar(f, y);
+ | ^^^^^^^^^ argument requires that `'b` must outlive `'a`
+
+error: aborting due to 2 previous errors
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/project-fn-ret-invariant.rs:48:4
+ |
+LL | fn baz<'a,'b>(x: Type<'a>) -> Type<'static> {
+ | -- lifetime `'a` defined here
+...
+LL | bar(foo, x)
+ | ^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+
+error: aborting due to previous error
+
() => {}
}
-fn main() {
- match await { await => () } //~ ERROR expected `!`, found `{`
-}
+fn main() {}
LL | macro_rules! r#await {
| ^^^^^^^
-error: expected `!`, found `{`
- --> $DIR/2018-edition-error-in-non-macro-position.rs:26:17
- |
-LL | match await { await => () }
- | ----- ^ expected `!`
- | |
- | while parsing this match expression
-
-error: aborting due to 8 previous errors
+error: aborting due to 7 previous errors
use self::outer_mod::await::await; //~ ERROR expected identifier
//~^ ERROR expected identifier, found reserved keyword `await`
-fn main() {
- match await { await => () } //~ ERROR expected `!`, found `{`
-}
+fn main() {}
LL | use self::outer_mod::await::r#await;
| ^^^^^^^
-error: expected `!`, found `{`
- --> $DIR/2018-edition-error.rs:13:17
- |
-LL | match await { await => () }
- | ----- ^ expected `!`
- | |
- | while parsing this match expression
-
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
--- /dev/null
+// edition:2018
+
+#![feature(async_await)]
+
+async fn bar() -> Result<(), ()> {
+ Ok(())
+}
+
+async fn foo1() -> Result<(), ()> {
+ let _ = await bar(); //~ ERROR incorrect use of `await`
+ Ok(())
+}
+async fn foo2() -> Result<(), ()> {
+ let _ = await? bar(); //~ ERROR incorrect use of `await`
+ Ok(())
+}
+async fn foo3() -> Result<(), ()> {
+ let _ = await bar()?; //~ ERROR incorrect use of `await`
+ //~^ ERROR the `?` operator can only be applied to values that implement `std::ops::Try`
+ Ok(())
+}
+async fn foo21() -> Result<(), ()> {
+ let _ = await { bar() }; //~ ERROR incorrect use of `await`
+ Ok(())
+}
+async fn foo22() -> Result<(), ()> {
+ let _ = await(bar()); //~ ERROR incorrect use of `await`
+ Ok(())
+}
+async fn foo23() -> Result<(), ()> {
+ let _ = await { bar() }?; //~ ERROR incorrect use of `await`
+ Ok(())
+}
+async fn foo4() -> Result<(), ()> {
+ let _ = (await bar())?; //~ ERROR incorrect use of `await`
+ Ok(())
+}
+async fn foo5() -> Result<(), ()> {
+ let _ = bar().await(); //~ ERROR incorrect use of `await`
+ Ok(())
+}
+async fn foo6() -> Result<(), ()> {
+ let _ = bar().await()?; //~ ERROR incorrect use of `await`
+ Ok(())
+}
+async fn foo7() -> Result<(), ()> {
+ let _ = bar().await; // OK
+ Ok(())
+}
+async fn foo8() -> Result<(), ()> {
+ let _ = bar().await?; // OK
+ Ok(())
+}
+fn foo9() -> Result<(), ()> {
+ let _ = await bar(); //~ ERROR `await` is only allowed inside `async` functions and blocks
+ //~^ ERROR incorrect use of `await`
+ Ok(())
+}
+fn foo10() -> Result<(), ()> {
+ let _ = await? bar(); //~ ERROR `await` is only allowed inside `async` functions and blocks
+ //~^ ERROR incorrect use of `await`
+ Ok(())
+}
+fn foo11() -> Result<(), ()> {
+ let _ = await bar()?; //~ ERROR `await` is only allowed inside `async` functions and blocks
+ //~^ ERROR incorrect use of `await`
+ Ok(())
+}
+fn foo12() -> Result<(), ()> {
+ let _ = (await bar())?; //~ ERROR `await` is only allowed inside `async` functions and blocks
+ //~^ ERROR incorrect use of `await`
+ Ok(())
+}
+fn foo13() -> Result<(), ()> {
+ let _ = bar().await(); //~ ERROR `await` is only allowed inside `async` functions and blocks
+ //~^ ERROR incorrect use of `await`
+ Ok(())
+}
+fn foo14() -> Result<(), ()> {
+ let _ = bar().await()?; //~ ERROR `await` is only allowed inside `async` functions and blocks
+ //~^ ERROR incorrect use of `await`
+ Ok(())
+}
+fn foo15() -> Result<(), ()> {
+ let _ = bar().await; //~ ERROR `await` is only allowed inside `async` functions and blocks
+ Ok(())
+}
+fn foo16() -> Result<(), ()> {
+ let _ = bar().await?; //~ ERROR `await` is only allowed inside `async` functions and blocks
+ Ok(())
+}
+fn foo24() -> Result<(), ()> {
+ fn foo() -> Result<(), ()> {
+ let _ = bar().await?; //~ ERROR `await` is only allowed inside `async` functions and blocks
+ Ok(())
+ }
+ foo()
+}
+fn foo25() -> Result<(), ()> {
+ let foo = || {
+ let _ = bar().await?; //~ ERROR `await` is only allowed inside `async` functions and blocks
+ Ok(())
+ };
+ foo()
+}
+
+fn main() {
+ match await { await => () }
+ //~^ ERROR expected expression, found `=>`
+ //~| ERROR incorrect use of `await`
+} //~ ERROR expected one of `.`, `?`, `{`, or an operator, found `}`
--- /dev/null
+error: incorrect use of `await`
+ --> $DIR/incorrect-syntax-suggestions.rs:10:13
+ |
+LL | let _ = await bar();
+ | ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
+
+error: incorrect use of `await`
+ --> $DIR/incorrect-syntax-suggestions.rs:14:13
+ |
+LL | let _ = await? bar();
+ | ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await?`
+
+error: incorrect use of `await`
+ --> $DIR/incorrect-syntax-suggestions.rs:18:13
+ |
+LL | let _ = await bar()?;
+ | ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar()?.await`
+
+error: incorrect use of `await`
+ --> $DIR/incorrect-syntax-suggestions.rs:23:13
+ |
+LL | let _ = await { bar() };
+ | ^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ bar() }.await`
+
+error: incorrect use of `await`
+ --> $DIR/incorrect-syntax-suggestions.rs:27:13
+ |
+LL | let _ = await(bar());
+ | ^^^^^^^^^^^^ help: `await` is a postfix operation: `(bar()).await`
+
+error: incorrect use of `await`
+ --> $DIR/incorrect-syntax-suggestions.rs:31:13
+ |
+LL | let _ = await { bar() }?;
+ | ^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ bar() }.await`
+
+error: incorrect use of `await`
+ --> $DIR/incorrect-syntax-suggestions.rs:35:14
+ |
+LL | let _ = (await bar())?;
+ | ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
+
+error: incorrect use of `await`
+ --> $DIR/incorrect-syntax-suggestions.rs:39:24
+ |
+LL | let _ = bar().await();
+ | ^^ help: `await` is not a method call, remove the parentheses
+
+error: incorrect use of `await`
+ --> $DIR/incorrect-syntax-suggestions.rs:43:24
+ |
+LL | let _ = bar().await()?;
+ | ^^ help: `await` is not a method call, remove the parentheses
+
+error: incorrect use of `await`
+ --> $DIR/incorrect-syntax-suggestions.rs:55:13
+ |
+LL | let _ = await bar();
+ | ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
+
+error: incorrect use of `await`
+ --> $DIR/incorrect-syntax-suggestions.rs:60:13
+ |
+LL | let _ = await? bar();
+ | ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await?`
+
+error: incorrect use of `await`
+ --> $DIR/incorrect-syntax-suggestions.rs:65:13
+ |
+LL | let _ = await bar()?;
+ | ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar()?.await`
+
+error: incorrect use of `await`
+ --> $DIR/incorrect-syntax-suggestions.rs:70:14
+ |
+LL | let _ = (await bar())?;
+ | ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
+
+error: incorrect use of `await`
+ --> $DIR/incorrect-syntax-suggestions.rs:75:24
+ |
+LL | let _ = bar().await();
+ | ^^ help: `await` is not a method call, remove the parentheses
+
+error: incorrect use of `await`
+ --> $DIR/incorrect-syntax-suggestions.rs:80:24
+ |
+LL | let _ = bar().await()?;
+ | ^^ help: `await` is not a method call, remove the parentheses
+
+error: expected expression, found `=>`
+ --> $DIR/incorrect-syntax-suggestions.rs:108:25
+ |
+LL | match await { await => () }
+ | ----- ^^ expected expression
+ | |
+ | while parsing this incorrect await expression
+
+error: incorrect use of `await`
+ --> $DIR/incorrect-syntax-suggestions.rs:108:11
+ |
+LL | match await { await => () }
+ | ^^^^^^^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ await => () }.await`
+
+error: expected one of `.`, `?`, `{`, or an operator, found `}`
+ --> $DIR/incorrect-syntax-suggestions.rs:111:1
+ |
+LL | match await { await => () }
+ | ----- - expected one of `.`, `?`, `{`, or an operator here
+ | |
+ | while parsing this match expression
+...
+LL | }
+ | ^ unexpected token
+
+error[E0728]: `await` is only allowed inside `async` functions and blocks
+ --> $DIR/incorrect-syntax-suggestions.rs:55:13
+ |
+LL | fn foo9() -> Result<(), ()> {
+ | ---- this is not `async`
+LL | let _ = await bar();
+ | ^^^^^^^^^^^ only allowed inside `async` functions and blocks
+
+error[E0728]: `await` is only allowed inside `async` functions and blocks
+ --> $DIR/incorrect-syntax-suggestions.rs:60:13
+ |
+LL | fn foo10() -> Result<(), ()> {
+ | ----- this is not `async`
+LL | let _ = await? bar();
+ | ^^^^^^^^^^^^ only allowed inside `async` functions and blocks
+
+error[E0728]: `await` is only allowed inside `async` functions and blocks
+ --> $DIR/incorrect-syntax-suggestions.rs:65:13
+ |
+LL | fn foo11() -> Result<(), ()> {
+ | ----- this is not `async`
+LL | let _ = await bar()?;
+ | ^^^^^^^^^^^^ only allowed inside `async` functions and blocks
+
+error[E0728]: `await` is only allowed inside `async` functions and blocks
+ --> $DIR/incorrect-syntax-suggestions.rs:70:14
+ |
+LL | fn foo12() -> Result<(), ()> {
+ | ----- this is not `async`
+LL | let _ = (await bar())?;
+ | ^^^^^^^^^^^ only allowed inside `async` functions and blocks
+
+error[E0728]: `await` is only allowed inside `async` functions and blocks
+ --> $DIR/incorrect-syntax-suggestions.rs:75:13
+ |
+LL | fn foo13() -> Result<(), ()> {
+ | ----- this is not `async`
+LL | let _ = bar().await();
+ | ^^^^^^^^^^^ only allowed inside `async` functions and blocks
+
+error[E0728]: `await` is only allowed inside `async` functions and blocks
+ --> $DIR/incorrect-syntax-suggestions.rs:80:13
+ |
+LL | fn foo14() -> Result<(), ()> {
+ | ----- this is not `async`
+LL | let _ = bar().await()?;
+ | ^^^^^^^^^^^ only allowed inside `async` functions and blocks
+
+error[E0728]: `await` is only allowed inside `async` functions and blocks
+ --> $DIR/incorrect-syntax-suggestions.rs:85:13
+ |
+LL | fn foo15() -> Result<(), ()> {
+ | ----- this is not `async`
+LL | let _ = bar().await;
+ | ^^^^^^^^^^^ only allowed inside `async` functions and blocks
+
+error[E0728]: `await` is only allowed inside `async` functions and blocks
+ --> $DIR/incorrect-syntax-suggestions.rs:89:13
+ |
+LL | fn foo16() -> Result<(), ()> {
+ | ----- this is not `async`
+LL | let _ = bar().await?;
+ | ^^^^^^^^^^^ only allowed inside `async` functions and blocks
+
+error[E0728]: `await` is only allowed inside `async` functions and blocks
+ --> $DIR/incorrect-syntax-suggestions.rs:94:17
+ |
+LL | fn foo() -> Result<(), ()> {
+ | --- this is not `async`
+LL | let _ = bar().await?;
+ | ^^^^^^^^^^^ only allowed inside `async` functions and blocks
+
+error[E0728]: `await` is only allowed inside `async` functions and blocks
+ --> $DIR/incorrect-syntax-suggestions.rs:101:17
+ |
+LL | let foo = || {
+ | -- this is not `async`
+LL | let _ = bar().await?;
+ | ^^^^^^^^^^^ only allowed inside `async` functions and blocks
+
+error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
+ --> $DIR/incorrect-syntax-suggestions.rs:18:19
+ |
+LL | let _ = await bar()?;
+ | ^^^^^^ the `?` operator cannot be applied to type `impl std::future::Future`
+ |
+ = help: the trait `std::ops::Try` is not implemented for `impl std::future::Future`
+ = note: required by `std::ops::Try::into_result`
+
+error: aborting due to 29 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
--> $DIR/post_expansion_error.rs:8:12
|
LL | await!()
- | ^ expected expression
+ | ----- ^ expected expression
+ | |
+ | while parsing this await macro call
error: aborting due to previous error
--- /dev/null
+error[E0503]: cannot use `y` because it was mutably borrowed
+ --> $DIR/borrowck-anon-fields-variant.rs:17:7
+ |
+LL | Foo::Y(ref mut a, _) => a,
+ | --------- borrow of `y.0` occurs here
+...
+LL | Foo::Y(_, ref mut b) => b,
+ | ^^^^^^^^^^^^^^^^^^^^ use of borrowed `y.0`
+...
+LL | *a += 1;
+ | ------- borrow later used here
+
+error[E0503]: cannot use `y` because it was mutably borrowed
+ --> $DIR/borrowck-anon-fields-variant.rs:37:7
+ |
+LL | Foo::Y(ref mut a, _) => a,
+ | --------- borrow of `y.0` occurs here
+...
+LL | Foo::Y(ref mut b, _) => b,
+ | ^^^^^^^^^^^^^^^^^^^^ use of borrowed `y.0`
+...
+LL | *a += 1;
+ | ------- borrow later used here
+
+error[E0499]: cannot borrow `y.0` as mutable more than once at a time
+ --> $DIR/borrowck-anon-fields-variant.rs:37:14
+ |
+LL | Foo::Y(ref mut a, _) => a,
+ | --------- first mutable borrow occurs here
+...
+LL | Foo::Y(ref mut b, _) => b,
+ | ^^^^^^^^^ second mutable borrow occurs here
+...
+LL | *a += 1;
+ | ------- first borrow later used here
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0499, E0503.
+For more information about an error, try `rustc --explain E0499`.
--- /dev/null
+error[E0499]: cannot borrow `x` as mutable more than once at a time
+ --> $DIR/borrowck-describe-lvalue.rs:262:13
+ |
+LL | let y = &mut x;
+ | ------ first mutable borrow occurs here
+LL | &mut x;
+ | ^^^^^^ second mutable borrow occurs here
+LL | *y = 1;
+ | ------ first borrow later used here
+
+error[E0499]: cannot borrow `x` as mutable more than once at a time
+ --> $DIR/borrowck-describe-lvalue.rs:272:20
+ |
+LL | let y = &mut x;
+ | ------ first mutable borrow occurs here
+LL | &mut x;
+ | ^^^^^^ second mutable borrow occurs here
+LL | *y = 1;
+ | ------ first borrow later used here
+
+error: captured variable cannot escape `FnMut` closure body
+ --> $DIR/borrowck-describe-lvalue.rs:270:16
+ |
+LL | || {
+ | - inferred to be a `FnMut` closure
+LL | / || {
+LL | | let y = &mut x;
+LL | | &mut x;
+LL | | *y = 1;
+LL | | drop(y);
+LL | | }
+ | |_________________^ returns a closure that contains a reference to a captured variable, which then escapes the closure body
+ |
+ = note: `FnMut` closures only have access to their captured variables while they are executing...
+ = note: ...therefore, they cannot allow references to captured variables to escape
+
+error[E0503]: cannot use `f.x` because it was mutably borrowed
+ --> $DIR/borrowck-describe-lvalue.rs:41:9
+ |
+LL | let x = f.x();
+ | - borrow of `f` occurs here
+LL | f.x;
+ | ^^^ use of borrowed `f`
+LL | drop(x);
+ | - borrow later used here
+
+error[E0503]: cannot use `g.0` because it was mutably borrowed
+ --> $DIR/borrowck-describe-lvalue.rs:48:9
+ |
+LL | let x = g.x();
+ | - borrow of `g` occurs here
+LL | g.0;
+ | ^^^ use of borrowed `g`
+LL | drop(x);
+ | - borrow later used here
+
+error[E0503]: cannot use `h.0` because it was mutably borrowed
+ --> $DIR/borrowck-describe-lvalue.rs:55:9
+ |
+LL | let x = &mut h.0;
+ | -------- borrow of `h.0` occurs here
+LL | h.0;
+ | ^^^ use of borrowed `h.0`
+LL | drop(x);
+ | - borrow later used here
+
+error[E0503]: cannot use `e.0` because it was mutably borrowed
+ --> $DIR/borrowck-describe-lvalue.rs:63:20
+ |
+LL | let x = e.x();
+ | - borrow of `e` occurs here
+LL | match e {
+LL | Baz::X(value) => value
+ | ^^^^^ use of borrowed `e`
+LL | };
+LL | drop(x);
+ | - borrow later used here
+
+error[E0503]: cannot use `u.a` because it was mutably borrowed
+ --> $DIR/borrowck-describe-lvalue.rs:71:9
+ |
+LL | let x = &mut u.a;
+ | -------- borrow of `u.a` occurs here
+LL | u.a;
+ | ^^^ use of borrowed `u.a`
+LL | drop(x);
+ | - borrow later used here
+
+error[E0503]: cannot use `f.x` because it was mutably borrowed
+ --> $DIR/borrowck-describe-lvalue.rs:78:9
+ |
+LL | let x = f.x();
+ | - borrow of `*f` occurs here
+LL | f.x;
+ | ^^^ use of borrowed `*f`
+LL | drop(x);
+ | - borrow later used here
+
+error[E0503]: cannot use `g.0` because it was mutably borrowed
+ --> $DIR/borrowck-describe-lvalue.rs:85:9
+ |
+LL | let x = g.x();
+ | - borrow of `*g` occurs here
+LL | g.0;
+ | ^^^ use of borrowed `*g`
+LL | drop(x);
+ | - borrow later used here
+
+error[E0503]: cannot use `h.0` because it was mutably borrowed
+ --> $DIR/borrowck-describe-lvalue.rs:92:9
+ |
+LL | let x = &mut h.0;
+ | -------- borrow of `h.0` occurs here
+LL | h.0;
+ | ^^^ use of borrowed `h.0`
+LL | drop(x);
+ | - borrow later used here
+
+error[E0503]: cannot use `e.0` because it was mutably borrowed
+ --> $DIR/borrowck-describe-lvalue.rs:100:20
+ |
+LL | let x = e.x();
+ | - borrow of `*e` occurs here
+LL | match *e {
+LL | Baz::X(value) => value
+ | ^^^^^ use of borrowed `*e`
+...
+LL | drop(x);
+ | - borrow later used here
+
+error[E0503]: cannot use `u.a` because it was mutably borrowed
+ --> $DIR/borrowck-describe-lvalue.rs:109:9
+ |
+LL | let x = &mut u.a;
+ | -------- borrow of `u.a` occurs here
+LL | u.a;
+ | ^^^ use of borrowed `u.a`
+LL | drop(x);
+ | - borrow later used here
+
+error[E0503]: cannot use `v[..]` because it was mutably borrowed
+ --> $DIR/borrowck-describe-lvalue.rs:117:15
+ |
+LL | let x = &mut v;
+ | ------ borrow of `v` occurs here
+LL | match v {
+LL | &[x, _, .., _, _] => println!("{}", x),
+ | ^ use of borrowed `v`
+...
+LL | drop(x);
+ | - borrow later used here
+
+error[E0503]: cannot use `v[..]` because it was mutably borrowed
+ --> $DIR/borrowck-describe-lvalue.rs:122:18
+ |
+LL | let x = &mut v;
+ | ------ borrow of `v` occurs here
+...
+LL | &[_, x, .., _, _] => println!("{}", x),
+ | ^ use of borrowed `v`
+...
+LL | drop(x);
+ | - borrow later used here
+
+error[E0503]: cannot use `v[..]` because it was mutably borrowed
+ --> $DIR/borrowck-describe-lvalue.rs:127:25
+ |
+LL | let x = &mut v;
+ | ------ borrow of `v` occurs here
+...
+LL | &[_, _, .., x, _] => println!("{}", x),
+ | ^ use of borrowed `v`
+...
+LL | drop(x);
+ | - borrow later used here
+
+error[E0503]: cannot use `v[..]` because it was mutably borrowed
+ --> $DIR/borrowck-describe-lvalue.rs:132:28
+ |
+LL | let x = &mut v;
+ | ------ borrow of `v` occurs here
+...
+LL | &[_, _, .., _, x] => println!("{}", x),
+ | ^ use of borrowed `v`
+...
+LL | drop(x);
+ | - borrow later used here
+
+error[E0503]: cannot use `v[..]` because it was mutably borrowed
+ --> $DIR/borrowck-describe-lvalue.rs:143:15
+ |
+LL | let x = &mut v;
+ | ------ borrow of `v` occurs here
+LL | match v {
+LL | &[x..] => println!("{:?}", x),
+ | ^ use of borrowed `v`
+...
+LL | drop(x);
+ | - borrow later used here
+
+error[E0503]: cannot use `v[..]` because it was mutably borrowed
+ --> $DIR/borrowck-describe-lvalue.rs:148:18
+ |
+LL | let x = &mut v;
+ | ------ borrow of `v` occurs here
+...
+LL | &[_, x..] => println!("{:?}", x),
+ | ^ use of borrowed `v`
+...
+LL | drop(x);
+ | - borrow later used here
+
+error[E0503]: cannot use `v[..]` because it was mutably borrowed
+ --> $DIR/borrowck-describe-lvalue.rs:153:15
+ |
+LL | let x = &mut v;
+ | ------ borrow of `v` occurs here
+...
+LL | &[x.., _] => println!("{:?}", x),
+ | ^ use of borrowed `v`
+...
+LL | drop(x);
+ | - borrow later used here
+
+error[E0503]: cannot use `v[..]` because it was mutably borrowed
+ --> $DIR/borrowck-describe-lvalue.rs:158:18
+ |
+LL | let x = &mut v;
+ | ------ borrow of `v` occurs here
+...
+LL | &[_, x.., _] => println!("{:?}", x),
+ | ^ use of borrowed `v`
+...
+LL | drop(x);
+ | - borrow later used here
+
+error[E0503]: cannot use `e` because it was mutably borrowed
+ --> $DIR/borrowck-describe-lvalue.rs:171:13
+ |
+LL | let x = &mut e;
+ | ------ borrow of `e` occurs here
+LL | match e {
+LL | E::A(ref ax) =>
+ | ^^^^^^^^^^^^ use of borrowed `e`
+...
+LL | drop(x);
+ | - borrow later used here
+
+error[E0502]: cannot borrow `e.0` as immutable because it is also borrowed as mutable
+ --> $DIR/borrowck-describe-lvalue.rs:171:18
+ |
+LL | let x = &mut e;
+ | ------ mutable borrow occurs here
+LL | match e {
+LL | E::A(ref ax) =>
+ | ^^^^^^ immutable borrow occurs here
+...
+LL | drop(x);
+ | - mutable borrow later used here
+
+error[E0502]: cannot borrow `e.x` as immutable because it is also borrowed as mutable
+ --> $DIR/borrowck-describe-lvalue.rs:175:23
+ |
+LL | let x = &mut e;
+ | ------ mutable borrow occurs here
+...
+LL | E::B { x: ref bx } =>
+ | ^^^^^^ immutable borrow occurs here
+...
+LL | drop(x);
+ | - mutable borrow later used here
+
+error[E0502]: cannot borrow `s.y.0` as immutable because it is also borrowed as mutable
+ --> $DIR/borrowck-describe-lvalue.rs:188:22
+ |
+LL | let x = &mut s;
+ | ------ mutable borrow occurs here
+LL | match s {
+LL | S { y: (ref y0, _), .. } =>
+ | ^^^^^^ immutable borrow occurs here
+...
+LL | drop(x);
+ | - mutable borrow later used here
+
+error[E0502]: cannot borrow `s.x.y` as immutable because it is also borrowed as mutable
+ --> $DIR/borrowck-describe-lvalue.rs:194:28
+ |
+LL | let x = &mut s;
+ | ------ mutable borrow occurs here
+...
+LL | S { x: F { y: ref x0, .. }, .. } =>
+ | ^^^^^^ immutable borrow occurs here
+...
+LL | drop(x);
+ | - mutable borrow later used here
+
+error[E0503]: cannot use `*v` because it was mutably borrowed
+ --> $DIR/borrowck-describe-lvalue.rs:240:9
+ |
+LL | let x = &mut v;
+ | ------ borrow of `v` occurs here
+LL | v[0].y;
+ | ^^^^ use of borrowed `v`
+...
+LL | drop(x);
+ | - borrow later used here
+
+error[E0503]: cannot use `v[_].y` because it was mutably borrowed
+ --> $DIR/borrowck-describe-lvalue.rs:240:9
+ |
+LL | let x = &mut v;
+ | ------ borrow of `v` occurs here
+LL | v[0].y;
+ | ^^^^^^ use of borrowed `v`
+...
+LL | drop(x);
+ | - borrow later used here
+
+error[E0502]: cannot borrow `v[..].x` as immutable because it is also borrowed as mutable
+ --> $DIR/borrowck-describe-lvalue.rs:251:24
+ |
+LL | let x = &mut v;
+ | ------ mutable borrow occurs here
+LL | match v {
+LL | &[_, F {x: ref xf, ..}] => println!("{}", xf),
+ | ^^^^^^ immutable borrow occurs here
+...
+LL | drop(x);
+ | - mutable borrow later used here
+
+error[E0502]: cannot borrow `*block.current` as immutable because it is also borrowed as mutable
+ --> $DIR/borrowck-describe-lvalue.rs:210:29
+ |
+LL | let x = &mut block;
+ | ---------- mutable borrow occurs here
+LL | let p: &'a u8 = &*block.current;
+ | ^^^^^^^^^^^^^^^ immutable borrow occurs here
+...
+LL | drop(x);
+ | - mutable borrow later used here
+
+error[E0502]: cannot borrow `*block.current` as immutable because it is also borrowed as mutable
+ --> $DIR/borrowck-describe-lvalue.rs:227:33
+ |
+LL | let x = &mut block;
+ | ---------- mutable borrow occurs here
+LL | let p : *const u8 = &*(*block).current;
+ | ^^^^^^^^^^^^^^^^^^ immutable borrow occurs here
+...
+LL | drop(x);
+ | - mutable borrow later used here
+
+error[E0382]: use of moved value: `x`
+ --> $DIR/borrowck-describe-lvalue.rs:282:22
+ |
+LL | drop(x);
+ | - value moved here
+LL | drop(x);
+ | ^ value used here after move
+ |
+ = note: move occurs because `x` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
+
+error: aborting due to 32 previous errors
+
+Some errors have detailed explanations: E0382, E0499, E0502, E0503.
+For more information about an error, try `rustc --explain E0382`.
--- /dev/null
+error[E0502]: cannot borrow `vector` as mutable because it is also borrowed as immutable
+ --> $DIR/borrowck-for-loop-head-linkage.rs:7:9
+ |
+LL | for &x in &vector {
+ | -------
+ | |
+ | immutable borrow occurs here
+ | immutable borrow later used here
+LL | let cap = vector.capacity();
+LL | vector.extend(repeat(0));
+ | ^^^^^^ mutable borrow occurs here
+
+error[E0502]: cannot borrow `vector` as mutable because it is also borrowed as immutable
+ --> $DIR/borrowck-for-loop-head-linkage.rs:8:9
+ |
+LL | for &x in &vector {
+ | -------
+ | |
+ | immutable borrow occurs here
+ | immutable borrow later used here
+...
+LL | vector[1] = 5;
+ | ^^^^^^ mutable borrow occurs here
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0502`.
-#![feature(nll)]
-
struct Node {
elem: i32,
next: Option<Box<Node>>,
error[E0382]: use of moved value: `src`
- --> $DIR/borrowck-issue-48962.rs:16:5
+ --> $DIR/borrowck-issue-48962.rs:14:5
|
LL | let mut src = &mut node;
| ------- move occurs because `src` has type `&mut Node`, which does not implement the `Copy` trait
| ^^^^^^^^ value used here after move
error[E0382]: use of moved value: `src`
- --> $DIR/borrowck-issue-48962.rs:22:5
+ --> $DIR/borrowck-issue-48962.rs:20:5
|
LL | let mut src = &mut (22, 44);
| ------- move occurs because `src` has type `&mut (i32, i32)`, which does not implement the `Copy` trait
--- /dev/null
+error[E0302]: cannot assign in a pattern guard
+ --> $DIR/borrowck-mutate-in-guard.rs:10:25
+ |
+LL | Enum::A(_) if { x = Enum::B(false); false } => 1,
+ | ^^^^^^^^^^^^^^^^^^ assignment in pattern guard
+
+error[E0301]: cannot mutably borrow in a pattern guard
+ --> $DIR/borrowck-mutate-in-guard.rs:15:38
+ |
+LL | Enum::A(_) if { let y = &mut x; *y = Enum::B(false); false } => 1,
+ | ^ borrowed mutably in pattern guard
+ |
+ = help: add #![feature(bind_by_move_pattern_guards)] to the crate attributes to enable
+
+error[E0302]: cannot assign in a pattern guard
+ --> $DIR/borrowck-mutate-in-guard.rs:15:41
+ |
+LL | Enum::A(_) if { let y = &mut x; *y = Enum::B(false); false } => 1,
+ | ^^^^^^^^^^^^^^^^^^^ assignment in pattern guard
+
+error[E0510]: cannot assign `x` in match guard
+ --> $DIR/borrowck-mutate-in-guard.rs:10:25
+ |
+LL | match x {
+ | - value is immutable in match guard
+LL | Enum::A(_) if { x = Enum::B(false); false } => 1,
+ | ^^^^^^^^^^^^^^^^^^ cannot assign
+
+error[E0510]: cannot mutably borrow `x` in match guard
+ --> $DIR/borrowck-mutate-in-guard.rs:15:33
+ |
+LL | match x {
+ | - value is immutable in match guard
+...
+LL | Enum::A(_) if { let y = &mut x; *y = Enum::B(false); false } => 1,
+ | ^^^^^^ cannot mutably borrow
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0301, E0302, E0510.
+For more information about an error, try `rustc --explain E0301`.
--- /dev/null
+error[E0502]: cannot borrow `*x` as mutable because it is also borrowed as immutable
+ --> $DIR/borrowck-object-lifetime.rs:20:13
+ |
+LL | let y = x.borrowed();
+ | - immutable borrow occurs here
+LL | let z = x.mut_borrowed();
+ | ^ mutable borrow occurs here
+LL | y.use_ref();
+ | - immutable borrow later used here
+
+error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable
+ --> $DIR/borrowck-object-lifetime.rs:26:13
+ |
+LL | let y = x.borrowed();
+ | - immutable borrow occurs here
+LL | let z = &mut x;
+ | ^^^^^^ mutable borrow occurs here
+LL | y.use_ref();
+ | - immutable borrow later used here
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0502`.
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/borrowck-reborrow-from-shorter-lived-andmut.rs:9:5
+ |
+LL | fn copy_borrowed_ptr<'a,'b>(p: &'a mut S<'b>) -> S<'b> {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | S { pointer: &mut *p.pointer }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+
+error: aborting due to previous error
+
// run-pass
-#![feature(nll)]
-
enum Nat {
S(Box<Nat>),
Z
// run-pass
-#![feature(nll)]
-
fn foo(x: &mut Result<(u32, u32), (u32, u32)>) -> u32 {
match *x {
Ok((ref mut v, _)) | Err((_, ref mut v)) if *v > 0 => { *v }
// computing liveness that wound up accidentally causing the program
// below to be accepted.
-#![feature(nll)]
-
fn foo<'a>(x: &'a mut u32) -> u32 {
let mut x = 22;
let y = &x;
error[E0506]: cannot assign to `x` because it is borrowed
- --> $DIR/issue-52713-bug.rs:14:5
+ --> $DIR/issue-52713-bug.rs:12:5
|
LL | let y = &x;
| -- borrow of `x` occurs here
-#![feature(nll)]
-
#![allow(dead_code)]
#[derive(Debug)]
error[E0507]: cannot move out of borrowed content
- --> $DIR/issue-54597-reject-move-out-of-borrow-via-pat.rs:16:13
+ --> $DIR/issue-54597-reject-move-out-of-borrow-via-pat.rs:14:13
|
LL | *array
| ^^^^^^
+++ /dev/null
-error[E0506]: cannot assign to `greeting` because it is borrowed
- --> $DIR/issue-58776-borrowck-scans-children.rs:11:5
- |
-LL | let res = (|| (|| &greeting)())();
- | -- -------- borrow occurs due to use in closure
- | |
- | borrow of `greeting` occurs here
-LL |
-LL | greeting = "DEALLOCATED".to_string();
- | ^^^^^^^^ assignment to borrowed `greeting` occurs here
-...
-LL | println!("thread result: {:?}", res);
- | --- borrow later used here
-
-error[E0505]: cannot move out of `greeting` because it is borrowed
- --> $DIR/issue-58776-borrowck-scans-children.rs:14:10
- |
-LL | let res = (|| (|| &greeting)())();
- | -- -------- borrow occurs due to use in closure
- | |
- | borrow of `greeting` occurs here
-...
-LL | drop(greeting);
- | ^^^^^^^^ move out of `greeting` occurs here
-...
-LL | println!("thread result: {:?}", res);
- | --- borrow later used here
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0505, E0506.
-For more information about an error, try `rustc --explain E0505`.
-// ignore-compare-mode-nll
-
-// revisions: migrate nll
-
-#![cfg_attr(nll, feature(nll))]
-
fn main() {
let mut greeting = "Hello world!".to_string();
let res = (|| (|| &greeting)())();
greeting = "DEALLOCATED".to_string();
- //[migrate]~^ ERROR cannot assign
- //[nll]~^^ ERROR cannot assign
+ //~^ ERROR cannot assign
drop(greeting);
- //[migrate]~^ ERROR cannot move
- //[nll]~^^ ERROR cannot move
+ //~^ ERROR cannot move
println!("thread result: {:?}", res);
}
--- /dev/null
+error[E0506]: cannot assign to `greeting` because it is borrowed
+ --> $DIR/issue-58776-borrowck-scans-children.rs:5:5
+ |
+LL | let res = (|| (|| &greeting)())();
+ | -- -------- borrow occurs due to use in closure
+ | |
+ | borrow of `greeting` occurs here
+LL |
+LL | greeting = "DEALLOCATED".to_string();
+ | ^^^^^^^^ assignment to borrowed `greeting` occurs here
+...
+LL | println!("thread result: {:?}", res);
+ | --- borrow later used here
+
+error[E0505]: cannot move out of `greeting` because it is borrowed
+ --> $DIR/issue-58776-borrowck-scans-children.rs:7:10
+ |
+LL | let res = (|| (|| &greeting)())();
+ | -- -------- borrow occurs due to use in closure
+ | |
+ | borrow of `greeting` occurs here
+...
+LL | drop(greeting);
+ | ^^^^^^^^ move out of `greeting` occurs here
+...
+LL | println!("thread result: {:?}", res);
+ | --- borrow later used here
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0505, E0506.
+For more information about an error, try `rustc --explain E0505`.
--- /dev/null
+error[E0521]: borrowed data escapes outside of closure
+ --> $DIR/issue-7573.rs:21:9
+ |
+LL | let mut lines_to_use: Vec<&CrateId> = Vec::new();
+ | ---------------- `lines_to_use` is declared here, outside of the closure body
+LL |
+LL | let push_id = |installed_id: &CrateId| {
+ | ------------ `installed_id` is a reference that is only valid in the closure body
+...
+LL | lines_to_use.push(installed_id);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `installed_id` escapes the closure body here
+
+error: aborting due to previous error
+
--- /dev/null
+error[E0521]: borrowed data escapes outside of closure
+ --> $DIR/regions-escape-bound-fn-2.rs:8:18
+ |
+LL | let mut x = None;
+ | ----- `x` is declared here, outside of the closure body
+LL | with_int(|y| x = Some(y));
+ | - ^^^^^^^^^^^ `y` escapes the closure body here
+ | |
+ | `y` is a reference that is only valid in the closure body
+
+error: aborting due to previous error
+
--- /dev/null
+error[E0521]: borrowed data escapes outside of closure
+ --> $DIR/regions-escape-bound-fn.rs:8:18
+ |
+LL | let mut x: Option<&isize> = None;
+ | ----- `x` is declared here, outside of the closure body
+LL | with_int(|y| x = Some(y));
+ | - ^^^^^^^^^^^ `y` escapes the closure body here
+ | |
+ | `y` is a reference that is only valid in the closure body
+
+error: aborting due to previous error
+
--- /dev/null
+error[E0521]: borrowed data escapes outside of closure
+ --> $DIR/regions-escape-unboxed-closure.rs:6:23
+ |
+LL | let mut x: Option<&isize> = None;
+ | ----- `x` is declared here, outside of the closure body
+LL | with_int(&mut |y| x = Some(y));
+ | - ^^^^^^^^^^^ `y` escapes the closure body here
+ | |
+ | `y` is a reference that is only valid in the closure body
+
+error: aborting due to previous error
+
// Test that a borrow which starts as a 2-phase borrow and gets
// carried around a loop winds up conflicting with itself.
-#![feature(nll)]
-
struct Foo { x: String }
impl Foo {
error[E0499]: cannot borrow `foo` as mutable more than once at a time
- --> $DIR/two-phase-across-loop.rs:19:22
+ --> $DIR/two-phase-across-loop.rs:17:22
|
LL | strings.push(foo.get_string());
| ^^^ mutable borrow starts here in previous iteration of loop
-#![feature(nll)]
-
struct Foo {
}
error[E0499]: cannot borrow `foo` as mutable more than once at a time
- --> $DIR/two-phase-multi-mut.rs:13:5
+ --> $DIR/two-phase-multi-mut.rs:11:5
|
LL | foo.method(&mut foo);
| ^^^^------^--------^
| second mutable borrow occurs here
error[E0499]: cannot borrow `foo` as mutable more than once at a time
- --> $DIR/two-phase-multi-mut.rs:13:16
+ --> $DIR/two-phase-multi-mut.rs:11:16
|
LL | foo.method(&mut foo);
| --- ------ ^^^^^^^^ second mutable borrow occurs here
--- /dev/null
+error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable
+ --> $DIR/two-phase-reservation-sharing-interference-future-compat-lint.rs:13:9
+ |
+LL | let shared = &v;
+ | -- immutable borrow occurs here
+LL |
+LL | v.push(shared.len());
+ | ^ ------ immutable borrow later used here
+ | |
+ | mutable borrow occurs here
+
+error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable
+ --> $DIR/two-phase-reservation-sharing-interference-future-compat-lint.rs:24:9
+ |
+LL | let shared = &v;
+ | -- immutable borrow occurs here
+LL |
+LL | v.push(shared.len());
+ | ^ ------ immutable borrow later used here
+ | |
+ | mutable borrow occurs here
+
+error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable
+ --> $DIR/two-phase-reservation-sharing-interference-future-compat-lint.rs:37:9
+ |
+LL | let shared = &v;
+ | -- immutable borrow occurs here
+LL |
+LL | v.push(shared.len());
+ | ^ ------ immutable borrow later used here
+ | |
+ | mutable borrow occurs here
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0502`.
--- /dev/null
+error[E0621]: explicit lifetime required in the type of `ap`
+ --> $DIR/variadic-ffi-4.rs:8:5
+ |
+LL | pub unsafe extern "C" fn no_escape0<'a>(_: usize, ap: ...) -> VaList<'a> {
+ | --- help: add explicit lifetime `'a` to the type of `ap`: `core::ffi::VaList<'a>`
+LL | ap
+ | ^^ lifetime `'a` required
+
+error[E0621]: explicit lifetime required in the type of `ap`
+ --> $DIR/variadic-ffi-4.rs:12:5
+ |
+LL | pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaList<'static> {
+ | --- help: add explicit lifetime `'static` to the type of `ap`: `core::ffi::VaList<'static>`
+LL | ap
+ | ^^ lifetime `'static` required
+
+error: lifetime may not live long enough
+ --> $DIR/variadic-ffi-4.rs:16:33
+ |
+LL | let _ = ap.with_copy(|ap| { ap });
+ | --- ^^ returning this value requires that `'1` must outlive `'2`
+ | | |
+ | | return type of closure is core::ffi::VaList<'2>
+ | has type `core::ffi::VaList<'1>`
+
+error: lifetime may not live long enough
+ --> $DIR/variadic-ffi-4.rs:20:5
+ |
+LL | pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaList, mut ap1: ...) {
+ | ------- ------- has type `core::ffi::VaList<'1>`
+ | |
+ | has type `&mut core::ffi::VaList<'2>`
+LL | *ap0 = ap1;
+ | ^^^^^^^^^^ assignment requires that `'1` must outlive `'2`
+
+error: lifetime may not live long enough
+ --> $DIR/variadic-ffi-4.rs:24:5
+ |
+LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaList, mut ap1: ...) {
+ | --- ------- has type `core::ffi::VaList<'2>`
+ | |
+ | has type `&mut core::ffi::VaList<'1>`
+LL | ap0 = &mut ap1;
+ | ^^^^^^^^^^^^^^ assignment requires that `'1` must outlive `'2`
+
+error: lifetime may not live long enough
+ --> $DIR/variadic-ffi-4.rs:24:5
+ |
+LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaList, mut ap1: ...) {
+ | --- ------- has type `core::ffi::VaList<'1>`
+ | |
+ | has type `&mut core::ffi::VaList<'2>`
+LL | ap0 = &mut ap1;
+ | ^^^^^^^^^^^^^^ assignment requires that `'1` must outlive `'2`
+
+error[E0384]: cannot assign to immutable argument `ap0`
+ --> $DIR/variadic-ffi-4.rs:24:5
+ |
+LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaList, mut ap1: ...) {
+ | --- help: make this binding mutable: `mut ap0`
+LL | ap0 = &mut ap1;
+ | ^^^^^^^^^^^^^^ cannot assign to immutable argument
+
+error[E0597]: `ap1` does not live long enough
+ --> $DIR/variadic-ffi-4.rs:24:11
+ |
+LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaList, mut ap1: ...) {
+ | - let's call the lifetime of this reference `'1`
+LL | ap0 = &mut ap1;
+ | ------^^^^^^^^
+ | | |
+ | | borrowed value does not live long enough
+ | assignment requires that `ap1` is borrowed for `'1`
+...
+LL | }
+ | - `ap1` dropped here while still borrowed
+
+error: aborting due to 8 previous errors
+
+Some errors have detailed explanations: E0384, E0597, E0621.
+For more information about an error, try `rustc --explain E0384`.
+++ /dev/null
-#![crate_type="lib"]
-#![no_std]
-#![feature(c_variadic)]
-// The tests in this file are similar to that of variadic-ffi-4, but this
-// one enables nll.
-#![feature(nll)]
-
-use core::ffi::VaList;
-
-pub unsafe extern "C" fn no_escape0<'a>(_: usize, ap: ...) -> VaList<'a> {
- ap //~ ERROR: explicit lifetime required
-}
-
-pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaList<'static> {
- ap //~ ERROR: explicit lifetime required
-}
-
-pub unsafe extern "C" fn no_escape2(_: usize, ap: ...) {
- let _ = ap.with_copy(|ap| { ap }); //~ ERROR: lifetime may not live long enough
-}
-
-pub unsafe extern "C" fn no_escape3(_: usize, ap0: &mut VaList, mut ap1: ...) {
- *ap0 = ap1; //~ ERROR: lifetime may not live long enough
-}
-
-pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaList, mut ap1: ...) {
- ap0 = &mut ap1;
- //~^ ERROR: lifetime may not live long enough
- //~^^ ERROR: lifetime may not live long enough
- //~^^^ ERROR: `ap1` does not live long enough
-}
+++ /dev/null
-error[E0621]: explicit lifetime required in the type of `ap`
- --> $DIR/variadic-ffi-5.rs:11:5
- |
-LL | pub unsafe extern "C" fn no_escape0<'a>(_: usize, ap: ...) -> VaList<'a> {
- | --- help: add explicit lifetime `'a` to the type of `ap`: `core::ffi::VaList<'a>`
-LL | ap
- | ^^ lifetime `'a` required
-
-error[E0621]: explicit lifetime required in the type of `ap`
- --> $DIR/variadic-ffi-5.rs:15:5
- |
-LL | pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaList<'static> {
- | --- help: add explicit lifetime `'static` to the type of `ap`: `core::ffi::VaList<'static>`
-LL | ap
- | ^^ lifetime `'static` required
-
-error: lifetime may not live long enough
- --> $DIR/variadic-ffi-5.rs:19:33
- |
-LL | let _ = ap.with_copy(|ap| { ap });
- | --- ^^ returning this value requires that `'1` must outlive `'2`
- | | |
- | | return type of closure is core::ffi::VaList<'2>
- | has type `core::ffi::VaList<'1>`
-
-error: lifetime may not live long enough
- --> $DIR/variadic-ffi-5.rs:23:5
- |
-LL | pub unsafe extern "C" fn no_escape3(_: usize, ap0: &mut VaList, mut ap1: ...) {
- | --- ------- has type `core::ffi::VaList<'1>`
- | |
- | has type `&mut core::ffi::VaList<'2>`
-LL | *ap0 = ap1;
- | ^^^^^^^^^^ assignment requires that `'1` must outlive `'2`
-
-error: lifetime may not live long enough
- --> $DIR/variadic-ffi-5.rs:27:5
- |
-LL | pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaList, mut ap1: ...) {
- | ------- ------- has type `core::ffi::VaList<'2>`
- | |
- | has type `&mut core::ffi::VaList<'1>`
-LL | ap0 = &mut ap1;
- | ^^^^^^^^^^^^^^ assignment requires that `'1` must outlive `'2`
-
-error: lifetime may not live long enough
- --> $DIR/variadic-ffi-5.rs:27:5
- |
-LL | pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaList, mut ap1: ...) {
- | ------- ------- has type `core::ffi::VaList<'1>`
- | |
- | has type `&mut core::ffi::VaList<'2>`
-LL | ap0 = &mut ap1;
- | ^^^^^^^^^^^^^^ assignment requires that `'1` must outlive `'2`
-
-error[E0597]: `ap1` does not live long enough
- --> $DIR/variadic-ffi-5.rs:27:11
- |
-LL | pub unsafe extern "C" fn no_escape4(_: usize, mut ap0: &mut VaList, mut ap1: ...) {
- | - let's call the lifetime of this reference `'1`
-LL | ap0 = &mut ap1;
- | ------^^^^^^^^
- | | |
- | | borrowed value does not live long enough
- | assignment requires that `ap1` is borrowed for `'1`
-...
-LL | }
- | - `ap1` dropped here while still borrowed
-
-error: aborting due to 7 previous errors
-
-Some errors have detailed explanations: E0597, E0621.
-For more information about an error, try `rustc --explain E0597`.
// ignore-musl
// ignore-cloudabi
// ignore-emscripten
-
+// ignore-sgx no dynamic libraries
#![crate_type = "cdylib"]
extern crate cdylib_dep;
--- /dev/null
+error[E0631]: type mismatch in closure arguments
+ --> $DIR/expect-fn-supply-fn.rs:30:5
+ |
+LL | with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {});
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---------------- found signature of `fn(for<'r> fn(&'r u32), _) -> _`
+ | |
+ | expected signature of `fn(fn(&'a u32), &i32) -> _`
+ |
+note: required by `with_closure_expecting_fn_with_free_region`
+ --> $DIR/expect-fn-supply-fn.rs:1:1
+ |
+LL | / fn with_closure_expecting_fn_with_free_region<F>(_: F)
+LL | | where F: for<'a> FnOnce(fn(&'a u32), &i32)
+LL | | {
+LL | | }
+ | |_^
+
+error[E0631]: type mismatch in closure arguments
+ --> $DIR/expect-fn-supply-fn.rs:37:5
+ |
+LL | with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {});
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------------------- found signature of `fn(fn(&'x u32), _) -> _`
+ | |
+ | expected signature of `fn(for<'r> fn(&'r u32), &i32) -> _`
+ |
+note: required by `with_closure_expecting_fn_with_bound_region`
+ --> $DIR/expect-fn-supply-fn.rs:6:1
+ |
+LL | / fn with_closure_expecting_fn_with_bound_region<F>(_: F)
+LL | | where F: FnOnce(fn(&u32), &i32)
+LL | | {
+LL | | }
+ | |_^
+
+error[E0631]: type mismatch in closure arguments
+ --> $DIR/expect-fn-supply-fn.rs:46:5
+ |
+LL | with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --------------- found signature of `for<'r> fn(fn(&'r u32), _) -> _`
+ | |
+ | expected signature of `fn(for<'r> fn(&'r u32), &i32) -> _`
+ |
+note: required by `with_closure_expecting_fn_with_bound_region`
+ --> $DIR/expect-fn-supply-fn.rs:6:1
+ |
+LL | / fn with_closure_expecting_fn_with_bound_region<F>(_: F)
+LL | | where F: FnOnce(fn(&u32), &i32)
+LL | | {
+LL | | }
+ | |_^
+
+error: aborting due to 3 previous errors
+
--- /dev/null
+error[E0621]: explicit lifetime required in the type of `x`
+ --> $DIR/closure-bounds-static-cant-capture-borrowed.rs:5:5
+ |
+LL | fn foo(x: &()) {
+ | --- help: add explicit lifetime `'static` to the type of `x`: `&'static ()`
+LL | / bar(|| {
+LL | |
+LL | | let _ = x;
+LL | | })
+ | |______^ lifetime `'static` required
+
+error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function
+ --> $DIR/closure-bounds-static-cant-capture-borrowed.rs:5:9
+ |
+LL | bar(|| {
+ | ^^ may outlive borrowed value `x`
+LL |
+LL | let _ = x;
+ | - `x` is borrowed here
+ |
+note: function requires argument type to outlive `'static`
+ --> $DIR/closure-bounds-static-cant-capture-borrowed.rs:5:5
+ |
+LL | / bar(|| {
+LL | |
+LL | | let _ = x;
+LL | | })
+ | |______^
+help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword
+ |
+LL | bar(move || {
+ | ^^^^^^^
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0373, E0621.
+For more information about an error, try `rustc --explain E0373`.
--- /dev/null
+error[E0521]: borrowed data escapes outside of closure
+ --> $DIR/expect-region-supply-region.rs:18:9
+ |
+LL | let mut f: Option<&u32> = None;
+ | ----- `f` is declared here, outside of the closure body
+LL | closure_expecting_bound(|x| {
+ | - `x` is a reference that is only valid in the closure body
+LL | f = Some(x);
+ | ^^^^^^^^^^^ `x` escapes the closure body here
+
+error[E0521]: borrowed data escapes outside of closure
+ --> $DIR/expect-region-supply-region.rs:28:9
+ |
+LL | let mut f: Option<&u32> = None;
+ | ----- `f` is declared here, outside of the closure body
+LL | closure_expecting_bound(|x: &u32| {
+ | - `x` is a reference that is only valid in the closure body
+LL | f = Some(x);
+ | ^^^^^^^^^^^ `x` escapes the closure body here
+
+error: lifetime may not live long enough
+ --> $DIR/expect-region-supply-region.rs:37:30
+ |
+LL | fn expect_bound_supply_named<'x>() {
+ | -- lifetime `'x` defined here
+...
+LL | closure_expecting_bound(|x: &'x u32| {
+ | ^ - let's call the lifetime of this reference `'1`
+ | |
+ | requires that `'1` must outlive `'x`
+
+error: lifetime may not live long enough
+ --> $DIR/expect-region-supply-region.rs:37:30
+ |
+LL | fn expect_bound_supply_named<'x>() {
+ | -- lifetime `'x` defined here
+...
+LL | closure_expecting_bound(|x: &'x u32| {
+ | ^ requires that `'x` must outlive `'static`
+
+error: aborting due to 4 previous errors
+
// compile-pass
-#![feature(nll)]
-
pub fn main() {
let y: &'static mut [u8; 0] = &mut [];
}
--- /dev/null
+error[E0005]: refutable pattern in function argument: `&[]` not covered
+ --> $DIR/const_let_refutable.rs:3:16
+ |
+LL | const fn slice([a, b]: &[i32]) -> i32 {
+ | ^^^^^^ pattern `&[]` not covered
+
+error[E0723]: can only call other `const fn` within a `const fn`, but `const std::ops::Add::add` is not stable as `const fn`
+ --> $DIR/const_let_refutable.rs:4:5
+ |
+LL | a + b
+ | ^^^^^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0381]: use of possibly uninitialized variable: `a`
+ --> $DIR/const_let_refutable.rs:4:5
+ |
+LL | a + b
+ | ^ use of possibly uninitialized `a`
+
+error[E0381]: use of possibly uninitialized variable: `b`
+ --> $DIR/const_let_refutable.rs:4:9
+ |
+LL | a + b
+ | ^ use of possibly uninitialized `b`
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0005, E0381, E0723.
+For more information about an error, try `rustc --explain E0005`.
-#![feature(nll)]
-
const FOO: Option<&[[u8; 3]]> = Some(&[*b"foo"]); //~ ERROR temporary value dropped while borrowed
use std::borrow::Cow;
error[E0716]: temporary value dropped while borrowed
- --> $DIR/issue-54224.rs:3:39
+ --> $DIR/issue-54224.rs:1:39
|
LL | const FOO: Option<&[[u8; 3]]> = Some(&[*b"foo"]);
| ------^^^^^^^^^-
| using this value as a constant requires that borrow lasts for `'static`
error[E0716]: temporary value dropped while borrowed
- --> $DIR/issue-54224.rs:11:57
+ --> $DIR/issue-54224.rs:9:57
|
LL | pub const Z: Cow<'static, [ [u8; 3] ]> = Cow::Borrowed(&[*b"ABC"]);
| ---------------^^^^^^^^^-
--- /dev/null
+error[E0493]: destructors cannot be evaluated at compile-time
+ --> $DIR/min_const_fn.rs:37:25
+ |
+LL | const fn into_inner(self) -> T { self.0 }
+ | ^^^^ constant functions cannot evaluate destructors
+
+error[E0723]: mutable references in const fn are unstable
+ --> $DIR/min_const_fn.rs:39:36
+ |
+LL | const fn get_mut(&mut self) -> &mut T { &mut self.0 }
+ | ^^^^^^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0493]: destructors cannot be evaluated at compile-time
+ --> $DIR/min_const_fn.rs:44:28
+ |
+LL | const fn into_inner_lt(self) -> T { self.0 }
+ | ^^^^ constant functions cannot evaluate destructors
+
+error[E0723]: mutable references in const fn are unstable
+ --> $DIR/min_const_fn.rs:46:42
+ |
+LL | const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 }
+ | ^^^^^^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0493]: destructors cannot be evaluated at compile-time
+ --> $DIR/min_const_fn.rs:51:27
+ |
+LL | const fn into_inner_s(self) -> T { self.0 }
+ | ^^^^ constant functions cannot evaluate destructors
+
+error[E0723]: mutable references in const fn are unstable
+ --> $DIR/min_const_fn.rs:53:38
+ |
+LL | const fn get_mut_s(&mut self) -> &mut T { &mut self.0 }
+ | ^^^^^^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0723]: mutable references in const fn are unstable
+ --> $DIR/min_const_fn.rs:58:39
+ |
+LL | const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 }
+ | ^^^^^^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
+ --> $DIR/min_const_fn.rs:76:16
+ |
+LL | const fn foo11<T: std::fmt::Display>(t: T) -> T { t }
+ | ^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
+ --> $DIR/min_const_fn.rs:78:18
+ |
+LL | const fn foo11_2<T: Send>(t: T) -> T { t }
+ | ^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0723]: only int, `bool` and `char` operations are stable in const fn
+ --> $DIR/min_const_fn.rs:80:33
+ |
+LL | const fn foo19(f: f32) -> f32 { f * 2.0 }
+ | ^^^^^^^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0723]: only int, `bool` and `char` operations are stable in const fn
+ --> $DIR/min_const_fn.rs:82:35
+ |
+LL | const fn foo19_2(f: f32) -> f32 { 2.0 - f }
+ | ^^^^^^^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0723]: only int and `bool` operations are stable in const fn
+ --> $DIR/min_const_fn.rs:84:35
+ |
+LL | const fn foo19_3(f: f32) -> f32 { -f }
+ | ^^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0723]: only int, `bool` and `char` operations are stable in const fn
+ --> $DIR/min_const_fn.rs:86:43
+ |
+LL | const fn foo19_4(f: f32, g: f32) -> f32 { f / g }
+ | ^^^^^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0723]: cannot access `static` items in const fn
+ --> $DIR/min_const_fn.rs:90:27
+ |
+LL | const fn foo25() -> u32 { BAR }
+ | ^^^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0723]: cannot access `static` items in const fn
+ --> $DIR/min_const_fn.rs:91:36
+ |
+LL | const fn foo26() -> &'static u32 { &BAR }
+ | ^^^^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0723]: casting pointers to ints is unstable in const fn
+ --> $DIR/min_const_fn.rs:92:42
+ |
+LL | const fn foo30(x: *const u32) -> usize { x as usize }
+ | ^^^^^^^^^^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0723]: casting pointers to ints is unstable in const fn
+ --> $DIR/min_const_fn.rs:94:63
+ |
+LL | const fn foo30_with_unsafe(x: *const u32) -> usize { unsafe { x as usize } }
+ | ^^^^^^^^^^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0723]: casting pointers to ints is unstable in const fn
+ --> $DIR/min_const_fn.rs:96:42
+ |
+LL | const fn foo30_2(x: *mut u32) -> usize { x as usize }
+ | ^^^^^^^^^^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0723]: casting pointers to ints is unstable in const fn
+ --> $DIR/min_const_fn.rs:98:63
+ |
+LL | const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } }
+ | ^^^^^^^^^^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0723]: `if`, `match`, `&&` and `||` are not stable in const fn
+ --> $DIR/min_const_fn.rs:100:38
+ |
+LL | const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } }
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0723]: `if`, `match`, `&&` and `||` are not stable in const fn
+ --> $DIR/min_const_fn.rs:102:29
+ |
+LL | const fn foo30_5(b: bool) { while b { } }
+ | ^^^^^^^^^^^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0723]: `if`, `match`, `&&` and `||` are not stable in const fn
+ --> $DIR/min_const_fn.rs:104:44
+ |
+LL | const fn foo36(a: bool, b: bool) -> bool { a && b }
+ | ^^^^^^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0723]: `if`, `match`, `&&` and `||` are not stable in const fn
+ --> $DIR/min_const_fn.rs:106:44
+ |
+LL | const fn foo37(a: bool, b: bool) -> bool { a || b }
+ | ^^^^^^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0723]: mutable references in const fn are unstable
+ --> $DIR/min_const_fn.rs:108:14
+ |
+LL | const fn inc(x: &mut i32) { *x += 1 }
+ | ^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
+ --> $DIR/min_const_fn.rs:113:6
+ |
+LL | impl<T: std::fmt::Debug> Foo<T> {
+ | ^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
+ --> $DIR/min_const_fn.rs:118:6
+ |
+LL | impl<T: std::fmt::Debug + Sized> Foo<T> {
+ | ^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
+ --> $DIR/min_const_fn.rs:123:6
+ |
+LL | impl<T: Sync + Sized> Foo<T> {
+ | ^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0723]: `impl Trait` in const fn is unstable
+ --> $DIR/min_const_fn.rs:129:24
+ |
+LL | const fn no_rpit2() -> AlanTuring<impl std::fmt::Debug> { AlanTuring(0) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
+ --> $DIR/min_const_fn.rs:131:34
+ |
+LL | const fn no_apit2(_x: AlanTuring<impl std::fmt::Debug>) {}
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
+ --> $DIR/min_const_fn.rs:133:22
+ |
+LL | const fn no_apit(_x: impl std::fmt::Debug) {}
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0723]: `impl Trait` in const fn is unstable
+ --> $DIR/min_const_fn.rs:134:23
+ |
+LL | const fn no_rpit() -> impl std::fmt::Debug {}
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
+ --> $DIR/min_const_fn.rs:135:23
+ |
+LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {}
+ | ^^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
+ --> $DIR/min_const_fn.rs:136:32
+ |
+LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0515]: cannot return reference to temporary value
+ --> $DIR/min_const_fn.rs:136:63
+ |
+LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
+ | ^--
+ | ||
+ | |temporary value created here
+ | returns a reference to data owned by the current function
+
+error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
+ --> $DIR/min_const_fn.rs:144:41
+ |
+LL | const fn really_no_traits_i_mean_it() { (&() as &std::fmt::Debug, ()).1 }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0723]: function pointers in const fn are unstable
+ --> $DIR/min_const_fn.rs:147:21
+ |
+LL | const fn no_fn_ptrs(_x: fn()) {}
+ | ^^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0723]: function pointers in const fn are unstable
+ --> $DIR/min_const_fn.rs:149:27
+ |
+LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo }
+ | ^^^^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error: aborting due to 37 previous errors
+
+Some errors have detailed explanations: E0515, E0723.
+For more information about an error, try `rustc --explain E0515`.
--- /dev/null
+error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
+ --> $DIR/min_const_fn_dyn.rs:9:5
+ |
+LL | x.0.field;
+ | ^^^^^^^^^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0723]: trait bounds other than `Sized` on const fn parameters are unstable
+ --> $DIR/min_const_fn_dyn.rs:12:66
+ |
+LL | const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) }
+ | ^^
+ |
+ = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
+ = help: add #![feature(const_fn)] to the crate attributes to enable
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/min_const_fn_dyn.rs:12:67
+ |
+LL | const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) }
+ | -^ - temporary value is freed at the end of this statement
+ | ||
+ | |creates a temporary which is freed while still in use
+ | cast requires that borrow lasts for `'static`
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0716, E0723.
+For more information about an error, try `rustc --explain E0716`.
//compile-pass
-#![feature(nll)]
-
fn main() {
let _: &'static usize = &(loop {}, 1).1;
// compile-pass
// aux-build:promotable_const_fn_lib.rs
-#![feature(nll)]
-
extern crate promotable_const_fn_lib;
use promotable_const_fn_lib::{foo, Foo};
// compile-pass
-#![feature(nll)]
-
fn main() {
let x: &'static u8 = &u8::max_value();
let x: &'static u16 = &u16::max_value();
--- /dev/null
+use std::alloc::Layout;
+
+// ok
+const LAYOUT_VALID: Layout = unsafe { Layout::from_size_align_unchecked(0x1000, 0x08) };
+
+// not ok, since alignment needs to be non-zero.
+const LAYOUT_INVALID: Layout = unsafe { Layout::from_size_align_unchecked(0x1000, 0x00) };
+//~^ ERROR it is undefined behavior to use this value
+
+fn main() {}
--- /dev/null
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/alloc.rs:7:1
+ |
+LL | const LAYOUT_INVALID: Layout = unsafe { Layout::from_size_align_unchecked(0x1000, 0x00) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0 at .align_, but expected something greater or equal to 1
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
--- /dev/null
+error[E0601]: `main` function not found in crate `continue_after_missing_main`
+ |
+ = note: consider adding a `main` function to `$DIR/continue-after-missing-main.rs`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0601`.
--- /dev/null
+error[E0005]: refutable pattern in local binding: `T(_, _)` not covered
+ --> $DIR/empty-never-array.rs:10:9
+ |
+LL | / enum Helper<T, U> {
+LL | | T(T, [!; 0]),
+LL | | #[allow(dead_code)]
+LL | | U(U),
+LL | | }
+ | |_- `Helper<T, U>` defined here
+...
+LL | let Helper::U(u) = Helper::T(t, []);
+ | ^^^^^^^^^^^^ pattern `T(_, _)` not covered
+
+error[E0381]: use of possibly uninitialized variable: `u`
+ --> $DIR/empty-never-array.rs:12:5
+ |
+LL | u
+ | ^ use of possibly uninitialized `u`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0005, E0381.
+For more information about an error, try `rustc --explain E0005`.
--- /dev/null
+error[E0502]: cannot borrow `*a` as mutable because it is also borrowed as immutable
+ --> $DIR/E0502.rs:4:9
+ |
+LL | let ref y = a;
+ | ----- immutable borrow occurs here
+LL | bar(a);
+ | ^ mutable borrow occurs here
+LL | y.use_ref();
+ | - immutable borrow later used here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0502`.
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/E0621-does-not-trigger-for-closures.rs:15:45
+ |
+LL | invoke(&x, |a, b| if a > b { a } else { b });
+ | -- ^ returning this value requires that `'1` must outlive `'2`
+ | ||
+ | |return type of closure is &'2 i32
+ | has type `&'1 i32`
+
+error: aborting due to previous error
+
--- /dev/null
+error: at least one trait must be specified
+ --> $DIR/generic_type_does_not_live_long_enough.rs:9:35
+ |
+LL | existential type WrongGeneric<T>: 'static;
+ | ^^^^^^^
+
+error[E0308]: mismatched types
+ --> $DIR/generic_type_does_not_live_long_enough.rs:6:18
+ |
+LL | let z: i32 = x;
+ | ^ expected i32, found opaque type
+ |
+ = note: expected type `i32`
+ found type `WrongGeneric::<&{integer}>`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
//~^ WARN unused attribute
#![path = "3800"] //~ WARN unused attribute
#![automatically_derived] //~ WARN unused attribute
-#![no_mangle] //~ WARN unused attribute
+#![no_mangle]
#![no_link] //~ WARN unused attribute
// see issue-43106-gating-of-derive.rs
#![should_panic] //~ WARN unused attribute
LL | #![automatically_derived]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
-warning: unused attribute
- --> $DIR/issue-43106-gating-of-builtin-attrs.rs:55:1
- |
-LL | #![no_mangle]
- | ^^^^^^^^^^^^^
-
warning: unused attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:56:1
|
--- /dev/null
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/auto-trait-regions.rs:44:24
+ |
+LL | let a = A(&mut true, &mut true, No);
+ | ^^^^ - temporary value is freed at the end of this statement
+ | |
+ | creates a temporary which is freed while still in use
+LL | yield;
+LL | assert_foo(a);
+ | - borrow later used here
+ |
+ = note: consider using a `let` binding to create a longer lived value
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/auto-trait-regions.rs:44:35
+ |
+LL | let a = A(&mut true, &mut true, No);
+ | ^^^^ - temporary value is freed at the end of this statement
+ | |
+ | creates a temporary which is freed while still in use
+LL | yield;
+LL | assert_foo(a);
+ | - borrow later used here
+ |
+ = note: consider using a `let` binding to create a longer lived value
+
+error: higher-ranked subtype error
+ --> $DIR/auto-trait-regions.rs:30:5
+ |
+LL | assert_foo(gen);
+ | ^^^^^^^^^^^^^^^
+
+error: higher-ranked subtype error
+ --> $DIR/auto-trait-regions.rs:48:5
+ |
+LL | assert_foo(gen);
+ | ^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0716`.
+++ /dev/null
-error[E0621]: explicit lifetime required in the type of `x`
- --> $DIR/generator-region-requirements.rs:16:51
- |
-LL | fn dangle(x: &mut i32) -> &'static mut i32 {
- | -------- help: add explicit lifetime `'static` to the type of `x`: `&'static mut i32`
-...
-LL | GeneratorState::Complete(c) => return c,
- | ^ lifetime `'static` required
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0621`.
-// revisions: migrate nll
-// ignore-compare-mode-nll
-
#![feature(generators, generator_trait)]
-#![cfg_attr(nll, feature(nll))]
use std::ops::{Generator, GeneratorState};
use std::pin::Pin;
loop {
match Pin::new(&mut g).resume() {
GeneratorState::Complete(c) => return c,
-//[nll]~^ ERROR explicit lifetime required
-//[migrate]~^^ ERROR explicit lifetime required
+ //~^ ERROR explicit lifetime required
GeneratorState::Yielded(_) => (),
}
}
--- /dev/null
+error[E0621]: explicit lifetime required in the type of `x`
+ --> $DIR/generator-region-requirements.rs:12:51
+ |
+LL | fn dangle(x: &mut i32) -> &'static mut i32 {
+ | -------- help: add explicit lifetime `'static` to the type of `x`: `&'static mut i32`
+...
+LL | GeneratorState::Complete(c) => return c,
+ | ^ lifetime `'static` required
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0621`.
#![feature(generators)]
-#![feature(nll)]
fn main() {
|| {
error[E0626]: borrow may still be in use when generator yields
- --> $DIR/generator-with-nll.rs:8:17
+ --> $DIR/generator-with-nll.rs:7:17
|
LL | let b = &mut true;
| ^^^^^^^^^
--- /dev/null
+error[E0502]: cannot borrow `my_stuff` as mutable because it is also borrowed as immutable
+ --> $DIR/hashmap-iter-value-lifetime.rs:7:5
+ |
+LL | let (_, thing) = my_stuff.iter().next().unwrap();
+ | -------- immutable borrow occurs here
+LL |
+LL | my_stuff.clear();
+ | ^^^^^^^^ mutable borrow occurs here
+LL |
+LL | println!("{}", *thing);
+ | ------ immutable borrow later used here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0502`.
--- /dev/null
+error[E0502]: cannot borrow `my_stuff` as mutable because it is also borrowed as immutable
+ --> $DIR/hashmap-lifetimes.rs:6:5
+ |
+LL | let mut it = my_stuff.iter();
+ | -------- immutable borrow occurs here
+LL | my_stuff.insert(1, 43);
+ | ^^^^^^^^ mutable borrow occurs here
+LL | it;
+ | -- immutable borrow later used here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0502`.
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/hr-subtype.rs:33:13
+ |
+LL | fn subtype<'x,'y:'x,'z:'y>() {
+ | -- -- lifetime `'y` defined here
+ | |
+ | lifetime `'x` defined here
+LL | gimme::<$t2>(None::<$t1>);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'x` must outlive `'y`
+...
+LL | / check! { free_inv_x_vs_free_inv_y: (fn(Inv<'x>),
+LL | | fn(Inv<'y>)) }
+ | |__________________________________________________- in this macro invocation
+
+error: lifetime may not live long enough
+ --> $DIR/hr-subtype.rs:39:13
+ |
+LL | fn supertype<'x,'y:'x,'z:'y>() {
+ | -- -- lifetime `'y` defined here
+ | |
+ | lifetime `'x` defined here
+LL | gimme::<$t1>(None::<$t2>);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'x` must outlive `'y`
+...
+LL | / check! { free_inv_x_vs_free_inv_y: (fn(Inv<'x>),
+LL | | fn(Inv<'y>)) }
+ | |__________________________________________________- in this macro invocation
+
+error: aborting due to 2 previous errors
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/hr-subtype.rs:39:13
+ |
+LL | fn supertype<'x,'y:'x,'z:'y>() {
+ | -- -- lifetime `'y` defined here
+ | |
+ | lifetime `'x` defined here
+LL | gimme::<$t1>(None::<$t2>);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'x` must outlive `'y`
+...
+LL | / check! { free_x_vs_free_y: (fn(&'x u32),
+LL | | fn(&'y u32)) }
+ | |__________________________________________- in this macro invocation
+
+error: aborting due to previous error
+
--- /dev/null
+error: higher-ranked subtype error
+ --> $DIR/hrtb-cache-issue-54302.rs:19:5
+ |
+LL | assert_deserialize_owned::<&'static str>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
--- /dev/null
+warning: function cannot return without recursing
+ --> $DIR/hrtb-perfect-forwarding.rs:22:1
+ |
+LL | / fn no_hrtb<'b,T>(mut t: T)
+LL | | where T : Bar<&'b isize>
+LL | | {
+LL | | // OK -- `T : Bar<&'b isize>`, and thus the impl above ensures that
+LL | | // `&mut T : Bar<&'b isize>`.
+LL | | no_hrtb(&mut t);
+ | | --------------- recursive call site
+LL | | }
+ | |_^ cannot return without recursing
+ |
+ = note: #[warn(unconditional_recursion)] on by default
+ = help: a `loop` may express intention better if this is on purpose
+
+warning: function cannot return without recursing
+ --> $DIR/hrtb-perfect-forwarding.rs:30:1
+ |
+LL | / fn bar_hrtb<T>(mut t: T)
+LL | | where T : for<'b> Bar<&'b isize>
+LL | | {
+LL | | // OK -- `T : for<'b> Bar<&'b isize>`, and thus the impl above
+... |
+LL | | bar_hrtb(&mut t);
+ | | ---------------- recursive call site
+LL | | }
+ | |_^ cannot return without recursing
+ |
+ = help: a `loop` may express intention better if this is on purpose
+
+warning: function cannot return without recursing
+ --> $DIR/hrtb-perfect-forwarding.rs:39:1
+ |
+LL | / fn foo_hrtb_bar_not<'b,T>(mut t: T)
+LL | | where T : for<'a> Foo<&'a isize> + Bar<&'b isize>
+LL | | {
+LL | | // Not OK -- The forwarding impl for `Foo` requires that `Bar` also
+... |
+LL | | foo_hrtb_bar_not(&mut t);
+ | | ------------------------ recursive call site
+LL | | }
+ | |_^ cannot return without recursing
+ |
+ = help: a `loop` may express intention better if this is on purpose
+
+error: higher-ranked subtype error
+ --> $DIR/hrtb-perfect-forwarding.rs:46:5
+ |
+LL | foo_hrtb_bar_not(&mut t);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: lifetime may not live long enough
+ --> $DIR/hrtb-perfect-forwarding.rs:46:5
+ |
+LL | fn foo_hrtb_bar_not<'b,T>(mut t: T)
+ | -- lifetime `'b` defined here
+...
+LL | foo_hrtb_bar_not(&mut t);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'static`
+
+warning: function cannot return without recursing
+ --> $DIR/hrtb-perfect-forwarding.rs:49:1
+ |
+LL | / fn foo_hrtb_bar_hrtb<T>(mut t: T)
+LL | | where T : for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize>
+LL | | {
+LL | | // OK -- now we have `T : for<'b> Bar&'b isize>`.
+LL | | foo_hrtb_bar_hrtb(&mut t);
+ | | ------------------------- recursive call site
+LL | | }
+ | |_^ cannot return without recursing
+ |
+ = help: a `loop` may express intention better if this is on purpose
+
+error: aborting due to 2 previous errors
+
--- /dev/null
+error[E0521]: borrowed data escapes outside of function
+ --> $DIR/dyn-trait.rs:20:5
+ |
+LL | fn with_dyn_debug_static<'a>(x: Box<dyn Debug + 'a>) {
+ | - `x` is a reference that is only valid in the function body
+LL | static_val(x);
+ | ^^^^^^^^^^^^^ `x` escapes the function body here
+
+error: aborting due to previous error
+
-#![feature(nll)]
-
// Regression test for #54593: the MIR type checker was going wrong
// when a closure returns the `impl Copy` from its parent fn. It was
// (incorrectly) replacing the `impl Copy` in its return type with the
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/must_outlive_least_region_or_bound.rs:3:23
+ |
+LL | fn elided(x: &i32) -> impl Copy { x }
+ | - ^^^^^^^^^ opaque type requires that `'1` must outlive `'static`
+ | |
+ | let's call the lifetime of this reference `'1`
+help: to allow this impl Trait to capture borrowed data with lifetime `'1`, add `'_` as a constraint
+ |
+LL | fn elided(x: &i32) -> impl Copy + '_ { x }
+ | ^^^^^^^^^^^^^^
+
+error: lifetime may not live long enough
+ --> $DIR/must_outlive_least_region_or_bound.rs:6:32
+ |
+LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x }
+ | -- ^^^^^^^^^ opaque type requires that `'a` must outlive `'static`
+ | |
+ | lifetime `'a` defined here
+help: to allow this impl Trait to capture borrowed data with lifetime `'a`, add `'a` as a constraint
+ |
+LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x }
+ | ^^^^^^^^^^^^^^
+
+error: lifetime may not live long enough
+ --> $DIR/must_outlive_least_region_or_bound.rs:12:69
+ |
+LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
+ | -- lifetime `'a` defined here ^ returning this value requires that `'a` must outlive `'static`
+ |
+ = help: consider replacing `'a` with `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/must_outlive_least_region_or_bound.rs:17:61
+ |
+LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) {
+ | -- -- lifetime `'b` defined here ^^^^^^^^^^^^^^^^ opaque type requires that `'b` must outlive `'a`
+ | |
+ | lifetime `'a` defined here
+
+error[E0310]: the parameter type `T` may not live long enough
+ --> $DIR/must_outlive_least_region_or_bound.rs:22:51
+ |
+LL | fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static {
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider adding an explicit lifetime bound `T: 'static`...
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0310`.
#![allow(dead_code)]
#![feature(in_band_lifetimes)]
-#![feature(nll)]
fn foo(x: &'x u32) -> impl Fn() -> &'y u32
where 'x: 'y
#![allow(dead_code)]
#![feature(in_band_lifetimes)]
-#![feature(nll)]
trait Trait<'a> { }
#![allow(dead_code)]
#![feature(in_band_lifetimes)]
-#![feature(nll)]
use std::cell::Cell;
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
- --> $DIR/region-escape-via-bound.rs:16:29
+ --> $DIR/region-escape-via-bound.rs:15:29
|
LL | fn foo(x: Cell<&'x u32>) -> impl Trait<'y>
| ^^^^^^^^^^^^^^
|
-note: hidden type `std::cell::Cell<&'x u32>` captures the lifetime 'x as defined on the function body at 18:7
- --> $DIR/region-escape-via-bound.rs:18:7
+note: hidden type `std::cell::Cell<&'x u32>` captures the lifetime 'x as defined on the function body at 17:7
+ --> $DIR/region-escape-via-bound.rs:17:7
|
LL | where 'x: 'y
| ^^
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/static-return-lifetime-infered.rs:6:35
+ |
+LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
+ | - ^^^^^^^^^^^^^^^^^^^^^^^ opaque type requires that `'1` must outlive `'static`
+ | |
+ | let's call the lifetime of this reference `'1`
+help: to allow this impl Trait to capture borrowed data with lifetime `'1`, add `'_` as a constraint
+ |
+LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> + '_ {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: lifetime may not live long enough
+ --> $DIR/static-return-lifetime-infered.rs:10:37
+ |
+LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
+ | -- ^^^^^^^^^^^^^^^^^^^^^^^ opaque type requires that `'a` must outlive `'static`
+ | |
+ | lifetime `'a` defined here
+help: to allow this impl Trait to capture borrowed data with lifetime `'a`, add `'a` as a constraint
+ |
+LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> + 'a {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
--- /dev/null
+error[E0310]: the parameter type `T` may not live long enough
+ --> $DIR/type_parameters_captured.rs:7:20
+ |
+LL | fn foo<T>(x: T) -> impl Any + 'static {
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider adding an explicit lifetime bound `T: 'static`...
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0310`.
#![deny(unused_extern_crates)]
-extern crate core as iso1; //~ ERROR `extern crate` is not idiomatic in the new edition
-extern crate core as iso2; //~ ERROR `extern crate` is not idiomatic in the new edition
-extern crate core as iso3; //~ ERROR `extern crate` is not idiomatic in the new edition
-extern crate core as iso4; //~ ERROR `extern crate` is not idiomatic in the new edition
+// Shouldn't suggest changing to `use`, as new name
+// would no longer be added to the prelude which could cause
+// compilation errors for imports that use the new name in
+// other modules. See #57672.
+extern crate core as iso1;
+extern crate core as iso2;
+extern crate core as iso3;
+extern crate core as iso4;
// Doesn't introduce its extern prelude entry, so it's still considered unused.
extern crate core; //~ ERROR unused extern crate
-error: `extern crate` is not idiomatic in the new edition
- --> $DIR/extern-crate-used.rs:8:1
+error: unused extern crate
+ --> $DIR/extern-crate-used.rs:18:1
|
-LL | extern crate core as iso1;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `use`
+LL | extern crate core;
+ | ^^^^^^^^^^^^^^^^^^ help: remove it
|
note: lint level defined here
--> $DIR/extern-crate-used.rs:6:9
LL | #![deny(unused_extern_crates)]
| ^^^^^^^^^^^^^^^^^^^^
-error: `extern crate` is not idiomatic in the new edition
- --> $DIR/extern-crate-used.rs:9:1
- |
-LL | extern crate core as iso2;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `use`
-
-error: `extern crate` is not idiomatic in the new edition
- --> $DIR/extern-crate-used.rs:10:1
- |
-LL | extern crate core as iso3;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `use`
-
-error: `extern crate` is not idiomatic in the new edition
- --> $DIR/extern-crate-used.rs:11:1
- |
-LL | extern crate core as iso4;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `use`
-
-error: unused extern crate
- --> $DIR/extern-crate-used.rs:14:1
- |
-LL | extern crate core;
- | ^^^^^^^^^^^^^^^^^^ help: remove it
-
-error: aborting due to 5 previous errors
+error: aborting due to previous error
--- /dev/null
+error[E0621]: explicit lifetime required in the type of `y`
+ --> $DIR/mismatched.rs:4:42
+ |
+LL | fn foo(x: &'a u32, y: &u32) -> &'a u32 { y }
+ | ---- ^ lifetime `'a` required
+ | |
+ | help: add explicit lifetime `'a` to the type of `y`: `&'a u32`
+
+error: lifetime may not live long enough
+ --> $DIR/mismatched.rs:6:46
+ |
+LL | fn foo2(x: &'a u32, y: &'b u32) -> &'a u32 { y }
+ | -- -- ^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
+ | | |
+ | | lifetime `'b` defined here
+ | lifetime `'a` defined here
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0621`.
--- /dev/null
+error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 'a in generic type due to conflicting requirements
+ --> $DIR/mismatched_trait_impl.rs:9:5
+ |
+LL | fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the method body at 9:5...
+ --> $DIR/mismatched_trait_impl.rs:9:5
+ |
+LL | / fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 {
+LL | | x
+LL | | }
+ | |_____^
+note: ...but the lifetime must also be valid for the lifetime 'a as defined on the method body at 9:32...
+ --> $DIR/mismatched_trait_impl.rs:9:32
+ |
+LL | fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 {
+ | ^^
+ = note: ...so that the method type is compatible with trait:
+ expected fn(&i32, &'a u32, &u32) -> &'a u32
+ found fn(&i32, &u32, &u32) -> &u32
+
+error: aborting due to previous error
+
--- /dev/null
+// ignore-tidy-linelength
+
+#![deny(warnings)]
+
+struct Borked {}
+
+impl Borked {
+ fn a(&self) {}
+}
+
+fn run_wild<T>(b: &Borked) {
+ b.a::<'_, T>();
+ //~^ ERROR cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+ //~^^ ERROR wrong number of type arguments: expected 0, found 1
+ //~^^^ WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+}
+
+fn main() {}
--- /dev/null
+error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+ --> $DIR/issue-60622.rs:12:11
+ |
+LL | fn a(&self) {}
+ | - the late bound lifetime parameter is introduced here
+...
+LL | b.a::<'_, T>();
+ | ^^
+ |
+note: lint level defined here
+ --> $DIR/issue-60622.rs:3:9
+ |
+LL | #![deny(warnings)]
+ | ^^^^^^^^
+ = note: #[deny(late_bound_lifetime_arguments)] implied by #[deny(warnings)]
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #42868 <https://github.com/rust-lang/rust/issues/42868>
+
+error[E0107]: wrong number of type arguments: expected 0, found 1
+ --> $DIR/issue-60622.rs:12:15
+ |
+LL | b.a::<'_, T>();
+ | ^ unexpected type argument
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0107`.
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/issue-10291.rs:3:9
+ |
+LL | fn test<'x>(x: &'x isize) {
+ | -- lifetime `'x` defined here
+LL | drop::<Box<for<'z> FnMut(&'z isize) -> &'z isize>>(Box::new(|z| {
+LL | x
+ | ^ returning this value requires that `'x` must outlive `'static`
+
+error: aborting due to previous error
+
--- /dev/null
+error[E0621]: explicit lifetime required in the type of `cont`
+ --> $DIR/issue-13058.rs:14:21
+ |
+LL | fn check<'r, I: Iterator<Item=usize>, T: Itble<'r, usize, I>>(cont: &T) -> bool
+ | -- help: add explicit lifetime `'r` to the type of `cont`: `&'r T`
+LL | {
+LL | let cont_iter = cont.iter();
+ | ^^^^^^^^^^^ lifetime `'r` required
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0621`.
--- /dev/null
+error[E0621]: explicit lifetime required in the type of `lexer`
+ --> $DIR/issue-15034.rs:17:9
+ |
+LL | pub fn new(lexer: &'a mut Lexer) -> Parser<'a> {
+ | ------------- help: add explicit lifetime `'a` to the type of `lexer`: `&'a mut Lexer<'a>`
+LL | Parser { lexer: lexer }
+ | ^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'a` required
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0621`.
--- /dev/null
+error[E0005]: refutable pattern in `for` loop binding: `&[]` not covered
+ --> $DIR/issue-15381.rs:4:9
+ |
+LL | for &[x,y,z] in values.chunks(3).filter(|&xs| xs.len() == 3) {
+ | ^^^^^^^^ pattern `&[]` not covered
+
+error[E0381]: borrow of possibly uninitialized variable: `y`
+ --> $DIR/issue-15381.rs:6:26
+ |
+LL | println!("y={}", y);
+ | ^ use of possibly uninitialized `y`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0005, E0381.
+For more information about an error, try `rustc --explain E0005`.
--- /dev/null
+error[E0521]: borrowed data escapes outside of function
+ --> $DIR/issue-16683.rs:4:9
+ |
+LL | fn b(&self) {
+ | ----- `self` is a reference that is only valid in the function body
+LL | self.a();
+ | ^^^^^^^^ `self` escapes the function body here
+
+error: aborting due to previous error
+
--- /dev/null
+error[E0308]: match arms have incompatible types
+ --> $DIR/issue-17728.rs:109:14
+ |
+LL | / match to_parse {
+LL | | "w" | "west" => RoomDirection::West,
+LL | | "e" | "east" => RoomDirection::East,
+LL | | "n" | "north" => RoomDirection::North,
+... |
+LL | | "down" => RoomDirection::Down,
+ | | ------------------- this and all prior arms are found to be of type `RoomDirection`
+LL | | _ => None
+ | | ^^^^ expected enum `RoomDirection`, found enum `std::option::Option`
+LL | | }
+ | |_____- `match` arms have incompatible types
+ |
+ = note: expected type `RoomDirection`
+ found type `std::option::Option<_>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
--- /dev/null
+error[E0521]: borrowed data escapes outside of function
+ --> $DIR/issue-17758.rs:7:9
+ |
+LL | fn bar(&self) {
+ | ----- `self` is a reference that is only valid in the function body
+LL | self.foo();
+ | ^^^^^^^^^^ `self` escapes the function body here
+
+error: aborting due to previous error
+
// ignore-cloudabi no processes
// ignore-emscripten no processes
+// ignore-sgx no processes
#![feature(os)]
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/issue-26217.rs:4:5
+ |
+LL | fn bar<'a>() {
+ | -- lifetime `'a` defined here
+LL | foo::<&'a i32>();
+ | ^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/issue-28848.rs:10:5
+ |
+LL | pub fn foo<'a, 'b>(u: &'b ()) -> &'a () {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | Foo::<'a, 'b>::xmute(u)
+ | ^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'a`
+
+error: aborting due to previous error
+
LL | Err(5)?;
| ^ the trait `std::convert::From<{integer}>` is not implemented for `()`
|
+ = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
= note: required by `std::convert::From::from`
error: aborting due to previous error
-#![feature(nll)]
-
pub trait Foo {
fn zero(self) -> Self;
}
error[E0382]: use of moved value: `x`
- --> $DIR/issue-34721.rs:27:9
+ --> $DIR/issue-34721.rs:25:9
|
LL | pub fn baz<T: Foo>(x: T) -> T {
| - - move occurs because `x` has type `T`, which does not implement the `Copy` trait
// ignore-windows
// ignore-cloudabi
// ignore-emscripten
+// ignore-sgx no processes
use std::process::Command;
// use std::os::unix::process::CommandExt;
error[E0599]: no method named `exec` found for type `&mut std::process::Command` in the current scope
- --> $DIR/issue-39175.rs:14:39
+ --> $DIR/issue-39175.rs:15:39
|
LL | Command::new("echo").arg("hello").exec();
| ^^^^
--- /dev/null
+error: captured variable cannot escape `FnMut` closure body
+ --> $DIR/issue-40510-1.rs:11:9
+ |
+LL | || {
+ | - inferred to be a `FnMut` closure
+LL | &mut x
+ | ^^^^^^ returns a reference to a captured variable which escapes the closure body
+ |
+ = note: `FnMut` closures only have access to their captured variables while they are executing...
+ = note: ...therefore, they cannot allow references to captured variables to escape
+
+error: aborting due to previous error
+
--- /dev/null
+warning: captured variable cannot escape `FnMut` closure body
+ --> $DIR/issue-40510-1.rs:11:9
+ |
+LL | || {
+ | - inferred to be a `FnMut` closure
+LL | &mut x
+ | ^^^^^^ returns a reference to a captured variable which escapes the closure body
+ |
+ = note: `FnMut` closures only have access to their captured variables while they are executing...
+ = note: ...therefore, they cannot allow references to captured variables to escape
+ = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
+ = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
+
+error: compilation successful
+ --> $DIR/issue-40510-1.rs:20:1
+ |
+LL | fn main() {}
+ | ^^^^^^^^^^^^
+
+error: aborting due to previous error
+
--- /dev/null
+error: captured variable cannot escape `FnMut` closure body
+ --> $DIR/issue-40510-1.rs:11:9
+ |
+LL | || {
+ | - inferred to be a `FnMut` closure
+LL | &mut x
+ | ^^^^^^ returns a reference to a captured variable which escapes the closure body
+ |
+ = note: `FnMut` closures only have access to their captured variables while they are executing...
+ = note: ...therefore, they cannot allow references to captured variables to escape
+
+error: aborting due to previous error
+
-// compile-pass
+#![feature(rustc_attrs)]
#![allow(unused)]
+// revisions: migrate nll
+#![cfg_attr(nll, feature(nll))]
+
fn f() {
let mut x: Box<()> = Box::new(());
|| {
&mut x
};
+ //[migrate]~^^ WARNING captured variable cannot escape `FnMut` closure body
+ //[migrate]~| WARNING this error has been downgraded to a warning
+ //[migrate]~| WARNING this warning will become a hard error in the future
+ //[nll]~^^^^^ ERROR captured variable cannot escape `FnMut` closure body
}
-
+#[rustc_error]
fn main() {}
+//[migrate]~^ ERROR
+++ /dev/null
-warning: captured variable cannot escape `FnMut` closure body
- --> $DIR/issue-40510-1.rs:8:9
- |
-LL | || {
- | - inferred to be a `FnMut` closure
-LL | &mut x
- | ^^^^^^ returns a reference to a captured variable which escapes the closure body
- |
- = note: `FnMut` closures only have access to their captured variables while they are executing...
- = note: ...therefore, they cannot allow references to captured variables to escape
- = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
- = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
-
--- /dev/null
+error: captured variable cannot escape `FnMut` closure body
+ --> $DIR/issue-40510-3.rs:11:9
+ |
+LL | || {
+ | - inferred to be a `FnMut` closure
+LL | / || {
+LL | | x.push(())
+LL | | }
+ | |_________^ returns a closure that contains a reference to a captured variable, which then escapes the closure body
+ |
+ = note: `FnMut` closures only have access to their captured variables while they are executing...
+ = note: ...therefore, they cannot allow references to captured variables to escape
+
+error: aborting due to previous error
+
--- /dev/null
+warning: captured variable cannot escape `FnMut` closure body
+ --> $DIR/issue-40510-3.rs:11:9
+ |
+LL | || {
+ | - inferred to be a `FnMut` closure
+LL | / || {
+LL | | x.push(())
+LL | | }
+ | |_________^ returns a closure that contains a reference to a captured variable, which then escapes the closure body
+ |
+ = note: `FnMut` closures only have access to their captured variables while they are executing...
+ = note: ...therefore, they cannot allow references to captured variables to escape
+ = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
+ = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
+
+error: compilation successful
+ --> $DIR/issue-40510-3.rs:22:1
+ |
+LL | fn main() {}
+ | ^^^^^^^^^^^^
+
+error: aborting due to previous error
+
--- /dev/null
+error: captured variable cannot escape `FnMut` closure body
+ --> $DIR/issue-40510-3.rs:11:9
+ |
+LL | || {
+ | - inferred to be a `FnMut` closure
+LL | / || {
+LL | | x.push(())
+LL | | }
+ | |_________^ returns a closure that contains a reference to a captured variable, which then escapes the closure body
+ |
+ = note: `FnMut` closures only have access to their captured variables while they are executing...
+ = note: ...therefore, they cannot allow references to captured variables to escape
+
+error: aborting due to previous error
+
-// compile-pass
+#![feature(rustc_attrs)]
#![allow(unused)]
+// revisions: migrate nll
+#![cfg_attr(nll, feature(nll))]
+
fn f() {
let mut x: Vec<()> = Vec::new();
|| {
x.push(())
}
+ //[migrate]~^^^ WARNING captured variable cannot escape `FnMut` closure body
+ //[migrate]~| WARNING this error has been downgraded to a warning
+ //[migrate]~| WARNING this warning will become a hard error in the future
+ //[nll]~^^^^^^ ERROR captured variable cannot escape `FnMut` closure body
};
}
-
+#[rustc_error]
fn main() {}
+//[migrate]~^ ERROR
+++ /dev/null
-warning: captured variable cannot escape `FnMut` closure body
- --> $DIR/issue-40510-3.rs:8:9
- |
-LL | || {
- | - inferred to be a `FnMut` closure
-LL | / || {
-LL | | x.push(())
-LL | | }
- | |_________^ returns a closure that contains a reference to a captured variable, which then escapes the closure body
- |
- = note: `FnMut` closures only have access to their captured variables while they are executing...
- = note: ...therefore, they cannot allow references to captured variables to escape
- = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
- = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
-
impl<X> Trait1<Box<X>> for A {
//~^ ERROR conflicting implementations of trait
-//~| hard error
//~| downstream crates may implement trait `Trait2<std::boxed::Box<_>>` for type `A`
type Output = i32;
}
-error: conflicting implementations of trait `Trait1<std::boxed::Box<_>>` for type `A`: (E0119)
+error[E0119]: conflicting implementations of trait `Trait1<std::boxed::Box<_>>` for type `A`:
--> $DIR/issue-43355.rs:13:1
|
LL | impl<X, T> Trait1<X> for T where T: Trait2<X> {
LL | impl<X> Trait1<Box<X>> for A {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `A`
|
- = note: #[deny(incoherent_fundamental_impls)] on by default
- = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
- = note: for more information, see issue #46205 <https://github.com/rust-lang/rust/issues/46205>
= note: downstream crates may implement trait `Trait2<std::boxed::Box<_>>` for type `A`
error: aborting due to previous error
+For more information about this error, try `rustc --explain E0119`.
// We will explicitly test NLL, and migration modes; thus we will also skip the
// automated compare-mode=nll.
-// revisions: nll migrate
-// ignore-compare-mode-nll
-
-#![cfg_attr(nll, feature(nll))]
-
// run-pass
// This test has structs and functions that are by definition unusable
// Issue 46036: [NLL] false edges on infinite loops
// Infinite loops should create false edges to the cleanup block.
-#![feature(nll)]
struct Foo { x: &'static u32 }
error[E0597]: `a` does not live long enough
- --> $DIR/issue-46036.rs:9:24
+ --> $DIR/issue-46036.rs:8:24
|
LL | let foo = Foo { x: &a };
| ^^
-#![feature(nll)]
-
fn foo(x: &u32) -> &'static u32 {
&*x
//~^ ERROR explicit lifetime required in the type of `x` [E0621]
error[E0621]: explicit lifetime required in the type of `x`
- --> $DIR/issue-46983.rs:4:5
+ --> $DIR/issue-46983.rs:2:5
|
LL | fn foo(x: &u32) -> &'static u32 {
| ---- help: add explicit lifetime `'static` to the type of `x`: `&'static u32`
-#![feature(nll)]
-
fn main() {
let _vec: Vec<&'static String> = vec![&String::new()];
//~^ ERROR temporary value dropped while borrowed [E0716]
error[E0716]: temporary value dropped while borrowed
- --> $DIR/issue-47184.rs:4:44
+ --> $DIR/issue-47184.rs:2:44
|
LL | let _vec: Vec<&'static String> = vec![&String::new()];
| -------------------- ^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
LL | let _a = b + ", World!";
| - ^ ---------- &str
| | |
- | | `+` can't be used to concatenate two `&str` strings
+ | | `+` cannot be used to concatenate two `&str` strings
| &str
help: `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left
|
LL | println!("🦀🦀🦀🦀🦀"); let _a = b + ", World!";
| - ^ ---------- &str
| | |
- | | `+` can't be used to concatenate two `&str` strings
+ | | `+` cannot be used to concatenate two `&str` strings
| &str
help: `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left
|
-#![allow(warnings)]
-#![feature(nll)]
-
use std::collections::BinaryHeap;
fn main() {
error[E0502]: cannot borrow `heap` as immutable because it is also borrowed as mutable
- --> $DIR/issue-47646.rs:12:30
+ --> $DIR/issue-47646.rs:9:30
|
LL | let borrow = heap.peek_mut();
| ---- mutable borrow occurs here
// compile-pass
-#![allow(dead_code)]
-#![feature(nll)]
struct AtomicRefMut<'a> {
value: &'a mut i32,
// compile-pass
-#![allow(dead_code)]
-#![feature(nll)]
struct WithDrop;
// compile-pass
-#![allow(dead_code)]
-#![feature(nll)]
struct MyStruct<'a> {
field: &'a mut (),
// compile-pass
-#![allow(dead_code)]
// Tests that automatic coercions from &mut T to *mut T
// allow borrows of T to expire immediately - essentially, that
// they work identically to 'foo as *mut T'
-#![feature(nll)]
struct SelfReference {
self_reference: *mut SelfReference,
// compile-pass
-#![allow(dead_code)]
#![allow(non_upper_case_globals)]
-#![feature(nll)]
-
static mut x: &'static u32 = &0;
fn foo() {
// run-pass
-#![feature(nll)]
-#![allow(warnings)]
-
struct Inner<I, V> {
iterator: I,
item: V,
// run-pass
-#![feature(nll)]
-#![allow(warnings)]
-
pub struct Container<T: Iterator> {
value: Option<T::Item>,
}
-#![feature(nll)]
-
fn flatten<'a, 'b, T>(x: &'a &'b T) -> &'a T {
x
}
error[E0506]: cannot assign to `x` because it is borrowed
- --> $DIR/issue-48803.rs:12:5
+ --> $DIR/issue-48803.rs:10:5
|
LL | let y = &x;
| -- borrow of `x` occurs here
// compile-pass
// ignore-emscripten no i128 support
-#![feature(nll)]
-
fn fibs(n: u32) -> impl Iterator<Item=u128> {
(0 .. n)
.scan((0, 1), |st, _| {
--- /dev/null
+error: captured variable cannot escape `FnMut` closure body
+ --> $DIR/issue-49824.rs:10:9
+ |
+LL | || {
+ | - inferred to be a `FnMut` closure
+LL | / || {
+LL | |
+LL | |
+LL | |
+LL | | let _y = &mut x;
+LL | | }
+ | |_________^ returns a closure that contains a reference to a captured variable, which then escapes the closure body
+ |
+ = note: `FnMut` closures only have access to their captured variables while they are executing...
+ = note: ...therefore, they cannot allow references to captured variables to escape
+
+error: aborting due to previous error
+
-#![feature(nll)]
-
fn main() {
let foo = &16;
//~^ HELP consider changing this to be a mutable reference
error[E0594]: cannot assign to `*foo` which is behind a `&` reference
- --> $DIR/issue-51515.rs:7:5
+ --> $DIR/issue-51515.rs:5:5
|
LL | let foo = &16;
| --- help: consider changing this to be a mutable reference: `&mut 16`
| ^^^^^^^^^ `foo` is a `&` reference, so the data it refers to cannot be written
error[E0594]: cannot assign to `*bar` which is behind a `&` reference
- --> $DIR/issue-51515.rs:12:5
+ --> $DIR/issue-51515.rs:10:5
|
LL | let bar = foo;
| --- help: consider changing this to be a mutable reference: `&mut i32`
fn make_generator() {
let _gen = || foo.await; //~ ERROR `await` is only allowed inside `async` functions and blocks
}
+
+fn main() {}
--> $DIR/issue-51719.rs:10:19
|
LL | let _gen = || foo.await;
- | ^^^^^^^^^
+ | -- ^^^^^^^^^ only allowed inside `async` functions and blocks
+ | |
+ | this is not `async`
error: aborting due to previous error
error[E0728]: `await` is only allowed inside `async` functions and blocks
--> $DIR/issue-51751.rs:11:20
|
+LL | fn main() {
+ | ---- this is not `async`
+LL | let result = inc(10000);
LL | let finished = result.await;
- | ^^^^^^^^^^^^
+ | ^^^^^^^^^^^^ only allowed inside `async` functions and blocks
error: aborting due to previous error
//
// run-pass
-#![feature(nll)]
-
pub trait Parser {
type Input;
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/issue-52213.rs:3:20
+ |
+LL | fn transmute_lifetime<'a, 'b, T>(t: &'a (T,)) -> &'b T {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | match (&t,) {
+LL | ((u,),) => u,
+ | ^ returning this value requires that `'a` must outlive `'b`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/issue-52533-1.rs:9:18
+ |
+LL | gimme(|x, y| y)
+ | - - ^ closure was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ | | |
+ | | has type `&Foo<'_, '1, u32>`
+ | has type `&Foo<'_, '2, u32>`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/issue-52533.rs:5:16
+ |
+LL | foo(|a, b| b)
+ | - - ^ closure was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ | | |
+ | | has type `&'1 u32`
+ | has type `&'2 u32`
+
+error: aborting due to previous error
+
//
// compile-pass
-#![feature(nll)]
-
fn main() {}
fn fail<'a>() -> Struct<'a, Generic<()>> {
//
// compile-pass
-#![feature(nll)]
-#![allow(dead_code)]
-
trait Future {
type Item;
}
--- /dev/null
+error: higher-ranked subtype error
+ --> $DIR/issue-54302-cases.rs:63:5
+ |
+LL | <u32 as RefFoo<u32>>::ref_foo(a)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: higher-ranked subtype error
+ --> $DIR/issue-54302-cases.rs:69:5
+ |
+LL | <i32 as RefFoo<i32>>::ref_foo(a)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: higher-ranked subtype error
+ --> $DIR/issue-54302-cases.rs:75:5
+ |
+LL | <u64 as RefFoo<u64>>::ref_foo(a)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: higher-ranked subtype error
+ --> $DIR/issue-54302-cases.rs:81:5
+ |
+LL | <i64 as RefFoo<i64>>::ref_foo(a)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+
--- /dev/null
+error: higher-ranked subtype error
+ --> $DIR/issue-54302.rs:13:5
+ |
+LL | assert_deserialize_owned::<&'static str>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
-#![feature(nll)]
-
// This test is a minimal version of an ICE in the dropck-eyepatch tests
// found in the fix for #54943.
-#![feature(nll)]
-
// This test is a minimal version of an ICE in the dropck-eyepatch tests
// found in the fix for #54943. In particular, this test is in unreachable
// code as the initial fix for this ICE only worked if the code was reachable.
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/issue-54943.rs:6:13
+ |
+LL | fn boo<'a>() {
+ | -- lifetime `'a` defined here
+...
+LL | let x = foo::<&'a u32>();
+ | ^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
+
+error: aborting due to previous error
+
-#![feature(nll)]
-#![allow(warnings)]
-
fn foo<T: 'static>() { }
fn boo<'a>() {
return;
let x = foo::<&'a u32>();
- //~^ ERROR lifetime may not live long enough
+ //~^ ERROR
}
fn main() {}
-error: lifetime may not live long enough
- --> $DIR/issue-54943.rs:9:13
+error[E0477]: the type `&'a u32` does not fulfill the required lifetime
+ --> $DIR/issue-54943.rs:6:13
|
-LL | fn boo<'a>() {
- | -- lifetime `'a` defined here
-...
LL | let x = foo::<&'a u32>();
- | ^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
+ | ^^^^^^^^^^^^^^
+ |
+ = note: type must satisfy the static lifetime
error: aborting due to previous error
--- /dev/null
+error: higher-ranked subtype error
+ --> $DIR/issue-55731.rs:48:5
+ |
+LL | / multi(Map {
+LL | | i: Cloned(PhantomData),
+LL | | f: X,
+LL | | });
+ | |______^
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/issue-55796.rs:16:9
+ |
+LL | pub trait Graph<'a> {
+ | -- lifetime `'a` defined here
+...
+LL | Box::new(self.out_edges(u).map(|e| e.target()))
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/issue-55796.rs:21:9
+ |
+LL | pub trait Graph<'a> {
+ | -- lifetime `'a` defined here
+...
+LL | Box::new(self.in_edges(u).map(|e| e.target()))
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+
+error: aborting due to 2 previous errors
+
--- /dev/null
+error: higher-ranked subtype error
+ --> $DIR/issue-57843.rs:23:9
+ |
+LL | Foo(Box::new(|_| ()));
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
--- /dev/null
+error[E0277]: `T` cannot be sent between threads safely
+ --> $DIR/kindck-impl-type-params.rs:18:13
+ |
+LL | let a = &t as &Gettable<T>;
+ | ^^ `T` cannot be sent between threads safely
+ |
+ = help: the trait `std::marker::Send` is not implemented for `T`
+ = help: consider adding a `where T: std::marker::Send` bound
+ = note: required because of the requirements on the impl of `Gettable<T>` for `S<T>`
+ = note: required for the cast to the object type `dyn Gettable<T>`
+
+error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
+ --> $DIR/kindck-impl-type-params.rs:18:13
+ |
+LL | let a = &t as &Gettable<T>;
+ | ^^ the trait `std::marker::Copy` is not implemented for `T`
+ |
+ = help: consider adding a `where T: std::marker::Copy` bound
+ = note: required because of the requirements on the impl of `Gettable<T>` for `S<T>`
+ = note: required for the cast to the object type `dyn Gettable<T>`
+
+error[E0277]: `T` cannot be sent between threads safely
+ --> $DIR/kindck-impl-type-params.rs:25:27
+ |
+LL | let a: &Gettable<T> = &t;
+ | ^^ `T` cannot be sent between threads safely
+ |
+ = help: the trait `std::marker::Send` is not implemented for `T`
+ = help: consider adding a `where T: std::marker::Send` bound
+ = note: required because of the requirements on the impl of `Gettable<T>` for `S<T>`
+ = note: required for the cast to the object type `dyn Gettable<T>`
+
+error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
+ --> $DIR/kindck-impl-type-params.rs:25:27
+ |
+LL | let a: &Gettable<T> = &t;
+ | ^^ the trait `std::marker::Copy` is not implemented for `T`
+ |
+ = help: consider adding a `where T: std::marker::Copy` bound
+ = note: required because of the requirements on the impl of `Gettable<T>` for `S<T>`
+ = note: required for the cast to the object type `dyn Gettable<T>`
+
+error[E0277]: the trait bound `std::string::String: std::marker::Copy` is not satisfied
+ --> $DIR/kindck-impl-type-params.rs:38:13
+ |
+LL | let a = t as Box<Gettable<String>>;
+ | ^ the trait `std::marker::Copy` is not implemented for `std::string::String`
+ |
+ = note: required because of the requirements on the impl of `Gettable<std::string::String>` for `S<std::string::String>`
+ = note: required for the cast to the object type `dyn Gettable<std::string::String>`
+
+error[E0277]: the trait bound `foo3::Foo: std::marker::Copy` is not satisfied
+ --> $DIR/kindck-impl-type-params.rs:46:33
+ |
+LL | let a: Box<Gettable<Foo>> = t;
+ | ^ the trait `std::marker::Copy` is not implemented for `foo3::Foo`
+ |
+ = note: required because of the requirements on the impl of `Gettable<foo3::Foo>` for `S<foo3::Foo>`
+ = note: required for the cast to the object type `dyn Gettable<foo3::Foo>`
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
--- /dev/null
+error[E0277]: `(dyn Dummy + 'a)` cannot be shared between threads safely
+ --> $DIR/kindck-send-object1.rs:10:5
+ |
+LL | assert_send::<&'a Dummy>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be shared between threads safely
+ |
+ = help: the trait `std::marker::Sync` is not implemented for `(dyn Dummy + 'a)`
+ = note: required because of the requirements on the impl of `std::marker::Send` for `&'a (dyn Dummy + 'a)`
+note: required by `assert_send`
+ --> $DIR/kindck-send-object1.rs:5:1
+ |
+LL | fn assert_send<T:Send+'static>() { }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0277]: `(dyn Dummy + 'a)` cannot be sent between threads safely
+ --> $DIR/kindck-send-object1.rs:29:5
+ |
+LL | assert_send::<Box<Dummy+'a>>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be sent between threads safely
+ |
+ = help: the trait `std::marker::Send` is not implemented for `(dyn Dummy + 'a)`
+ = note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<(dyn Dummy + 'a)>`
+ = note: required because it appears within the type `std::boxed::Box<(dyn Dummy + 'a)>`
+note: required by `assert_send`
+ --> $DIR/kindck-send-object1.rs:5:1
+ |
+LL | fn assert_send<T:Send+'static>() { }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
--- /dev/null
+error[E0521]: borrowed data escapes outside of function
+ --> $DIR/lifetime-bound-will-change-warning.rs:34:5
+ |
+LL | fn test2<'a>(x: &'a Box<Fn()+'a>) {
+ | - `x` is a reference that is only valid in the function body
+LL | // but ref_obj will not, so warn.
+LL | ref_obj(x)
+ | ^^^^^^^^^^ `x` escapes the function body here
+
+error[E0521]: borrowed data escapes outside of function
+ --> $DIR/lifetime-bound-will-change-warning.rs:39:5
+ |
+LL | fn test2cc<'a>(x: &'a Box<Fn()+'a>) {
+ | - `x` is a reference that is only valid in the function body
+LL | // same as test2, but cross crate
+LL | lib::ref_obj(x)
+ | ^^^^^^^^^^^^^^^ `x` escapes the function body here
+
+error: aborting due to 2 previous errors
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/ex1-return-one-existing-name-if-else-using-impl.rs:11:20
+ |
+LL | fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32 {
+ | -- - let's call the lifetime of this reference `'1`
+ | |
+ | lifetime `'a` defined here
+LL |
+LL | if x > y { x } else { y }
+ | ^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/ex1-return-one-existing-name-return-type-is-anon.rs:8:5
+ |
+LL | fn foo<'a>(&self, x: &'a i32) -> &i32 {
+ | -- - let's call the lifetime of this reference `'1`
+ | |
+ | lifetime `'a` defined here
+LL |
+LL | x
+ | ^ function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/ex1-return-one-existing-name-self-is-anon.rs:8:30
+ |
+LL | fn foo<'a>(&self, x: &'a Foo) -> &'a Foo {
+ | -- - let's call the lifetime of this reference `'1`
+ | |
+ | lifetime `'a` defined here
+LL |
+LL | if true { x } else { self }
+ | ^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1`
+
+error: aborting due to previous error
+
--- /dev/null
+error[E0621]: explicit lifetime required in the type of `x`
+ --> $DIR/ex2a-push-one-existing-name-2.rs:6:5
+ |
+LL | fn foo<'a>(x: Ref<i32>, y: &mut Vec<Ref<'a, i32>>) {
+ | -------- help: add explicit lifetime `'a` to the type of `x`: `Ref<'a, i32>`
+LL | y.push(x);
+ | ^^^^^^^^^ lifetime `'a` required
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0621`.
--- /dev/null
+error[E0621]: explicit lifetime required in the type of `y`
+ --> $DIR/ex2a-push-one-existing-name-early-bound.rs:8:5
+ |
+LL | fn baz<'a, 'b, T>(x: &mut Vec<&'a T>, y: &T)
+ | -- help: add explicit lifetime `'a` to the type of `y`: `&'a T`
+...
+LL | x.push(y);
+ | ^^^^^^^^^ lifetime `'a` required
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0621`.
--- /dev/null
+error[E0621]: explicit lifetime required in the type of `y`
+ --> $DIR/ex2a-push-one-existing-name.rs:6:5
+ |
+LL | fn foo<'a>(x: &mut Vec<Ref<'a, i32>>, y: Ref<i32>) {
+ | -------- help: add explicit lifetime `'a` to the type of `y`: `Ref<'a, i32>`
+LL | x.push(y);
+ | ^^^^^^^^^ lifetime `'a` required
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0621`.
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/ex2b-push-no-existing-names.rs:6:5
+ |
+LL | fn foo(x: &mut Vec<Ref<i32>>, y: Ref<i32>) {
+ | - - has type `Ref<'1, i32>`
+ | |
+ | has type `&mut std::vec::Vec<Ref<'2, i32>>`
+LL | x.push(y);
+ | ^^^^^^^^^ argument requires that `'1` must outlive `'2`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/ex2c-push-inference-variable.rs:7:5
+ |
+LL | fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
+ | -- -- lifetime `'c` defined here
+ | |
+ | lifetime `'b` defined here
+LL | let z = Ref { data: y.data };
+LL | x.push(z);
+ | ^^^^^^^^^ argument requires that `'c` must outlive `'b`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/ex2d-push-inference-variable-2.rs:8:5
+ |
+LL | fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
+ | -- -- lifetime `'c` defined here
+ | |
+ | lifetime `'b` defined here
+...
+LL | a.push(b);
+ | ^^^^^^^^^ argument requires that `'c` must outlive `'b`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/ex2e-push-inference-variable-3.rs:8:5
+ |
+LL | fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
+ | -- -- lifetime `'c` defined here
+ | |
+ | lifetime `'b` defined here
+...
+LL | Vec::push(a, b);
+ | ^^^^^^^^^^^^^^^ argument requires that `'c` must outlive `'b`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-2.rs:2:5
+ |
+LL | fn foo(&mut (ref mut v, w): &mut (&u8, &u8), x: &u8) {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | *v = x;
+ | ^^^^^^ assignment requires that `'1` must outlive `'2`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-3.rs:2:5
+ |
+LL | fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | z.push((x,y));
+ | ^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
+
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-3.rs:2:5
+ |
+LL | fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | z.push((x,y));
+ | ^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
+
+error: aborting due to 2 previous errors
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-both-are-structs-2.rs:7:5
+ |
+LL | fn foo(mut x: Ref, y: Ref) {
+ | ----- - has type `Ref<'_, '1>`
+ | |
+ | has type `Ref<'_, '2>`
+LL | x.b = y.b;
+ | ^^^^^^^^^ assignment requires that `'1` must outlive `'2`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-both-are-structs-3.rs:7:5
+ |
+LL | fn foo(mut x: Ref) {
+ | -----
+ | |
+ | has type `Ref<'_, '1>`
+ | has type `Ref<'2, '_>`
+LL | x.a = x.b;
+ | ^^^^^^^^^ assignment requires that `'1` must outlive `'2`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-both-are-structs-earlybound-regions.rs:9:5
+ |
+LL | fn foo<'a, 'b>(mut x: Vec<Ref<'a>>, y: Ref<'b>)
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | x.push(y);
+ | ^^^^^^^^^ argument requires that `'b` must outlive `'a`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-both-are-structs-latebound-regions.rs:6:5
+ |
+LL | fn foo<'a, 'b>(mut x: Vec<Ref<'a>>, y: Ref<'b>) {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | x.push(y);
+ | ^^^^^^^^^ argument requires that `'b` must outlive `'a`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-both-are-structs.rs:6:5
+ |
+LL | fn foo(mut x: Vec<Ref>, y: Ref) {
+ | ----- - has type `Ref<'1>`
+ | |
+ | has type `std::vec::Vec<Ref<'2>>`
+LL | x.push(y);
+ | ^^^^^^^^^ argument requires that `'1` must outlive `'2`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-latebound-regions.rs:2:5
+ |
+LL | fn foo<'a,'b>(x: &mut Vec<&'a u8>, y: &'b u8) {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | x.push(y);
+ | ^^^^^^^^^ argument requires that `'b` must outlive `'a`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-one-is-struct-2.rs:4:5
+ |
+LL | fn foo(mut x: Ref, y: &u32) {
+ | ----- - let's call the lifetime of this reference `'2`
+ | |
+ | has type `Ref<'_, '1>`
+LL | y = x.b;
+ | ^^^^^^^ assignment requires that `'1` must outlive `'2`
+
+error[E0384]: cannot assign to immutable argument `y`
+ --> $DIR/ex3-both-anon-regions-one-is-struct-2.rs:4:5
+ |
+LL | fn foo(mut x: Ref, y: &u32) {
+ | - help: make this binding mutable: `mut y`
+LL | y = x.b;
+ | ^^^^^^^ cannot assign to immutable argument
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0384`.
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-one-is-struct-3.rs:4:5
+ |
+LL | fn foo(mut y: Ref, x: &u32) {
+ | ----- - let's call the lifetime of this reference `'1`
+ | |
+ | has type `Ref<'_, '2>`
+LL | y.b = x;
+ | ^^^^^^^ assignment requires that `'1` must outlive `'2`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-one-is-struct-4.rs:4:5
+ |
+LL | fn foo(mut y: Ref, x: &u32) {
+ | ----- - let's call the lifetime of this reference `'1`
+ | |
+ | has type `Ref<'_, '2>`
+LL | y.b = x;
+ | ^^^^^^^ assignment requires that `'1` must outlive `'2`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-one-is-struct.rs:7:5
+ |
+LL | fn foo(mut x: Ref, y: &u32) {
+ | ----- - let's call the lifetime of this reference `'1`
+ | |
+ | has type `Ref<'_, '2>`
+LL | x.b = y;
+ | ^^^^^^^ assignment requires that `'1` must outlive `'2`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-return-type-is-anon.rs:7:5
+ |
+LL | fn foo<'a>(&self, x: &i32) -> &i32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | x
+ | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-self-is-anon.rs:7:19
+ |
+LL | fn foo<'a>(&self, x: &Foo) -> &Foo {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | if true { x } else { self }
+ | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: aborting due to previous error
+
--- /dev/null
+error[E0596]: cannot borrow `y` as mutable, as it is not declared as mutable
+ --> $DIR/ex3-both-anon-regions-using-fn-items.rs:2:3
+ |
+LL | fn foo(x:fn(&u8, &u8), y: Vec<&u8>, z: &u8) {
+ | - help: consider changing this to be mutable: `mut y`
+LL | y.push(z);
+ | ^ cannot borrow as mutable
+
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-using-fn-items.rs:2:3
+ |
+LL | fn foo(x:fn(&u8, &u8), y: Vec<&u8>, z: &u8) {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | y.push(z);
+ | ^^^^^^^^^ argument requires that `'1` must outlive `'2`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0596`.
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-using-impl-items.rs:6:9
+ |
+LL | fn foo(x: &mut Vec<&u8>, y: &u8) {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | x.push(y);
+ | ^^^^^^^^^ argument requires that `'1` must outlive `'2`
+
+error: aborting due to previous error
+
--- /dev/null
+error[E0596]: cannot borrow `y` as mutable, as it is not declared as mutable
+ --> $DIR/ex3-both-anon-regions-using-trait-objects.rs:2:3
+ |
+LL | fn foo(x:Box<Fn(&u8, &u8)> , y: Vec<&u8>, z: &u8) {
+ | - help: consider changing this to be mutable: `mut y`
+LL | y.push(z);
+ | ^ cannot borrow as mutable
+
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-using-trait-objects.rs:2:3
+ |
+LL | fn foo(x:Box<Fn(&u8, &u8)> , y: Vec<&u8>, z: &u8) {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | y.push(z);
+ | ^^^^^^^^^ argument requires that `'1` must outlive `'2`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0596`.
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions.rs:2:5
+ |
+LL | fn foo(x: &mut Vec<&u8>, y: &u8) {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | x.push(y);
+ | ^^^^^^^^^ argument requires that `'1` must outlive `'2`
+
+error: aborting due to previous error
+
// FIXME https://github.com/rust-lang/rust/issues/59774
// normalize-stderr-test "thread.*panicked.*Metadata module not compiled.*\n" -> ""
// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> ""
+// ignore-sgx no weak linkages permitted
#![feature(linkage)]
error: must have type `*const T` or `*mut T`
- --> $DIR/linkage2.rs:8:32
+ --> $DIR/linkage2.rs:9:32
|
LL | #[linkage = "extern_weak"] static foo: i32;
| ^^^^^^^^^^^^^^^^
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/lub-if.rs:28:9
+ |
+LL | pub fn opt_str2<'a>(maybestr: &'a Option<String>) -> &'static str {
+ | -- lifetime `'a` defined here
+...
+LL | s
+ | ^ returning this value requires that `'a` must outlive `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/lub-if.rs:35:9
+ |
+LL | pub fn opt_str3<'a>(maybestr: &'a Option<String>) -> &'static str {
+ | -- lifetime `'a` defined here
+...
+LL | s
+ | ^ returning this value requires that `'a` must outlive `'static`
+
+error: aborting due to 2 previous errors
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/lub-match.rs:30:13
+ |
+LL | pub fn opt_str2<'a>(maybestr: &'a Option<String>) -> &'static str {
+ | -- lifetime `'a` defined here
+...
+LL | s
+ | ^ returning this value requires that `'a` must outlive `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/lub-match.rs:39:13
+ |
+LL | pub fn opt_str3<'a>(maybestr: &'a Option<String>) -> &'static str {
+ | -- lifetime `'a` defined here
+...
+LL | s
+ | ^ returning this value requires that `'a` must outlive `'static`
+
+error: aborting due to 2 previous errors
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/match-ref-mut-invariance.rs:10:9
+ |
+LL | impl<'b> S<'b> {
+ | -- lifetime `'b` defined here
+LL | fn bar<'a>(&'a mut self) -> &'a mut &'a i32 {
+ | -- lifetime `'a` defined here
+LL | match self.0 { ref mut x => x }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'b`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/match-ref-mut-let-invariance.rs:11:9
+ |
+LL | impl<'b> S<'b> {
+ | -- lifetime `'b` defined here
+LL | fn bar<'a>(&'a mut self) -> &'a mut &'a i32 {
+ | -- lifetime `'a` defined here
+LL | let ref mut x = self.0;
+LL | x
+ | ^ returning this value requires that `'a` must outlive `'b`
+
+error: aborting due to previous error
+
// General test of maybe_uninits state computed by MIR dataflow.
-#![feature(nll)]
#![feature(core_intrinsics, rustc_attrs)]
use std::intrinsics::rustc_peek;
error: rustc_peek: bit not set
- --> $DIR/def-inits-1.rs:15:14
+ --> $DIR/def-inits-1.rs:14:14
|
LL | unsafe { rustc_peek(&ret); }
| ^^^^^^^^^^^^^^^^
error: rustc_peek: bit not set
- --> $DIR/def-inits-1.rs:31:14
+ --> $DIR/def-inits-1.rs:30:14
|
LL | unsafe { rustc_peek(&z); }
| ^^^^^^^^^^^^^^
error: rustc_peek: bit not set
- --> $DIR/def-inits-1.rs:34:14
+ --> $DIR/def-inits-1.rs:33:14
|
LL | unsafe { rustc_peek(&y); }
| ^^^^^^^^^^^^^^
error: rustc_peek: bit not set
- --> $DIR/def-inits-1.rs:42:14
+ --> $DIR/def-inits-1.rs:41:14
|
LL | unsafe { rustc_peek(&x); }
| ^^^^^^^^^^^^^^
// General test of maybe_inits state computed by MIR dataflow.
-#![feature(nll)]
#![feature(core_intrinsics, rustc_attrs)]
use std::intrinsics::rustc_peek;
error: rustc_peek: bit not set
- --> $DIR/inits-1.rs:15:14
+ --> $DIR/inits-1.rs:14:14
|
LL | unsafe { rustc_peek(&ret); }
| ^^^^^^^^^^^^^^^^
error: rustc_peek: bit not set
- --> $DIR/inits-1.rs:35:14
+ --> $DIR/inits-1.rs:34:14
|
LL | unsafe { rustc_peek(&y); }
| ^^^^^^^^^^^^^^
error: rustc_peek: bit not set
- --> $DIR/inits-1.rs:43:14
+ --> $DIR/inits-1.rs:42:14
|
LL | unsafe { rustc_peek(&x); }
| ^^^^^^^^^^^^^^
// General test of maybe_uninits state computed by MIR dataflow.
-#![feature(nll)]
#![feature(core_intrinsics, rustc_attrs)]
use std::intrinsics::rustc_peek;
error: rustc_peek: bit not set
- --> $DIR/uninits-1.rs:19:14
+ --> $DIR/uninits-1.rs:18:14
|
LL | unsafe { rustc_peek(&x) };
| ^^^^^^^^^^^^^^
error: rustc_peek: bit not set
- --> $DIR/uninits-1.rs:20:14
+ --> $DIR/uninits-1.rs:19:14
|
LL | unsafe { rustc_peek(&y) };
| ^^^^^^^^^^^^^^
error: rustc_peek: bit not set
- --> $DIR/uninits-1.rs:21:14
+ --> $DIR/uninits-1.rs:20:14
|
LL | unsafe { rustc_peek(&z) };
| ^^^^^^^^^^^^^^
error: rustc_peek: bit not set
- --> $DIR/uninits-1.rs:37:14
+ --> $DIR/uninits-1.rs:36:14
|
LL | unsafe { rustc_peek(&x); }
| ^^^^^^^^^^^^^^
error: rustc_peek: bit not set
- --> $DIR/uninits-1.rs:45:14
+ --> $DIR/uninits-1.rs:44:14
|
LL | unsafe { rustc_peek(&ret); }
| ^^^^^^^^^^^^^^^^
// General test of maybe_uninits state computed by MIR dataflow.
-#![feature(nll)]
#![feature(core_intrinsics, rustc_attrs)]
use std::intrinsics::rustc_peek;
error: rustc_peek: bit not set
- --> $DIR/uninits-2.rs:15:14
+ --> $DIR/uninits-2.rs:14:14
|
LL | unsafe { rustc_peek(&x) };
| ^^^^^^^^^^^^^^
-#![feature(nll)]
-
// run-pass
fn vec() {
//
// FIXME(#54366) - We probably shouldn't allow #[thread_local] static mut to get a 'static lifetime.
-#![feature(nll)]
#![feature(thread_local)]
#[thread_local]
-#![feature(nll)]
-
fn gimme(x: &(u32,)) -> &u32 {
&x.0
}
error[E0597]: `v` does not live long enough
- --> $DIR/borrowed-local-error.rs:10:9
+ --> $DIR/borrowed-local-error.rs:8:9
|
LL | let x = gimme({
| ----- borrow later used by call
// Regression test for issue #38899
#![feature(nll)]
-#![allow(dead_code)]
pub struct Block<'a> {
current: &'a u8,
error[E0502]: cannot borrow `*block.current` as immutable because it is also borrowed as mutable
- --> $DIR/borrowed-referent-issue-38899.rs:14:21
+ --> $DIR/borrowed-referent-issue-38899.rs:13:21
|
LL | let x = &mut block;
| ---------- mutable borrow occurs here
-#![feature(nll)]
-
fn gimme(x: &(u32,)) -> &u32 {
&x.0
}
error[E0716]: temporary value dropped while borrowed
- --> $DIR/borrowed-temporary-error.rs:10:10
+ --> $DIR/borrowed-temporary-error.rs:8:10
|
LL | &(v,)
| ^^^^ creates a temporary which is freed while still in use
-#![feature(nll)]
-#![allow(warnings)]
-
fn foo<'a>(x: &'a (u32,)) -> &'a u32 {
let v = 22;
&v
error[E0515]: cannot return reference to local variable `v`
- --> $DIR/borrowed-universal-error-2.rs:6:5
+ --> $DIR/borrowed-universal-error-2.rs:3:5
|
LL | &v
| ^^ returns a reference to data owned by the current function
-#![feature(nll)]
-#![allow(warnings)]
-
fn gimme(x: &(u32,)) -> &u32 {
&x.0
}
error[E0515]: cannot return value referencing temporary value
- --> $DIR/borrowed-universal-error.rs:10:5
+ --> $DIR/borrowed-universal-error.rs:7:5
|
LL | gimme(&(v,))
| ^^^^^^^----^
// Check that capturing a mutable reference by move and assigning to its
// referent doesn't make the unused mut lint think that it is mutable.
-#![feature(nll)]
#![deny(unused_mut)]
fn mutable_upvar() {
error: variable does not need to be mutable
- --> $DIR/capture-mut-ref.rs:8:9
+ --> $DIR/capture-mut-ref.rs:7:9
|
LL | let mut x = &mut 0;
| ----^
| help: remove this `mut`
|
note: lint level defined here
- --> $DIR/capture-mut-ref.rs:5:9
+ --> $DIR/capture-mut-ref.rs:4:9
|
LL | #![deny(unused_mut)]
| ^^^^^^^^^^
// Test that a structure which tries to store a pointer to `y` into
// `p` (indirectly) fails to compile.
-#![feature(rustc_attrs)]
-#![feature(nll)]
-
struct SomeStruct<'a, 'b: 'a> {
p: &'a mut &'b i32,
y: &'b i32,
error[E0597]: `y` does not live long enough
- --> $DIR/capture-ref-in-struct.rs:21:16
+ --> $DIR/capture-ref-in-struct.rs:18:16
|
LL | y: &y,
| ^^ borrowed value does not live long enough
// check that accesses due to a closure capture give a special note
-#![feature(nll)]
-
fn closure_imm_capture_conflict(mut x: i32) {
let r = &mut x;
|| x; //~ ERROR
error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable
- --> $DIR/closure-access-spans.rs:7:5
+ --> $DIR/closure-access-spans.rs:5:5
|
LL | let r = &mut x;
| ------ mutable borrow occurs here
| - mutable borrow later used here
error[E0499]: cannot borrow `x` as mutable more than once at a time
- --> $DIR/closure-access-spans.rs:13:5
+ --> $DIR/closure-access-spans.rs:11:5
|
LL | let r = &mut x;
| ------ first mutable borrow occurs here
| - first borrow later used here
error[E0500]: closure requires unique access to `x` but it is already borrowed
- --> $DIR/closure-access-spans.rs:19:5
+ --> $DIR/closure-access-spans.rs:17:5
|
LL | let r = &mut x;
| ------ borrow occurs here
| - first borrow later used here
error[E0503]: cannot use `x` because it was mutably borrowed
- --> $DIR/closure-access-spans.rs:25:13
+ --> $DIR/closure-access-spans.rs:23:13
|
LL | let r = &mut x;
| ------ borrow of `x` occurs here
| - borrow later used here
error[E0505]: cannot move out of `x` because it is borrowed
- --> $DIR/closure-access-spans.rs:31:5
+ --> $DIR/closure-access-spans.rs:29:5
|
LL | let r = &x;
| -- borrow of `x` occurs here
| - borrow later used here
error[E0382]: borrow of moved value: `x`
- --> $DIR/closure-access-spans.rs:37:5
+ --> $DIR/closure-access-spans.rs:35:5
|
LL | fn closure_imm_capture_moved(mut x: String) {
| ----- move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait
| value borrowed here after move
error[E0382]: borrow of moved value: `x`
- --> $DIR/closure-access-spans.rs:42:5
+ --> $DIR/closure-access-spans.rs:40:5
|
LL | fn closure_mut_capture_moved(mut x: String) {
| ----- move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait
| value borrowed here after move
error[E0382]: borrow of moved value: `x`
- --> $DIR/closure-access-spans.rs:47:5
+ --> $DIR/closure-access-spans.rs:45:5
|
LL | fn closure_unique_capture_moved(x: &mut String) {
| - move occurs because `x` has type `&mut std::string::String`, which does not implement the `Copy` trait
| value borrowed here after move
error[E0382]: use of moved value: `x`
- --> $DIR/closure-access-spans.rs:52:5
+ --> $DIR/closure-access-spans.rs:50:5
|
LL | fn closure_move_capture_moved(x: &mut String) {
| - move occurs because `x` has type `&mut std::string::String`, which does not implement the `Copy` trait
// check that existing borrows due to a closure capture give a special note
-#![feature(nll)]
-
fn move_while_borrowed(x: String) {
let f = || x.len();
let y = x; //~ ERROR
error[E0505]: cannot move out of `x` because it is borrowed
- --> $DIR/closure-borrow-spans.rs:7:13
+ --> $DIR/closure-borrow-spans.rs:5:13
|
LL | let f = || x.len();
| -- - borrow occurs due to use in closure
| - borrow later used here
error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable
- --> $DIR/closure-borrow-spans.rs:13:13
+ --> $DIR/closure-borrow-spans.rs:11:13
|
LL | let f = || x;
| -- - first borrow occurs due to use of `x` in closure
| - immutable borrow later used here
error[E0597]: `x` does not live long enough
- --> $DIR/closure-borrow-spans.rs:21:16
+ --> $DIR/closure-borrow-spans.rs:19:16
|
LL | f = || x;
| -- ^ borrowed value does not live long enough
| - borrow later used here
error[E0506]: cannot assign to `x` because it is borrowed
- --> $DIR/closure-borrow-spans.rs:28:5
+ --> $DIR/closure-borrow-spans.rs:26:5
|
LL | let f = || x;
| -- - borrow occurs due to use in closure
| - borrow later used here
error[E0503]: cannot use `x` because it was mutably borrowed
- --> $DIR/closure-borrow-spans.rs:34:13
+ --> $DIR/closure-borrow-spans.rs:32:13
|
LL | let f = || x = 0;
| -- - borrow occurs due to use of `x` in closure
| - borrow later used here
error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable
- --> $DIR/closure-borrow-spans.rs:40:13
+ --> $DIR/closure-borrow-spans.rs:38:13
|
LL | let f = || x = 0;
| -- - first borrow occurs due to use of `x` in closure
| - mutable borrow later used here
error[E0499]: cannot borrow `x` as mutable more than once at a time
- --> $DIR/closure-borrow-spans.rs:46:13
+ --> $DIR/closure-borrow-spans.rs:44:13
|
LL | let f = || x = 0;
| -- - first borrow occurs due to use of `x` in closure
| - first borrow later used here
error[E0597]: `x` does not live long enough
- --> $DIR/closure-borrow-spans.rs:54:16
+ --> $DIR/closure-borrow-spans.rs:52:16
|
LL | f = || x = 0;
| -- ^ borrowed value does not live long enough
| - borrow later used here
error[E0506]: cannot assign to `x` because it is borrowed
- --> $DIR/closure-borrow-spans.rs:61:5
+ --> $DIR/closure-borrow-spans.rs:59:5
|
LL | let f = || x = 0;
| -- - borrow occurs due to use in closure
| - borrow later used here
error[E0505]: cannot move out of `x` because it is borrowed
- --> $DIR/closure-borrow-spans.rs:67:13
+ --> $DIR/closure-borrow-spans.rs:65:13
|
LL | let f = || *x = 0;
| -- - borrow occurs due to use in closure
| - borrow later used here
error[E0501]: cannot borrow `x` as immutable because previous closure requires unique access
- --> $DIR/closure-borrow-spans.rs:73:13
+ --> $DIR/closure-borrow-spans.rs:71:13
|
LL | let f = || *x = 0;
| -- - first borrow occurs due to use of `x` in closure
| - first borrow later used here
error[E0501]: cannot borrow `x` as mutable because previous closure requires unique access
- --> $DIR/closure-borrow-spans.rs:79:13
+ --> $DIR/closure-borrow-spans.rs:77:13
|
LL | let f = || *x = 0;
| -- - first borrow occurs due to use of `x` in closure
| - first borrow later used here
error[E0597]: `x` does not live long enough
- --> $DIR/closure-borrow-spans.rs:88:17
+ --> $DIR/closure-borrow-spans.rs:86:17
|
LL | f = || *x = 0;
| -- ^ borrowed value does not live long enough
| - borrow later used here
error[E0506]: cannot assign to `*x` because it is borrowed
- --> $DIR/closure-borrow-spans.rs:95:5
+ --> $DIR/closure-borrow-spans.rs:93:5
|
LL | let f = || *x = 0;
| -- - borrow occurs due to use in closure
// Some cases with closures that might be problems
-#![allow(unused)]
-#![feature(nll)]
-
// Should have one error per assignment
fn one_closure(x: i32) {
error[E0594]: cannot assign to `x`, as it is not declared as mutable
- --> $DIR/closure-captures.rs:10:5
+ --> $DIR/closure-captures.rs:7:5
|
LL | fn one_closure(x: i32) {
| - help: consider changing this to be mutable: `mut x`
| ^^^^^ cannot assign
error[E0594]: cannot assign to `x`, as it is not declared as mutable
- --> $DIR/closure-captures.rs:12:5
+ --> $DIR/closure-captures.rs:9:5
|
LL | fn one_closure(x: i32) {
| - help: consider changing this to be mutable: `mut x`
| ^^^^^ cannot assign
error[E0594]: cannot assign to `x`, as it is not declared as mutable
- --> $DIR/closure-captures.rs:18:9
+ --> $DIR/closure-captures.rs:15:9
|
LL | fn two_closures(x: i32) {
| - help: consider changing this to be mutable: `mut x`
| ^^^^^ cannot assign
error[E0594]: cannot assign to `x`, as it is not declared as mutable
- --> $DIR/closure-captures.rs:22:9
+ --> $DIR/closure-captures.rs:19:9
|
LL | fn two_closures(x: i32) {
| - help: consider changing this to be mutable: `mut x`
| ^^^^^ cannot assign
error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure
- --> $DIR/closure-captures.rs:30:9
+ --> $DIR/closure-captures.rs:27:9
|
LL | ||
| ^^ cannot borrow as mutable
| - mutable borrow occurs due to use of `x` in closure
|
help: consider changing this to accept closures that implement `FnMut`
- --> $DIR/closure-captures.rs:29:12
+ --> $DIR/closure-captures.rs:26:12
|
LL | fn_ref(|| {
| ____________^
| |________________^
error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure
- --> $DIR/closure-captures.rs:34:9
+ --> $DIR/closure-captures.rs:31:9
|
LL | ||
| ^^ cannot borrow as mutable
| - mutable borrow occurs due to use of `x` in closure
|
help: consider changing this to accept closures that implement `FnMut`
- --> $DIR/closure-captures.rs:33:12
+ --> $DIR/closure-captures.rs:30:12
|
LL | fn_ref(move || {
| ____________^
| |___________^
error[E0594]: cannot assign to `x`, as it is not declared as mutable
- --> $DIR/closure-captures.rs:42:10
+ --> $DIR/closure-captures.rs:39:10
|
LL | fn two_closures_ref(x: i32) {
| - help: consider changing this to be mutable: `mut x`
| ^^^^^ cannot assign
error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure
- --> $DIR/closure-captures.rs:41:9
+ --> $DIR/closure-captures.rs:38:9
|
LL | ||
| ^^ cannot borrow as mutable
| - mutable borrow occurs due to use of `x` in closure
|
help: consider changing this to accept closures that implement `FnMut`
- --> $DIR/closure-captures.rs:40:12
+ --> $DIR/closure-captures.rs:37:12
|
LL | fn_ref(|| {
| ____________^
| |________________^
error[E0594]: cannot assign to `x`, as it is not declared as mutable
- --> $DIR/closure-captures.rs:46:5
+ --> $DIR/closure-captures.rs:43:5
|
LL | fn two_closures_ref(x: i32) {
| - help: consider changing this to be mutable: `mut x`
| ^^^^^ cannot assign
error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure
- --> $DIR/closure-captures.rs:45:9
+ --> $DIR/closure-captures.rs:42:9
|
LL | ||
| ^^ cannot borrow as mutable
| - mutable borrow occurs due to use of `x` in closure
|
help: consider changing this to accept closures that implement `FnMut`
- --> $DIR/closure-captures.rs:44:12
+ --> $DIR/closure-captures.rs:41:12
|
LL | fn_ref(move || {
| ____________^
| |___________^
error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure
- --> $DIR/closure-captures.rs:51:9
+ --> $DIR/closure-captures.rs:48:9
|
LL | ||
| ^^ cannot borrow as mutable
| - mutable borrow occurs due to use of `x` in closure
|
help: consider changing this to accept closures that implement `FnMut`
- --> $DIR/closure-captures.rs:50:12
+ --> $DIR/closure-captures.rs:47:12
|
LL | fn_ref(|| {
| ____________^
| |________________^
error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure
- --> $DIR/closure-captures.rs:54:9
+ --> $DIR/closure-captures.rs:51:9
|
LL | ||
| ^^ cannot borrow as mutable
| - mutable borrow occurs due to use of `x` in closure
|
help: consider changing this to accept closures that implement `FnMut`
- --> $DIR/closure-captures.rs:53:12
+ --> $DIR/closure-captures.rs:50:12
|
LL | fn_ref(move || {
| ____________^
// check that moves due to a closure capture give a special note
-#![feature(nll)]
-
fn move_after_move(x: String) {
|| x;
let y = x; //~ ERROR
error[E0382]: use of moved value: `x`
- --> $DIR/closure-move-spans.rs:7:13
+ --> $DIR/closure-move-spans.rs:5:13
|
LL | fn move_after_move(x: String) {
| - move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait
| ^ value used here after move
error[E0382]: borrow of moved value: `x`
- --> $DIR/closure-move-spans.rs:12:13
+ --> $DIR/closure-move-spans.rs:10:13
|
LL | fn borrow_after_move(x: String) {
| - move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait
| ^^ value borrowed here after move
error[E0382]: borrow of moved value: `x`
- --> $DIR/closure-move-spans.rs:17:13
+ --> $DIR/closure-move-spans.rs:15:13
|
LL | fn borrow_mut_after_move(mut x: String) {
| ----- move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait
-// revisions: migrate nll
-//[migrate]compile-flags: -Z borrowck=migrate
-#![cfg_attr(nll, feature(nll))]
-
// compile-pass
// Test that we propagate region relations from closures precisely when there is
// Test that we propagate *all* requirements to the caller, not just the first
// one.
-#![feature(nll)]
-
fn once<S, T, U, F: FnOnce(S, T) -> U>(f: F, s: S, t: T) -> U {
f(s, t)
}
error[E0597]: `local_arr` does not live long enough
- --> $DIR/propagate-multiple-requirements.rs:17:14
+ --> $DIR/propagate-multiple-requirements.rs:15:14
|
LL | let mut out: &mut &'static [i32] = &mut (&[1] as _);
| ------------------- type annotation requires that `local_arr` is borrowed for `'static`
// check that liveness due to a closure capture gives a special note
-#![feature(nll)]
-
fn use_as_borrow_capture(mut x: i32) {
let y = &x;
x = 0; //~ ERROR
error[E0506]: cannot assign to `x` because it is borrowed
- --> $DIR/closure-use-spans.rs:7:5
+ --> $DIR/closure-use-spans.rs:5:5
|
LL | let y = &x;
| -- borrow of `x` occurs here
| - borrow later captured here by closure
error[E0506]: cannot assign to `x` because it is borrowed
- --> $DIR/closure-use-spans.rs:13:5
+ --> $DIR/closure-use-spans.rs:11:5
|
LL | let y = &mut x;
| ------ borrow of `x` occurs here
| - borrow later captured here by closure
error[E0506]: cannot assign to `x` because it is borrowed
- --> $DIR/closure-use-spans.rs:19:5
+ --> $DIR/closure-use-spans.rs:17:5
|
LL | let y = &x;
| -- borrow of `x` occurs here
// Test messages where a closure capture conflicts with itself because it's in
// a loop.
-#![feature(nll)]
-
fn repreated_move(x: String) {
for i in 0..10 {
|| x; //~ ERROR
error[E0382]: use of moved value: `x`
- --> $DIR/closures-in-loops.rs:8:9
+ --> $DIR/closures-in-loops.rs:6:9
|
LL | fn repreated_move(x: String) {
| - move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait
| value moved into closure here, in previous iteration of loop
error[E0499]: cannot borrow `x` as mutable more than once at a time
- --> $DIR/closures-in-loops.rs:15:16
+ --> $DIR/closures-in-loops.rs:13:16
|
LL | v.push(|| x = String::new());
| ^^ - borrows occur due to use of `x` in closure
| mutable borrow starts here in previous iteration of loop
error[E0524]: two closures require unique access to `x` at the same time
- --> $DIR/closures-in-loops.rs:22:16
+ --> $DIR/closures-in-loops.rs:20:16
|
LL | v.push(|| *x = String::new());
| ^^ - borrows occur due to use of `x` in closure
// Regression test for issue #47053
-#![feature(nll)]
#![feature(thread_local)]
#[thread_local]
error[E0594]: cannot assign to immutable static item `FOO`
- --> $DIR/constant-thread-locals-issue-47053.rs:10:5
+ --> $DIR/constant-thread-locals-issue-47053.rs:9:5
|
LL | FOO = 6;
| ^^^^^^^ cannot assign
// Regression test for #46314
-#![feature(nll)]
#![feature(decl_macro)]
struct NonCopy(String);
error[E0382]: use of moved value: `wrapper.inner`
- --> $DIR/decl-macro-illegal-copy.rs:22:9
+ --> $DIR/decl-macro-illegal-copy.rs:21:9
|
LL | $wrapper.inner
| -------------- value moved here
--- /dev/null
+error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable
+ --> $DIR/get_default.rs:21:17
+ |
+LL | fn ok(map: &mut Map) -> &String {
+ | - let's call the lifetime of this reference `'1`
+LL | loop {
+LL | match map.get() {
+ | --- immutable borrow occurs here
+LL | Some(v) => {
+LL | return v;
+ | - returning this value requires that `*map` is borrowed for `'1`
+...
+LL | map.set(String::new()); // Ideally, this would not error.
+ | ^^^ mutable borrow occurs here
+
+error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable
+ --> $DIR/get_default.rs:32:17
+ |
+LL | fn err(map: &mut Map) -> &String {
+ | - let's call the lifetime of this reference `'1`
+LL | loop {
+LL | match map.get() {
+ | --- immutable borrow occurs here
+LL | Some(v) => {
+LL | map.set(String::new()); // Both AST and MIR error here
+ | ^^^ mutable borrow occurs here
+LL |
+LL | return v;
+ | - returning this value requires that `*map` is borrowed for `'1`
+
+error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable
+ --> $DIR/get_default.rs:37:17
+ |
+LL | fn err(map: &mut Map) -> &String {
+ | - let's call the lifetime of this reference `'1`
+LL | loop {
+LL | match map.get() {
+ | --- immutable borrow occurs here
+...
+LL | return v;
+ | - returning this value requires that `*map` is borrowed for `'1`
+...
+LL | map.set(String::new()); // Ideally, just AST would error here
+ | ^^^ mutable borrow occurs here
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0502`.
// compile-pass
-#![feature(nll)]
#![feature(box_patterns)]
struct Root {
-// (this works, but only in NLL)
// compile-pass
-#![feature(nll)]
use std::collections::HashMap;
use std::sync::Mutex;
-// (this works, but only in NLL)
// compile-pass
-#![feature(nll)]
fn from_stdin(min: u64) -> Vec<u64> {
use std::io::BufRead;
// meant to compile and run successfully once rust-lang/rust#54987 is
// implemented.
-#![feature(nll)]
-
struct D {
x: u32,
s: S,
error[E0381]: assign of possibly uninitialized variable: `d`
- --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:30:5
+ --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:28:5
|
LL | d.x = 10;
| ^^^^^^^^ use of possibly uninitialized `d`
error[E0381]: assign of possibly uninitialized variable: `d`
- --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:36:5
+ --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:34:5
|
LL | d.x = 10;
| ^^^^^^^^ use of possibly uninitialized `d`
error[E0382]: assign of moved value: `d`
- --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:43:5
+ --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:41:5
|
LL | let mut d = D { x: 0, s: S{ y: 0, z: 0 } };
| ----- move occurs because `d` has type `D`, which does not implement the `Copy` trait
| ^^^^^^^^ value assigned here after move
error[E0381]: assign to part of possibly uninitialized variable: `d`
- --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:49:5
+ --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:47:5
|
LL | d.s.y = 20;
| ^^^^^^^^^^ use of possibly uninitialized `d.s`
error[E0381]: assign to part of possibly uninitialized variable: `d`
- --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:55:5
+ --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:53:5
|
LL | d.s.y = 20;
| ^^^^^^^^^^ use of possibly uninitialized `d.s`
error[E0382]: assign to part of moved value: `d`
- --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:62:5
+ --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:60:5
|
LL | let mut d = D { x: 0, s: S{ y: 0, z: 0} };
| ----- move occurs because `d` has type `D`, which does not implement the `Copy` trait
// compile-pass
-#![feature(nll)]
-
fn main() {
let _s = construct().borrow().consume_borrowed();
}
// compile-pass
-#![feature(nll)]
-
use std::ops::{Deref, DerefMut};
fn box_two_field(v: &mut Box<(i32, i32)>) {
-#![feature(nll)]
// compile-pass
// rust-lang/rust#32382: Borrow checker used to complain about
// compile-pass
-#![feature(nll)]
-
use std::borrow::Cow;
#[derive(Clone, Debug)]
-#![feature(nll)]
-
struct Foo;
impl Foo {
error[E0499]: cannot borrow `**other` as mutable more than once at a time
- --> $DIR/issue-46589.rs:19:21
+ --> $DIR/issue-46589.rs:17:21
|
LL | *other = match (*other).get_self() {
| -------- first mutable borrow occurs here
// compile-pass
-#![allow(warnings)]
-#![feature(nll)]
-
struct LoadedObject {
bodies: Vec<Body>,
color: Color,
-#![feature(nll)]
struct FancyNum {
num: u8,
}
error[E0594]: cannot assign to `fancy_ref.num` which is behind a `&` reference
- --> $DIR/issue-47388.rs:9:5
+ --> $DIR/issue-47388.rs:8:5
|
LL | let fancy_ref = &(&mut fancy);
| ------------- help: consider changing this to be a mutable reference: `&mut (&mut fancy)`
// causing region relations not to be enforced at all the places where
// they have to be enforced.
-#![feature(nll)]
-
struct Foo<'a>(&'a ());
trait Bar {
type Assoc;
error[E0515]: cannot return reference to local variable `local`
- --> $DIR/issue-47470.rs:17:9
+ --> $DIR/issue-47470.rs:15:9
|
LL | &local
| ^^^^^^ returns a reference to data owned by the current function
// run-pass
// revisions: lxl nll
-#![cfg_attr(nll, feature(nll))]
-
struct Foo {
x: u32
}
// Regression test for #48697
-#![feature(nll)]
-
fn foo(x: &i32) -> &i32 {
let z = 4;
let f = &|y| y;
error[E0515]: cannot return value referencing local variable `z`
- --> $DIR/issue-48697.rs:9:5
+ --> $DIR/issue-48697.rs:7:5
|
LL | let k = f(&z);
| -- `z` is borrowed here
// bounds derived from `Sized` requirements” that checks that the fixed compiler
// accepts this code fragment with both AST and MIR borrow checkers.
//
-// revisions: migrate nll
-//
// compile-pass
-#![cfg_attr(nll, feature(nll))]
-
struct Qey<Q: ?Sized>(Q);
fn main() {}
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/issue-50716.rs:14:14
+ |
+LL | fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>)
+ | -- lifetime `'a` defined here
+...
+LL | let _x = *s;
+ | ^^ proving this value is `Sized` requires that `'a` must outlive `'static`
+
+error: aborting due to previous error
+
// Regression test for the issue #50716: NLL ignores lifetimes bounds
// derived from `Sized` requirements
-#![feature(nll)]
-
trait A {
type X: ?Sized;
}
-error: lifetime may not live long enough
- --> $DIR/issue-50716.rs:16:14
+error[E0308]: mismatched types
+ --> $DIR/issue-50716.rs:14:9
|
-LL | fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>)
- | -- lifetime `'a` defined here
-...
LL | let _x = *s;
- | ^^ proving this value is `Sized` requires that `'a` must outlive `'static`
+ | ^^ lifetime mismatch
+ |
+ = note: expected type `std::marker::Sized`
+ found type `std::marker::Sized`
+note: the lifetime 'a as defined on the function body at 9:8...
+ --> $DIR/issue-50716.rs:9:8
+ |
+LL | fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>)
+ | ^^
+ = note: ...does not necessarily outlive the static lifetime
error: aborting due to previous error
+For more information about this error, try `rustc --explain E0308`.
-#![feature(nll)]
-
struct Struct;
impl Struct {
warning: function cannot return without recursing
- --> $DIR/issue-51191.rs:6:5
+ --> $DIR/issue-51191.rs:4:5
|
LL | fn bar(self: &mut Self) {
| ^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
= help: a `loop` may express intention better if this is on purpose
error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable
- --> $DIR/issue-51191.rs:8:9
+ --> $DIR/issue-51191.rs:6:9
|
LL | (&mut self).bar();
| ^^^^^^^^^^^
| try removing `&mut` here
error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable
- --> $DIR/issue-51191.rs:13:9
+ --> $DIR/issue-51191.rs:11:9
|
LL | fn imm(self) {
| ---- help: consider changing this to be mutable: `mut self`
| ^^^^^^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable
- --> $DIR/issue-51191.rs:22:9
+ --> $DIR/issue-51191.rs:20:9
|
LL | (&mut self).bar();
| ^^^^^^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow data in a `&` reference as mutable
- --> $DIR/issue-51191.rs:22:9
+ --> $DIR/issue-51191.rs:20:9
|
LL | (&mut self).bar();
| ^^^^^^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable
- --> $DIR/issue-51191.rs:28:9
+ --> $DIR/issue-51191.rs:26:9
|
LL | (&mut self).bar();
| ^^^^^^^^^^^
-#![feature(nll)]
-
fn main() {
let ref my_ref @ _ = 0;
*my_ref = 0;
error[E0594]: cannot assign to `*my_ref` which is behind a `&` reference
- --> $DIR/issue-51244.rs:5:5
+ --> $DIR/issue-51244.rs:3:5
|
LL | let ref my_ref @ _ = 0;
| -------------- help: consider changing this to be a mutable reference: `ref mut my_ref @ _`
// ignore-tidy-linelength
-#![feature(nll)]
-
struct Bar;
impl Bar {
error[E0502]: cannot borrow `self.thing` as mutable because it is also borrowed as immutable
- --> $DIR/issue-51268.rs:18:9
+ --> $DIR/issue-51268.rs:16:9
|
LL | self.thing.bar(|| {
| ^ --- -- immutable borrow occurs here
//
// compile-pass
-#![feature(nll)]
-
fn creash<'a>() {
let x: &'a () = &();
}
-#![allow(warnings)]
-#![feature(nll)]
-
fn main() {
let range = 0..1;
let r = range;
error[E0382]: use of moved value: `range`
- --> $DIR/issue-51512.rs:7:13
+ --> $DIR/issue-51512.rs:4:13
|
LL | let range = 0..1;
| ----- move occurs because `range` has type `std::ops::Range<i32>`, which does not implement the `Copy` trait
// of the fact that the type implements Drop.
#![feature(nll)]
-#![allow(dead_code)]
pub struct S<'a> { url: &'a mut String }
error[E0713]: borrow may still be in use when destructor runs
- --> $DIR/issue-52059-report-when-borrow-and-drop-conflict.rs:14:5
+ --> $DIR/issue-52059-report-when-borrow-and-drop-conflict.rs:13:5
|
LL | fn finish_1(s: S) -> &mut String {
| - has type `S<'1>`
| - here, drop of `s` needs exclusive access to `*s.url`, because the type `S<'_>` implements the `Drop` trait
error[E0713]: borrow may still be in use when destructor runs
- --> $DIR/issue-52059-report-when-borrow-and-drop-conflict.rs:19:13
+ --> $DIR/issue-52059-report-when-borrow-and-drop-conflict.rs:18:13
|
LL | fn finish_2(s: S) -> &mut String {
| - has type `S<'1>`
| - here, drop of `s` needs exclusive access to `*s.url`, because the type `S<'_>` implements the `Drop` trait
error[E0713]: borrow may still be in use when destructor runs
- --> $DIR/issue-52059-report-when-borrow-and-drop-conflict.rs:24:21
+ --> $DIR/issue-52059-report-when-borrow-and-drop-conflict.rs:23:21
|
LL | fn finish_3(s: S) -> &mut String {
| - has type `S<'1>`
| - here, drop of `s` needs exclusive access to `*s.url`, because the type `S<'_>` implements the `Drop` trait
error[E0509]: cannot move out of type `S<'_>`, which implements the `Drop` trait
- --> $DIR/issue-52059-report-when-borrow-and-drop-conflict.rs:29:13
+ --> $DIR/issue-52059-report-when-borrow-and-drop-conflict.rs:28:13
|
LL | let p = s.url; p
| ^^^^^
-#![feature(nll)]
-#![allow(unused_variables)]
-
// Regression test for #52078: we were failing to infer a relationship
// between `'a` and `'b` below due to inference variables introduced
// during the normalization process.
-#![feature(nll)]
-
use std::rc::Rc;
use std::sync::Arc;
error[E0507]: cannot move out of an `Rc`
- --> $DIR/issue-52086.rs:10:10
+ --> $DIR/issue-52086.rs:8:10
|
LL | drop(x.field);
| ^^^^^^^ cannot move out of an `Rc`
error[E0507]: cannot move out of an `Arc`
- --> $DIR/issue-52086.rs:14:10
+ --> $DIR/issue-52086.rs:12:10
|
LL | drop(y.field);
| ^^^^^^^ cannot move out of an `Arc`
-//
-
-#![allow(warnings)]
#![feature(nll)]
trait Bazinga {}
error: lifetime may not live long enough
- --> $DIR/issue-52113.rs:37:5
+ --> $DIR/issue-52113.rs:34:5
|
LL | fn produce_err<'a, 'b: 'a>(data: &'b mut Vec<&'b u32>, value: &'a u32) -> impl Bazinga + 'b {
| -- -- lifetime `'b` defined here
-#![feature(nll)]
-#![allow(warnings)]
-
struct Test;
impl Test {
error[E0515]: cannot return reference to local variable `x`
- --> $DIR/issue-52534-1.rs:9:9
+ --> $DIR/issue-52534-1.rs:6:9
|
LL | &x
| ^^ returns a reference to data owned by the current function
error[E0515]: cannot return reference to local variable `x`
- --> $DIR/issue-52534-1.rs:16:5
+ --> $DIR/issue-52534-1.rs:13:5
|
LL | &x
| ^^ returns a reference to data owned by the current function
error[E0515]: cannot return value referencing local variable `x`
- --> $DIR/issue-52534-1.rs:22:5
+ --> $DIR/issue-52534-1.rs:19:5
|
LL | &&x
| ^--
| returns a value referencing data owned by the current function
error[E0515]: cannot return reference to temporary value
- --> $DIR/issue-52534-1.rs:22:5
+ --> $DIR/issue-52534-1.rs:19:5
|
LL | &&x
| ^--
| returns a reference to data owned by the current function
error[E0515]: cannot return reference to local variable `x`
- --> $DIR/issue-52534-1.rs:29:5
+ --> $DIR/issue-52534-1.rs:26:5
|
LL | &x
| ^^ returns a reference to data owned by the current function
error[E0515]: cannot return reference to local variable `x`
- --> $DIR/issue-52534-1.rs:35:5
+ --> $DIR/issue-52534-1.rs:32:5
|
LL | &x
| ^^ returns a reference to data owned by the current function
error[E0515]: cannot return reference to local variable `x`
- --> $DIR/issue-52534-1.rs:41:5
+ --> $DIR/issue-52534-1.rs:38:5
|
LL | &x
| ^^ returns a reference to data owned by the current function
error[E0515]: cannot return reference to local variable `x`
- --> $DIR/issue-52534-1.rs:47:5
+ --> $DIR/issue-52534-1.rs:44:5
|
LL | &x
| ^^ returns a reference to data owned by the current function
-#![feature(nll)]
-#![allow(warnings)]
-
fn foo(x: &u32) -> &u32 {
let y;
error[E0597]: `x` does not live long enough
- --> $DIR/issue-52534-2.rs:9:9
+ --> $DIR/issue-52534-2.rs:6:9
|
LL | y = &x
| ^^^^^^ borrowed value does not live long enough
-#![feature(nll)]
-#![allow(warnings)]
-
fn foo(_: impl FnOnce(&u32) -> &u32) {
}
error[E0597]: `x` does not live long enough
- --> $DIR/issue-52534.rs:12:14
+ --> $DIR/issue-52534.rs:9:14
|
LL | foo(|a| &x)
| - ^ `x` would have to be valid for `'0`...
= note: to learn more, visit <https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html#dangling-references>
error[E0597]: `y` does not live long enough
- --> $DIR/issue-52534.rs:18:26
+ --> $DIR/issue-52534.rs:15:26
|
LL | baz(|first, second| &y)
| ----- ^ `y` would have to be valid for `'0`...
-#![feature(nll)]
-
fn expect_fn<F>(f: F) where F : Fn() {
f();
}
error[E0507]: cannot move out of captured variable in an `Fn` closure
- --> $DIR/issue-52663-span-decl-captured-variable.rs:10:26
+ --> $DIR/issue-52663-span-decl-captured-variable.rs:8:26
|
LL | let x = (vec![22], vec![44]);
| - captured outer variable
#![feature(box_syntax)]
-#![feature(nll)]
trait Foo { fn get(&self); }
error[E0597]: `tmp0` does not live long enough
- --> $DIR/issue-52663-trait-object.rs:13:20
+ --> $DIR/issue-52663-trait-object.rs:12:20
|
LL | let tmp1 = &tmp0;
| ^^^^^ borrowed value does not live long enough
-#![feature(nll)]
-
struct A {
b: B,
}
error[E0382]: borrow of moved value: `a.b`
- --> $DIR/issue-52669.rs:15:5
+ --> $DIR/issue-52669.rs:13:5
|
LL | fn bar(mut a: A) -> B {
| ----- move occurs because `a` has type `A`, which does not implement the `Copy` trait
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/issue-52742.rs:14:9
+ |
+LL | fn take_bar(&mut self, b: Bar<'_>) {
+ | --------- -- let's call this `'1`
+ | |
+ | has type `&mut Foo<'_, '2>`
+LL | self.y = b.z
+ | ^^^^^^^^^^^^ assignment requires that `'1` must outlive `'2`
+
+error: aborting due to previous error
+
-#![feature(nll)]
#![feature(in_band_lifetimes)]
struct Foo<'a, 'b> {
impl Foo<'_, '_> {
fn take_bar(&mut self, b: Bar<'_>) {
self.y = b.z
- //~^ ERROR lifetime may not live long enough
+ //~^ ERROR
}
}
-error: lifetime may not live long enough
- --> $DIR/issue-52742.rs:15:9
+error[E0312]: lifetime of reference outlives lifetime of borrowed content...
+ --> $DIR/issue-52742.rs:14:18
|
-LL | fn take_bar(&mut self, b: Bar<'_>) {
- | --------- -- let's call this `'1`
- | |
- | has type `&mut Foo<'_, '2>`
LL | self.y = b.z
- | ^^^^^^^^^^^^ assignment requires that `'1` must outlive `'2`
+ | ^^^
+ |
+note: ...the reference is valid for the lifetime '_ as defined on the impl at 12:10...
+ --> $DIR/issue-52742.rs:12:10
+ |
+LL | impl Foo<'_, '_> {
+ | ^^
+note: ...but the borrowed content is only valid for the anonymous lifetime #2 defined on the method body at 13:5
+ --> $DIR/issue-52742.rs:13:5
+ |
+LL | / fn take_bar(&mut self, b: Bar<'_>) {
+LL | | self.y = b.z
+LL | |
+LL | | }
+ | |_____^
error: aborting due to previous error
// compile-pass
-#![feature(nll)]
-
use std::ops::Deref;
pub struct TypeFieldIterator<'a, T: 'a> {
//
// compile-pass
-#![feature(nll)]
-#![feature(rustc_attrs)]
-#![allow(dead_code)]
-
use std::cell::{RefCell, Ref};
trait AnyVec<'a> {
-#![feature(nll)]
-
// run-pass
struct Slice(&'static [&'static [u8]]);
// compile-pass
-#![feature(nll)]
-#![allow(unreachable_code)]
#![deny(unused_mut)]
pub fn foo() {
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/issue-55394.rs:9:9
+ |
+LL | fn new(bar: &mut Bar) -> Self {
+ | - ---- return type is Foo<'2>
+ | |
+ | let's call the lifetime of this reference `'1`
+LL | Foo { bar }
+ | ^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2`
+
+error: aborting due to previous error
+
-#![feature(nll)]
-
struct Bar;
struct Foo<'s> {
impl Foo<'_> {
fn new(bar: &mut Bar) -> Self {
- Foo { bar } //~ERROR lifetime may not live long enough
+ Foo { bar } //~ERROR
}
}
-error: lifetime may not live long enough
- --> $DIR/issue-55394.rs:11:9
+error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'s` due to conflicting requirements
+ --> $DIR/issue-55394.rs:9:9
|
-LL | fn new(bar: &mut Bar) -> Self {
- | - ---- return type is Foo<'2>
- | |
- | let's call the lifetime of this reference `'1`
LL | Foo { bar }
- | ^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2`
+ | ^^^
+ |
+note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 8:5...
+ --> $DIR/issue-55394.rs:8:5
+ |
+LL | / fn new(bar: &mut Bar) -> Self {
+LL | | Foo { bar }
+LL | | }
+ | |_____^
+note: ...so that reference does not outlive borrowed content
+ --> $DIR/issue-55394.rs:9:15
+ |
+LL | Foo { bar }
+ | ^^^
+note: but, the lifetime must be valid for the lifetime '_ as defined on the impl at 7:10...
+ --> $DIR/issue-55394.rs:7:10
+ |
+LL | impl Foo<'_> {
+ | ^^
+ = note: ...so that the expression is assignable:
+ expected Foo<'_>
+ found Foo<'_>
error: aborting due to previous error
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/issue-55401.rs:3:5
+ |
+LL | fn static_to_a_to_static_through_ref_in_tuple<'a>(x: &'a u32) -> &'static u32 {
+ | -- lifetime `'a` defined here
+LL | let (ref y, _z): (&'a u32, u32) = (&22, 44);
+LL | *y
+ | ^^ returning this value requires that `'a` must outlive `'static`
+
+error: aborting due to previous error
+
-#![feature(nll)]
-
fn static_to_a_to_static_through_ref_in_tuple<'a>(x: &'a u32) -> &'static u32 {
let (ref y, _z): (&'a u32, u32) = (&22, 44);
*y //~ ERROR
-error: lifetime may not live long enough
- --> $DIR/issue-55401.rs:5:5
+error[E0312]: lifetime of reference outlives lifetime of borrowed content...
+ --> $DIR/issue-55401.rs:3:5
|
-LL | fn static_to_a_to_static_through_ref_in_tuple<'a>(x: &'a u32) -> &'static u32 {
- | -- lifetime `'a` defined here
-LL | let (ref y, _z): (&'a u32, u32) = (&22, 44);
LL | *y
- | ^^ returning this value requires that `'a` must outlive `'static`
+ | ^^
+ |
+ = note: ...the reference is valid for the static lifetime...
+note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 1:47
+ --> $DIR/issue-55401.rs:1:47
+ |
+LL | fn static_to_a_to_static_through_ref_in_tuple<'a>(x: &'a u32) -> &'static u32 {
+ | ^^
error: aborting due to previous error
-#![feature(nll)]
-
use std::any::Any;
#[derive(Debug, Clone)]
error[E0716]: temporary value dropped while borrowed
- --> $DIR/issue-57265-return-type-wf-check.rs:22:23
+ --> $DIR/issue-57265-return-type-wf-check.rs:20:23
|
LL | let (_, z) = foo(&"hello".to_string());
| -----^^^^^^^^^^^^^^^^^^^-- temporary value is freed at the end of this statement
-#![feature(nll)]
-
// compile-pass
trait Foo<'a> {
-#![feature(nll)]
-
// compile-pass
trait Foo {
// Test for ICE from issue 57989
-#![feature(nll)]
-
fn f(x: &i32) {
let g = &x;
*x = 0; //~ ERROR cannot assign to `*x` which is behind a `&` reference
error[E0594]: cannot assign to `*x` which is behind a `&` reference
- --> $DIR/issue-57989.rs:7:5
+ --> $DIR/issue-57989.rs:5:5
|
LL | fn f(x: &i32) {
| ---- help: consider changing this to be a mutable reference: `&mut i32`
| ^^^^^^ `x` is a `&` reference, so the data it refers to cannot be written
error[E0506]: cannot assign to `*x` because it is borrowed
- --> $DIR/issue-57989.rs:7:5
+ --> $DIR/issue-57989.rs:5:5
|
LL | let g = &x;
| -- borrow of `*x` occurs here
-#![allow(warnings)]
#![feature(nll)]
fn main() {
error: lifetime may not live long enough
- --> $DIR/issue-58053.rs:7:33
+ --> $DIR/issue-58053.rs:6:33
|
LL | let f = |x: &i32| -> &i32 { x };
| - ---- ^ returning this value requires that `'1` must outlive `'2`
| let's call the lifetime of this reference `'1`
error: lifetime may not live long enough
- --> $DIR/issue-58053.rs:11:25
+ --> $DIR/issue-58053.rs:10:25
|
LL | let g = |x: &i32| { x };
| - - ^ returning this value requires that `'1` must outlive `'2`
-#![allow(dead_code)]
#![feature(nll)]
struct A<'a>(&'a ());
error: lifetime may not live long enough
- --> $DIR/issue-58299.rs:17:9
+ --> $DIR/issue-58299.rs:16:9
|
LL | fn foo<'a>(x: i32) {
| -- lifetime `'a` defined here
| ^^^^^^^^^^ requires that `'a` must outlive `'static`
error: lifetime may not live long enough
- --> $DIR/issue-58299.rs:25:27
+ --> $DIR/issue-58299.rs:24:27
|
LL | fn bar<'a>(x: i32) {
| -- lifetime `'a` defined here
-#![allow(warnings)]
-#![feature(nll)]
-
struct Wrap<'p> { p: &'p mut i32 }
impl<'p> Drop for Wrap<'p> {
error[E0506]: cannot assign to `x` because it is borrowed
- --> $DIR/maybe-initialized-drop-implicit-fragment-drop.rs:20:5
+ --> $DIR/maybe-initialized-drop-implicit-fragment-drop.rs:17:5
|
LL | let wrap = Wrap { p: &mut x };
| ------ borrow of `x` occurs here
-#![allow(unused)]
-#![feature(nll)]
-
struct A(String);
struct C(D);
error[E0507]: cannot move out of borrowed content
- --> $DIR/move-errors.rs:9:13
+ --> $DIR/move-errors.rs:6:13
|
LL | let b = *a;
| ^^
| help: consider removing the `*`: `a`
error[E0508]: cannot move out of type `[A; 1]`, a non-copy array
- --> $DIR/move-errors.rs:15:13
+ --> $DIR/move-errors.rs:12:13
|
LL | let b = a[0];
| ^^^^
| help: consider borrowing here: `&a[0]`
error[E0507]: cannot move out of borrowed content
- --> $DIR/move-errors.rs:22:13
+ --> $DIR/move-errors.rs:19:13
|
LL | let s = **r;
| ^^^
| help: consider removing the `*`: `*r`
error[E0507]: cannot move out of an `Rc`
- --> $DIR/move-errors.rs:30:13
+ --> $DIR/move-errors.rs:27:13
|
LL | let s = *r;
| ^^
| help: consider removing the `*`: `r`
error[E0508]: cannot move out of type `[A; 1]`, a non-copy array
- --> $DIR/move-errors.rs:35:13
+ --> $DIR/move-errors.rs:32:13
|
LL | let a = [A("".to_string())][0];
| ^^^^^^^^^^^^^^^^^^^^^^
| help: consider borrowing here: `&[A("".to_string())][0]`
error[E0507]: cannot move out of borrowed content
- --> $DIR/move-errors.rs:41:16
+ --> $DIR/move-errors.rs:38:16
|
LL | let A(s) = *a;
| - ^^
| data moved here
|
note: move occurs because `s` has type `std::string::String`, which does not implement the `Copy` trait
- --> $DIR/move-errors.rs:41:11
+ --> $DIR/move-errors.rs:38:11
|
LL | let A(s) = *a;
| ^
error[E0509]: cannot move out of type `D`, which implements the `Drop` trait
- --> $DIR/move-errors.rs:47:19
+ --> $DIR/move-errors.rs:44:19
|
LL | let C(D(s)) = c;
| - ^ cannot move out of here
| data moved here
|
note: move occurs because `s` has type `std::string::String`, which does not implement the `Copy` trait
- --> $DIR/move-errors.rs:47:13
+ --> $DIR/move-errors.rs:44:13
|
LL | let C(D(s)) = c;
| ^
error[E0507]: cannot move out of borrowed content
- --> $DIR/move-errors.rs:54:9
+ --> $DIR/move-errors.rs:51:9
|
LL | b = *a;
| ^^ cannot move out of borrowed content
error[E0508]: cannot move out of type `[B; 1]`, a non-copy array
- --> $DIR/move-errors.rs:77:11
+ --> $DIR/move-errors.rs:74:11
|
LL | match x[0] {
| ^^^^
| - ...and here
|
note: move occurs because these variables have types that don't implement the `Copy` trait
- --> $DIR/move-errors.rs:79:14
+ --> $DIR/move-errors.rs:76:14
|
LL | B::U(d) => (),
| ^
| ^
error[E0509]: cannot move out of type `D`, which implements the `Drop` trait
- --> $DIR/move-errors.rs:86:11
+ --> $DIR/move-errors.rs:83:11
|
LL | match x {
| ^ cannot move out of here
| - data moved here
|
note: move occurs because `s` has type `std::string::String`, which does not implement the `Copy` trait
- --> $DIR/move-errors.rs:89:16
+ --> $DIR/move-errors.rs:86:16
|
LL | B::U(D(s)) => (),
| ^
error[E0509]: cannot move out of type `D`, which implements the `Drop` trait
- --> $DIR/move-errors.rs:95:11
+ --> $DIR/move-errors.rs:92:11
|
LL | match x {
| ^ cannot move out of here
| - data moved here
|
note: move occurs because `s` has type `std::string::String`, which does not implement the `Copy` trait
- --> $DIR/move-errors.rs:98:12
+ --> $DIR/move-errors.rs:95:12
|
LL | (D(s), &t) => (),
| ^
error[E0507]: cannot move out of borrowed content
- --> $DIR/move-errors.rs:95:11
+ --> $DIR/move-errors.rs:92:11
|
LL | match x {
| ^ cannot move out of borrowed content
| - data moved here
|
note: move occurs because `t` has type `std::string::String`, which does not implement the `Copy` trait
- --> $DIR/move-errors.rs:98:17
+ --> $DIR/move-errors.rs:95:17
|
LL | (D(s), &t) => (),
| ^
error[E0509]: cannot move out of type `F`, which implements the `Drop` trait
- --> $DIR/move-errors.rs:105:11
+ --> $DIR/move-errors.rs:102:11
|
LL | match x {
| ^ cannot move out of here
| data moved here
|
note: move occurs because these variables have types that don't implement the `Copy` trait
- --> $DIR/move-errors.rs:107:11
+ --> $DIR/move-errors.rs:104:11
|
LL | F(s, mut t) => (),
| ^ ^^^^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/move-errors.rs:113:11
+ --> $DIR/move-errors.rs:110:11
|
LL | match *x {
| ^^
| - data moved here
|
note: move occurs because `s` has type `std::string::String`, which does not implement the `Copy` trait
- --> $DIR/move-errors.rs:115:12
+ --> $DIR/move-errors.rs:112:12
|
LL | Ok(s) | Err(s) => (),
| ^
-#![feature(nll)]
-
fn main() {
let x = (vec![1, 2, 3], );
drop(x.0);
error[E0382]: use of moved value: `x`
- --> $DIR/move-subpaths-moves-root.rs:6:10
+ --> $DIR/move-subpaths-moves-root.rs:4:10
|
LL | drop(x.0);
| --- value moved here
// Check that we error when a bound from the impl is not satisfied when
// normalizing an associated type.
-#![feature(nll)]
trait Visitor<'d> {
type Value;
}
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'d` due to conflicting requirements
- --> $DIR/normalization-bounds-error.rs:13:1
+ --> $DIR/normalization-bounds-error.rs:12:1
|
LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
-note: first, the lifetime cannot outlive the lifetime 'd as defined on the function body at 13:14...
- --> $DIR/normalization-bounds-error.rs:13:14
+note: first, the lifetime cannot outlive the lifetime 'd as defined on the function body at 12:14...
+ --> $DIR/normalization-bounds-error.rs:12:14
|
LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {}
| ^^
-note: ...but the lifetime must also be valid for the lifetime 'a as defined on the function body at 13:18...
- --> $DIR/normalization-bounds-error.rs:13:18
+note: ...but the lifetime must also be valid for the lifetime 'a as defined on the function body at 12:18...
+ --> $DIR/normalization-bounds-error.rs:12:18
|
LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {}
| ^^
//run-pass
-#![feature(nll)]
trait Visitor<'d> {
type Value;
}
// run-pass
-#![feature(nll)]
-
pub fn main() {
let mut x: Vec<&[i32; 0]> = Vec::new();
for i in 0..10 {
-#![feature(nll)]
-
fn shorten_lifetime<'a, 'b, 'min>(a: &'a i32, b: &'b i32) -> &'min i32
where
'a: 'min,
error[E0597]: `l` does not live long enough
- --> $DIR/promoted-bounds.rs:21:17
+ --> $DIR/promoted-bounds.rs:19:17
|
LL | let ptr = {
| --- borrow later stored here
// Check that we handle multiple closures in the same promoted constant.
-#![feature(nll)]
-
fn foo() -> &'static i32 {
let z = 0;
let p = &(|y| y, |y| y);
error[E0515]: cannot return value referencing local variable `z`
- --> $DIR/promoted-closure-pair.rs:9:5
+ --> $DIR/promoted-closure-pair.rs:7:5
|
LL | p.1(&z)
| ^^^^--^
--- /dev/null
+error[E0502]: cannot borrow `my_struct.field` as mutable because it is also borrowed as immutable
+ --> $DIR/region-ends-after-if-condition.rs:26:9
+ |
+LL | let value = &my_struct.field;
+ | ---------------- immutable borrow occurs here
+LL | if value.is_empty() {
+LL | my_struct.field.push_str("Hello, world!");
+ | ^^^^^^^^^^^^^^^ mutable borrow occurs here
+...
+LL | drop(value);
+ | ----- immutable borrow later used here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0502`.
//
// compile-pass
-#![allow(warnings)]
-#![feature(dyn_trait)]
-#![feature(nll)]
-
trait Foo {
fn foo(&self) { }
}
// function returning always its first argument can be upcast to one
// that returns either first or second argument.
-#![feature(nll)]
-#![allow(warnings)]
-
use std::cell::Cell;
type DoubleCell<A> = Cell<(A, A)>;
error[E0597]: `b` does not live long enough
- --> $DIR/var-appears-twice.rs:23:38
+ --> $DIR/var-appears-twice.rs:20:38
|
LL | let x: DoubleCell<_> = make_cell(&b);
| ------------- ^^ borrowed value does not live long enough
// Regression test for issue #46557
-#![feature(nll)]
-#![allow(dead_code)]
-
fn gimme_static_mut() -> &'static mut u32 {
let ref mut x = 1234543;
x //~ ERROR cannot return value referencing temporary value [E0515]
error[E0515]: cannot return value referencing temporary value
- --> $DIR/return-ref-mut-issue-46557.rs:8:5
+ --> $DIR/return-ref-mut-issue-46557.rs:5:5
|
LL | let ref mut x = 1234543;
| ------- temporary value created here
//
// compile-pass
-#![feature(nll)]
-#![allow(unused_variables)]
-
use std::collections::BTreeMap;
trait ValueTree {
//
// compile-pass
-#![feature(nll)]
-#![allow(unused_variables)]
-
use std::collections::BTreeMap;
use std::ops::Range;
use std::cmp::Ord;
--- /dev/null
+error[E0309]: the associated type `<T as MyTrait<'_>>::Output` may not live long enough
+ --> $DIR/projection-where-clause-env-wrong-bound.rs:15:5
+ |
+LL | bar::<T::Output>()
+ | ^^^^^^^^^^^^^^^^
+ |
+ = help: consider adding an explicit lifetime bound `<T as MyTrait<'_>>::Output: 'a`...
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0309`.
-#![feature(nll)]
-
// Test that we are able to establish that `<T as
// MyTrait<'a>>::Output` outlives `'b` here. We need to prove however
// that `<T as MyTrait<'a>>::Output` outlives `'a`, so we also have to
-error[E0309]: the associated type `<T as MyTrait<'_>>::Output` may not live long enough
- --> $DIR/projection-where-clause-env-wrong-bound.rs:17:5
+error[E0309]: the associated type `<T as MyTrait<'a>>::Output` may not live long enough
+ --> $DIR/projection-where-clause-env-wrong-bound.rs:15:5
|
LL | bar::<T::Output>()
| ^^^^^^^^^^^^^^^^
|
- = help: consider adding an explicit lifetime bound `<T as MyTrait<'_>>::Output: 'a`...
+ = help: consider adding an explicit lifetime bound `<T as MyTrait<'a>>::Output: 'a`...
+note: ...so that the type `<T as MyTrait<'a>>::Output` will meet its required lifetime bounds
+ --> $DIR/projection-where-clause-env-wrong-bound.rs:15:5
+ |
+LL | bar::<T::Output>()
+ | ^^^^^^^^^^^^^^^^
error: aborting due to previous error
--- /dev/null
+error[E0309]: the associated type `<T as MyTrait<'_>>::Output` may not live long enough
+ --> $DIR/projection-where-clause-env-wrong-lifetime.rs:14:5
+ |
+LL | bar::<<T as MyTrait<'a>>::Output>()
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider adding an explicit lifetime bound `<T as MyTrait<'_>>::Output: 'a`...
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0309`.
-#![feature(nll)]
-
// Test that when we have a `<T as MyTrait<'a>>::Output: 'a`
// relationship in the environment we take advantage of it. In this
// case, that means we **don't** have to prove that `T: 'a`.
+++ /dev/null
-// Test that we assume that universal types like `T` outlive the
-// function body. Same as ty-param-fn-body, but uses `feature(nll)`,
-// which affects error reporting.
-
-#![feature(nll)]
-
-#![allow(warnings)]
-
-use std::cell::Cell;
-
-// No errors here, because `'a` is local to the body.
-fn region_within_body<T>(t: T) {
- let some_int = 22;
- let cell = Cell::new(&some_int);
- outlives(cell, t)
-}
-
-// Error here, because T: 'a is not satisfied.
-fn region_static<'a, T>(cell: Cell<&'a usize>, t: T) {
- outlives(cell, t)
- //~^ ERROR the parameter type `T` may not live long enough
-}
-
-fn outlives<'a, T>(x: Cell<&'a usize>, y: T)
-where
- T: 'a,
-{
-}
-
-fn main() {}
+++ /dev/null
-error[E0309]: the parameter type `T` may not live long enough
- --> $DIR/ty-param-fn-body-nll-feature.rs:20:5
- |
-LL | outlives(cell, t)
- | ^^^^^^^^^^^^^^^^^
- |
- = help: consider adding an explicit lifetime bound `T: 'a`...
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0309`.
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/type-alias-free-regions.rs:17:9
+ |
+LL | impl<'a> FromBox<'a> for C<'a> {
+ | -- lifetime `'a` defined here
+LL | fn from_box(b: Box<B>) -> Self {
+ | - has type `std::boxed::Box<std::boxed::Box<&'1 isize>>`
+LL | C { f: b }
+ | ^^^^^^^^^^ returning this value requires that `'1` must outlive `'a`
+
+error: lifetime may not live long enough
+ --> $DIR/type-alias-free-regions.rs:27:9
+ |
+LL | impl<'a> FromTuple<'a> for C<'a> {
+ | -- lifetime `'a` defined here
+LL | fn from_tuple(b: (B,)) -> Self {
+ | - has type `(std::boxed::Box<&'1 isize>,)`
+LL | C { f: Box::new(b.0) }
+ | ^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'a`
+
+error: aborting due to 2 previous errors
+
// Test that we don't assume that type aliases have the same type parameters
// as the type they alias and then panic when we see this.
-#![feature(nll)]
-
type A<'a> = &'a isize;
type B<'a> = Box<A<'a>>;
-error: lifetime may not live long enough
- --> $DIR/type-alias-free-regions.rs:19:9
+error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
+ --> $DIR/type-alias-free-regions.rs:17:9
|
-LL | impl<'a> FromBox<'a> for C<'a> {
- | -- lifetime `'a` defined here
-LL | fn from_box(b: Box<B>) -> Self {
- | - has type `std::boxed::Box<std::boxed::Box<&'1 isize>>`
LL | C { f: b }
- | ^^^^^^^^^^ returning this value requires that `'1` must outlive `'a`
+ | ^
+ |
+note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 16:5...
+ --> $DIR/type-alias-free-regions.rs:16:5
+ |
+LL | / fn from_box(b: Box<B>) -> Self {
+LL | | C { f: b }
+LL | | }
+ | |_____^
+ = note: ...so that the expression is assignable:
+ expected std::boxed::Box<std::boxed::Box<&isize>>
+ found std::boxed::Box<std::boxed::Box<&isize>>
+note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 15:6...
+ --> $DIR/type-alias-free-regions.rs:15:6
+ |
+LL | impl<'a> FromBox<'a> for C<'a> {
+ | ^^
+ = note: ...so that the expression is assignable:
+ expected C<'a>
+ found C<'_>
-error: lifetime may not live long enough
- --> $DIR/type-alias-free-regions.rs:29:9
+error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
+ --> $DIR/type-alias-free-regions.rs:27:16
|
-LL | impl<'a> FromTuple<'a> for C<'a> {
- | -- lifetime `'a` defined here
-LL | fn from_tuple(b: (B,)) -> Self {
- | - has type `(std::boxed::Box<&'1 isize>,)`
LL | C { f: Box::new(b.0) }
- | ^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'a`
+ | ^^^^^^^^^^^^^
+ |
+note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 26:5...
+ --> $DIR/type-alias-free-regions.rs:26:5
+ |
+LL | / fn from_tuple(b: (B,)) -> Self {
+LL | | C { f: Box::new(b.0) }
+LL | | }
+ | |_____^
+ = note: ...so that the expression is assignable:
+ expected std::boxed::Box<&isize>
+ found std::boxed::Box<&isize>
+note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 25:6...
+ --> $DIR/type-alias-free-regions.rs:25:6
+ |
+LL | impl<'a> FromTuple<'a> for C<'a> {
+ | ^^
+ = note: ...so that the expression is assignable:
+ expected C<'a>
+ found C<'_>
error: aborting due to 2 previous errors
-#![feature(nll)]
#![deny(unused_mut)]
fn main() {
error: variable does not need to be mutable
- --> $DIR/unused-mut-issue-50343.rs:5:33
+ --> $DIR/unused-mut-issue-50343.rs:4:33
|
LL | vec![(42, 22)].iter().map(|(mut x, _y)| ()).count();
| ----^
| help: remove this `mut`
|
note: lint level defined here
- --> $DIR/unused-mut-issue-50343.rs:2:9
+ --> $DIR/unused-mut-issue-50343.rs:1:9
|
LL | #![deny(unused_mut)]
| ^^^^^^^^^^
// Unit test for the "user substitutions" that are annotated on each
// node.
-#![feature(nll)]
-
enum SomeEnum<T> {
SomeVariant { t: T }
}
error[E0597]: `c` does not live long enough
- --> $DIR/adt-brace-enums.rs:27:48
+ --> $DIR/adt-brace-enums.rs:25:48
|
LL | SomeEnum::SomeVariant::<&'static u32> { t: &c };
| ^^
| - `c` dropped here while still borrowed
error[E0597]: `c` does not live long enough
- --> $DIR/adt-brace-enums.rs:32:43
+ --> $DIR/adt-brace-enums.rs:30:43
|
LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) {
| -- lifetime `'a` defined here
| - `c` dropped here while still borrowed
error[E0597]: `c` does not live long enough
- --> $DIR/adt-brace-enums.rs:42:47
+ --> $DIR/adt-brace-enums.rs:40:47
|
LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
| -- lifetime `'a` defined here
// Unit test for the "user substitutions" that are annotated on each
// node.
-#![feature(nll)]
-
struct SomeStruct<T> { t: T }
fn no_annot() {
error[E0597]: `c` does not live long enough
- --> $DIR/adt-brace-structs.rs:25:37
+ --> $DIR/adt-brace-structs.rs:23:37
|
LL | SomeStruct::<&'static u32> { t: &c };
| ^^
| - `c` dropped here while still borrowed
error[E0597]: `c` does not live long enough
- --> $DIR/adt-brace-structs.rs:30:32
+ --> $DIR/adt-brace-structs.rs:28:32
|
LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) {
| -- lifetime `'a` defined here
| - `c` dropped here while still borrowed
error[E0597]: `c` does not live long enough
- --> $DIR/adt-brace-structs.rs:40:36
+ --> $DIR/adt-brace-structs.rs:38:36
|
LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
| -- lifetime `'a` defined here
// Unit test for the "user substitutions" that are annotated on each
// node.
-#![feature(nll)]
#![allow(warnings)]
use std::cell::Cell;
error[E0597]: `c` does not live long enough
- --> $DIR/adt-nullary-enums.rs:34:41
+ --> $DIR/adt-nullary-enums.rs:33:41
|
LL | SomeEnum::SomeVariant(Cell::new(&c)),
| ----------^^-
| - `c` dropped here while still borrowed
error[E0597]: `c` does not live long enough
- --> $DIR/adt-nullary-enums.rs:42:41
+ --> $DIR/adt-nullary-enums.rs:41:41
|
LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) {
| -- lifetime `'a` defined here
| - `c` dropped here while still borrowed
error[E0597]: `c` does not live long enough
- --> $DIR/adt-nullary-enums.rs:55:45
+ --> $DIR/adt-nullary-enums.rs:54:45
|
LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
| -- lifetime `'a` defined here
// Unit test for the "user substitutions" that are annotated on each
// node.
-#![feature(nll)]
#![allow(warnings)]
enum SomeEnum<T> {
error[E0597]: `c` does not live long enough
- --> $DIR/adt-tuple-enums.rs:29:43
+ --> $DIR/adt-tuple-enums.rs:28:43
|
LL | SomeEnum::SomeVariant::<&'static u32>(&c);
| ^^
| - `c` dropped here while still borrowed
error[E0597]: `c` does not live long enough
- --> $DIR/adt-tuple-enums.rs:34:38
+ --> $DIR/adt-tuple-enums.rs:33:38
|
LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) {
| -- lifetime `'a` defined here
| - `c` dropped here while still borrowed
error[E0597]: `c` does not live long enough
- --> $DIR/adt-tuple-enums.rs:44:42
+ --> $DIR/adt-tuple-enums.rs:43:42
|
LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
| -- lifetime `'a` defined here
// Unit test for the "user substitutions" that are annotated on each
// node.
-#![feature(nll)]
-
struct SomeStruct<T>(T);
fn no_annot() {
error[E0597]: `c` does not live long enough
- --> $DIR/adt-tuple-struct.rs:25:32
+ --> $DIR/adt-tuple-struct.rs:23:32
|
LL | SomeStruct::<&'static u32>(&c);
| ^^
| - `c` dropped here while still borrowed
error[E0597]: `c` does not live long enough
- --> $DIR/adt-tuple-struct.rs:30:27
+ --> $DIR/adt-tuple-struct.rs:28:27
|
LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) {
| -- lifetime `'a` defined here
| - `c` dropped here while still borrowed
error[E0597]: `c` does not live long enough
- --> $DIR/adt-tuple-struct.rs:40:31
+ --> $DIR/adt-tuple-struct.rs:38:31
|
LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
| -- lifetime `'a` defined here
#![allow(warnings)]
-#![feature(nll)]
fn main() {
let x = 22_u32;
error[E0597]: `x` does not live long enough
- --> $DIR/cast_static_lifetime.rs:6:19
+ --> $DIR/cast_static_lifetime.rs:5:19
|
LL | let y: &u32 = (&x) as &'static u32;
| ^^^^----------------
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/constant-in-expr-inherent-1.rs:8:5
+ |
+LL | fn foo<'a>(_: &'a u32) -> &'static u32 {
+ | -- lifetime `'a` defined here
+LL | <Foo<'a>>::C
+ | ^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+
+error: aborting due to previous error
+
-#![feature(nll)]
-
struct Foo<'a> { x: &'a u32 }
impl<'a> Foo<'a> {
-error: lifetime may not live long enough
- --> $DIR/constant-in-expr-inherent-1.rs:10:5
+error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
+ --> $DIR/constant-in-expr-inherent-1.rs:8:5
+ |
+LL | <Foo<'a>>::C
+ | ^^^^^^^^^^^^
+ |
+note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 7:8...
+ --> $DIR/constant-in-expr-inherent-1.rs:7:8
|
LL | fn foo<'a>(_: &'a u32) -> &'static u32 {
- | -- lifetime `'a` defined here
+ | ^^
+ = note: ...so that the types are compatible:
+ expected Foo<'_>
+ found Foo<'a>
+ = note: but, the lifetime must be valid for the static lifetime...
+note: ...so that reference does not outlive borrowed content
+ --> $DIR/constant-in-expr-inherent-1.rs:8:5
+ |
LL | <Foo<'a>>::C
- | ^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+ | ^^^^^^^^^^^^
error: aborting due to previous error
// Test that we still check constants are well-formed, even when we there's no
// type annotation to check.
-#![feature(nll)]
-
const FUN: fn(&'static ()) = |_| {};
struct A;
impl A {
error[E0597]: `x` does not live long enough
- --> $DIR/constant-in-expr-inherent-2.rs:25:9
+ --> $DIR/constant-in-expr-inherent-2.rs:23:9
|
LL | FUN(&x);
| ----^^-
| - `x` dropped here while still borrowed
error[E0597]: `x` does not live long enough
- --> $DIR/constant-in-expr-inherent-2.rs:26:23
+ --> $DIR/constant-in-expr-inherent-2.rs:24:23
|
LL | A::ASSOCIATED_FUN(&x);
| ------------------^^-
| - `x` dropped here while still borrowed
error[E0597]: `x` does not live long enough
- --> $DIR/constant-in-expr-inherent-2.rs:27:28
+ --> $DIR/constant-in-expr-inherent-2.rs:25:28
|
LL | B::ALSO_ASSOCIATED_FUN(&x);
| -----------------------^^-
| - `x` dropped here while still borrowed
error[E0597]: `x` does not live long enough
- --> $DIR/constant-in-expr-inherent-2.rs:28:31
+ --> $DIR/constant-in-expr-inherent-2.rs:26:31
|
LL | <_>::TRAIT_ASSOCIATED_FUN(&x);
| --------------------------^^-
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/constant-in-expr-normalize.rs:18:5
+ |
+LL | fn foo<'a>(_: &'a u32) -> &'static u32 {
+ | -- lifetime `'a` defined here
+LL | <() as Foo<'a>>::C
+ | ^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+
+error: aborting due to previous error
+
-#![feature(nll)]
-
trait Mirror {
type Me;
}
-error: lifetime may not live long enough
- --> $DIR/constant-in-expr-normalize.rs:20:5
+error[E0312]: lifetime of reference outlives lifetime of borrowed content...
+ --> $DIR/constant-in-expr-normalize.rs:18:5
|
-LL | fn foo<'a>(_: &'a u32) -> &'static u32 {
- | -- lifetime `'a` defined here
LL | <() as Foo<'a>>::C
- | ^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ = note: ...the reference is valid for the static lifetime...
+note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 17:8
+ --> $DIR/constant-in-expr-normalize.rs:17:8
+ |
+LL | fn foo<'a>(_: &'a u32) -> &'static u32 {
+ | ^^
error: aborting due to previous error
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/constant-in-expr-trait-item-1.rs:10:5
+ |
+LL | fn foo<'a>(_: &'a u32) -> &'static u32 {
+ | -- lifetime `'a` defined here
+LL | <() as Foo<'a>>::C
+ | ^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+
+error: aborting due to previous error
+
-#![feature(nll)]
-
trait Foo<'a> {
const C: &'a u32;
}
-error: lifetime may not live long enough
- --> $DIR/constant-in-expr-trait-item-1.rs:12:5
+error[E0312]: lifetime of reference outlives lifetime of borrowed content...
+ --> $DIR/constant-in-expr-trait-item-1.rs:10:5
|
-LL | fn foo<'a>(_: &'a u32) -> &'static u32 {
- | -- lifetime `'a` defined here
LL | <() as Foo<'a>>::C
- | ^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ = note: ...the reference is valid for the static lifetime...
+note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 9:8
+ --> $DIR/constant-in-expr-trait-item-1.rs:9:8
+ |
+LL | fn foo<'a>(_: &'a u32) -> &'static u32 {
+ | ^^
error: aborting due to previous error
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/constant-in-expr-trait-item-2.rs:10:5
+ |
+LL | fn foo<'a, T: Foo<'a>>() -> &'static u32 {
+ | -- lifetime `'a` defined here
+LL | <T as Foo<'a>>::C
+ | ^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+
+error: aborting due to previous error
+
-#![feature(nll)]
-
trait Foo<'a> {
const C: &'a u32;
}
-error: lifetime may not live long enough
- --> $DIR/constant-in-expr-trait-item-2.rs:12:5
+error[E0312]: lifetime of reference outlives lifetime of borrowed content...
+ --> $DIR/constant-in-expr-trait-item-2.rs:10:5
|
-LL | fn foo<'a, T: Foo<'a>>() -> &'static u32 {
- | -- lifetime `'a` defined here
LL | <T as Foo<'a>>::C
- | ^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: ...the reference is valid for the static lifetime...
+note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 9:8
+ --> $DIR/constant-in-expr-trait-item-2.rs:9:8
+ |
+LL | fn foo<'a, T: Foo<'a>>() -> &'static u32 {
+ | ^^
error: aborting due to previous error
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/constant-in-expr-trait-item-3.rs:10:5
+ |
+LL | fn foo<'a, T: Foo<'a>>() -> &'static u32 {
+ | -- lifetime `'a` defined here
+LL | T::C
+ | ^^^^ returning this value requires that `'a` must outlive `'static`
+
+error: aborting due to previous error
+
-#![feature(nll)]
-
trait Foo<'a> {
const C: &'a u32;
}
-error: lifetime may not live long enough
- --> $DIR/constant-in-expr-trait-item-3.rs:12:5
+error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
+ --> $DIR/constant-in-expr-trait-item-3.rs:10:5
+ |
+LL | T::C
+ | ^^^^
+ |
+note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 9:8...
+ --> $DIR/constant-in-expr-trait-item-3.rs:9:8
|
LL | fn foo<'a, T: Foo<'a>>() -> &'static u32 {
- | -- lifetime `'a` defined here
+ | ^^
+ = note: ...so that the types are compatible:
+ expected Foo<'_>
+ found Foo<'a>
+ = note: but, the lifetime must be valid for the static lifetime...
+note: ...so that reference does not outlive borrowed content
+ --> $DIR/constant-in-expr-trait-item-3.rs:10:5
+ |
LL | T::C
- | ^^^^ returning this value requires that `'a` must outlive `'static`
+ | ^^^^
error: aborting due to previous error
// Unit test for the "user substitutions" that are annotated on each
// node.
-#![feature(nll)]
-
fn some_fn<T>(arg: T) { }
fn no_annot() {
error[E0597]: `c` does not live long enough
- --> $DIR/fns.rs:25:29
+ --> $DIR/fns.rs:23:29
|
LL | some_fn::<&'static u32>(&c);
| ------------------------^^-
| - `c` dropped here while still borrowed
error[E0597]: `c` does not live long enough
- --> $DIR/fns.rs:30:24
+ --> $DIR/fns.rs:28:24
|
LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) {
| -- lifetime `'a` defined here
| - `c` dropped here while still borrowed
error[E0597]: `c` does not live long enough
- --> $DIR/fns.rs:40:28
+ --> $DIR/fns.rs:38:28
|
LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
| -- lifetime `'a` defined here
// compile-pass
-#![feature(nll)]
// This test is reduced from a scenario pnkfelix encountered while
// bootstrapping the compiler.
//
// run-pass
-#![feature(nll)]
-
pub struct Foo<T>(T);
impl<T> Foo<T> {
//
// run-pass
-#![feature(nll)]
-
pub trait Hasher {
type Out: Eq;
}
// Unit test for the "user substitutions" that are annotated on each
// node.
-#![feature(nll)]
-
trait Bazoom<T> {
fn method<U>(&self, arg: T, arg2: U) { }
}
error[E0597]: `c` does not live long enough
- --> $DIR/method-call.rs:38:34
+ --> $DIR/method-call.rs:36:34
|
LL | a.method::<&'static u32>(b, &c);
| -----------------------------^^-
| - `c` dropped here while still borrowed
error[E0597]: `c` does not live long enough
- --> $DIR/method-call.rs:45:29
+ --> $DIR/method-call.rs:43:29
|
LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) {
| -- lifetime `'a` defined here
| - `c` dropped here while still borrowed
error[E0597]: `c` does not live long enough
- --> $DIR/method-call.rs:59:33
+ --> $DIR/method-call.rs:57:33
|
LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
| -- lifetime `'a` defined here
// Unit test for the "user substitutions" that are annotated on each
// node.
-#![feature(nll)]
-
trait Bazoom<T>: Sized {
fn method<U>(self, arg: T, arg2: U) { }
}
error[E0597]: `a` does not live long enough
- --> $DIR/method-ufcs-1.rs:32:7
+ --> $DIR/method-ufcs-1.rs:30:7
|
LL | x(&a, b, c);
| --^^-------
| - `a` dropped here while still borrowed
error[E0597]: `a` does not live long enough
- --> $DIR/method-ufcs-1.rs:39:36
+ --> $DIR/method-ufcs-1.rs:37:36
|
LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) {
| -- lifetime `'a` defined here
| - `a` dropped here while still borrowed
error[E0597]: `a` does not live long enough
- --> $DIR/method-ufcs-1.rs:53:41
+ --> $DIR/method-ufcs-1.rs:51:41
|
LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
| -- lifetime `'a` defined here
// Unit test for the "user substitutions" that are annotated on each
// node.
-#![feature(nll)]
-
trait Bazoom<T>: Sized {
fn method<U>(self, arg: T, arg2: U) { }
}
error[E0597]: `a` does not live long enough
- --> $DIR/method-ufcs-2.rs:32:7
+ --> $DIR/method-ufcs-2.rs:30:7
|
LL | x(&a, b, c);
| --^^-------
| - `a` dropped here while still borrowed
error[E0597]: `b` does not live long enough
- --> $DIR/method-ufcs-2.rs:39:39
+ --> $DIR/method-ufcs-2.rs:37:39
|
LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) {
| -- lifetime `'a` defined here
| - `b` dropped here while still borrowed
error[E0597]: `b` does not live long enough
- --> $DIR/method-ufcs-2.rs:53:44
+ --> $DIR/method-ufcs-2.rs:51:44
|
LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
| -- lifetime `'a` defined here
// Unit test for the "user substitutions" that are annotated on each
// node.
-#![feature(nll)]
-
trait Bazoom<T> {
fn method<U>(&self, arg: T, arg2: U) { }
}
error[E0597]: `c` does not live long enough
- --> $DIR/method-ufcs-3.rs:38:53
+ --> $DIR/method-ufcs-3.rs:36:53
|
LL | <_ as Bazoom<_>>::method::<&'static u32>(&a, b, &c);
| ------------------------------------------------^^-
| - `c` dropped here while still borrowed
error[E0597]: `c` does not live long enough
- --> $DIR/method-ufcs-3.rs:45:48
+ --> $DIR/method-ufcs-3.rs:43:48
|
LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) {
| -- lifetime `'a` defined here
| - `c` dropped here while still borrowed
error[E0597]: `c` does not live long enough
- --> $DIR/method-ufcs-3.rs:59:52
+ --> $DIR/method-ufcs-3.rs:57:52
|
LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) {
| -- lifetime `'a` defined here
-#![feature(nll)]
-
// Check that substitutions given on the self type (here, `A`) can be
// used in combination with annotations given for method arguments.
error[E0597]: `v` does not live long enough
- --> $DIR/method-ufcs-inherent-2.rs:16:37
+ --> $DIR/method-ufcs-inherent-2.rs:14:37
|
LL | fn foo<'a>() {
| -- lifetime `'a` defined here
| - `v` dropped here while still borrowed
error[E0597]: `v` does not live long enough
- --> $DIR/method-ufcs-inherent-2.rs:16:41
+ --> $DIR/method-ufcs-inherent-2.rs:14:41
|
LL | fn foo<'a>() {
| -- lifetime `'a` defined here
-#![feature(nll)]
-
// Check that inherent methods invoked with `<T>::new` style
// carry their annotations through to NLL in connection with
// method type parameters.
error[E0597]: `v` does not live long enough
- --> $DIR/method-ufcs-inherent-4.rs:17:37
+ --> $DIR/method-ufcs-inherent-4.rs:15:37
|
LL | fn foo<'a>() {
| -- lifetime `'a` defined here
| - `v` dropped here while still borrowed
error[E0597]: `v` does not live long enough
- --> $DIR/method-ufcs-inherent-4.rs:17:41
+ --> $DIR/method-ufcs-inherent-4.rs:15:41
|
LL | fn foo<'a>() {
| -- lifetime `'a` defined here
// Test that we enforce a `&'static` requirement that is only visible
// after normalization.
-#![feature(nll)]
-
trait Foo { type Out; }
impl Foo for () { type Out = &'static u32; }
error[E0597]: `a` does not live long enough
- --> $DIR/normalization.rs:11:31
+ --> $DIR/normalization.rs:9:31
|
LL | let b: <() as Foo>::Out = &a;
| ---------------- ^^ borrowed value does not live long enough
//
// run-pass
-#![feature(nll)]
-
trait Mirror {
type Me;
}
-#![feature(nll)]
-
enum Foo<'a> {
Bar { field: &'a u32 }
}
error[E0597]: `y` does not live long enough
- --> $DIR/pattern_substs_on_brace_enum_variant.rs:9:33
+ --> $DIR/pattern_substs_on_brace_enum_variant.rs:7:33
|
LL | let foo = Foo::Bar { field: &y };
| ^^ borrowed value does not live long enough
| - `y` dropped here while still borrowed
error[E0597]: `y` does not live long enough
- --> $DIR/pattern_substs_on_brace_enum_variant.rs:16:33
+ --> $DIR/pattern_substs_on_brace_enum_variant.rs:14:33
|
LL | let foo = Foo::Bar { field: &y };
| ^^ borrowed value does not live long enough
-#![feature(nll)]
-
struct Foo<'a> { field: &'a u32 }
fn in_let() {
error[E0597]: `y` does not live long enough
- --> $DIR/pattern_substs_on_brace_struct.rs:7:28
+ --> $DIR/pattern_substs_on_brace_struct.rs:5:28
|
LL | let foo = Foo { field: &y };
| ^^ borrowed value does not live long enough
| - `y` dropped here while still borrowed
error[E0597]: `y` does not live long enough
- --> $DIR/pattern_substs_on_brace_struct.rs:14:28
+ --> $DIR/pattern_substs_on_brace_struct.rs:12:28
|
LL | let foo = Foo { field: &y };
| ^^ borrowed value does not live long enough
-#![feature(nll)]
-
enum Foo<'a> {
Bar(&'a u32)
}
error[E0597]: `y` does not live long enough
- --> $DIR/pattern_substs_on_tuple_enum_variant.rs:9:24
+ --> $DIR/pattern_substs_on_tuple_enum_variant.rs:7:24
|
LL | let foo = Foo::Bar(&y);
| ^^ borrowed value does not live long enough
| - `y` dropped here while still borrowed
error[E0597]: `y` does not live long enough
- --> $DIR/pattern_substs_on_tuple_enum_variant.rs:16:24
+ --> $DIR/pattern_substs_on_tuple_enum_variant.rs:14:24
|
LL | let foo = Foo::Bar(&y);
| ^^ borrowed value does not live long enough
-#![feature(nll)]
-
struct Foo<'a>(&'a u32);
fn in_let() {
error[E0597]: `y` does not live long enough
- --> $DIR/pattern_substs_on_tuple_struct.rs:7:19
+ --> $DIR/pattern_substs_on_tuple_struct.rs:5:19
|
LL | let foo = Foo(&y);
| ^^ borrowed value does not live long enough
| - `y` dropped here while still borrowed
error[E0597]: `y` does not live long enough
- --> $DIR/pattern_substs_on_tuple_struct.rs:14:19
+ --> $DIR/pattern_substs_on_tuple_struct.rs:12:19
|
LL | let foo = Foo(&y);
| ^^ borrowed value does not live long enough
// Test that type annotations are checked in promoted constants correctly.
-#![feature(nll)]
-
fn foo<'a>() {
let x = 0;
let f = &drop::<&'a i32>;
error[E0597]: `x` does not live long enough
- --> $DIR/promoted-annotation.rs:8:7
+ --> $DIR/promoted-annotation.rs:6:7
|
LL | fn foo<'a>() {
| -- lifetime `'a` defined here
#![allow(warnings)]
-#![feature(nll)]
#![feature(type_ascription)]
fn main() {
error[E0597]: `x` does not live long enough
- --> $DIR/type_ascription_static_lifetime.rs:7:19
+ --> $DIR/type_ascription_static_lifetime.rs:6:19
|
LL | let y: &u32 = &x: &'static u32;
| ^^--------------
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/object-lifetime-default-elision.rs:71:5
+ |
+LL | fn load3<'a,'b>(ss: &'a SomeTrait) -> &'b SomeTrait {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | ss
+ | ^^ returning this value requires that `'a` must outlive `'b`
+
+error: aborting due to previous error
+
--- /dev/null
+error[E0621]: explicit lifetime required in the type of `ss`
+ --> $DIR/object-lifetime-default-from-box-error.rs:18:5
+ |
+LL | fn load(ss: &mut SomeStruct) -> Box<SomeTrait> {
+ | --------------- help: add explicit lifetime `'static` to the type of `ss`: `&mut SomeStruct<'static>`
+...
+LL | ss.r
+ | ^^^^ lifetime `'static` required
+
+error[E0507]: cannot move out of borrowed content
+ --> $DIR/object-lifetime-default-from-box-error.rs:18:5
+ |
+LL | ss.r
+ | ^^^^ cannot move out of borrowed content
+
+error[E0621]: explicit lifetime required in the type of `ss`
+ --> $DIR/object-lifetime-default-from-box-error.rs:31:5
+ |
+LL | fn store1<'b>(ss: &mut SomeStruct, b: Box<SomeTrait+'b>) {
+ | --------------- help: add explicit lifetime `'b` to the type of `ss`: `&mut SomeStruct<'b>`
+...
+LL | ss.r = b;
+ | ^^^^ lifetime `'b` required
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0507, E0621.
+For more information about an error, try `rustc --explain E0507`.
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/object-lifetime-default-from-rptr-box-error.rs:15:5
+ |
+LL | fn c<'a>(t: &'a Box<Test+'a>, mut ss: SomeStruct<'a>) {
+ | -- lifetime `'a` defined here
+LL | ss.t = t;
+ | ^^^^^^^^ assignment requires that `'a` must outlive `'static`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/object-lifetime-default-from-rptr-struct-error.rs:21:5
+ |
+LL | fn c<'a>(t: &'a MyBox<Test+'a>, mut ss: SomeStruct<'a>) {
+ | -- lifetime `'a` defined here
+LL | ss.t = t;
+ | ^^^^^^^^ assignment requires that `'a` must outlive `'static`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/object-lifetime-default-mybox.rs:27:5
+ |
+LL | fn load1<'a,'b>(a: &'a MyBox<SomeTrait>,
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | a
+ | ^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+
+error[E0521]: borrowed data escapes outside of function
+ --> $DIR/object-lifetime-default-mybox.rs:31:5
+ |
+LL | fn load2<'a>(ss: &MyBox<SomeTrait+'a>) -> MyBox<SomeTrait+'a> {
+ | -- `ss` is a reference that is only valid in the function body
+LL | load0(ss)
+ | ^^^^^^^^^ `ss` escapes the function body here
+
+error: aborting due to 2 previous errors
+
// ignore-musl - no dylibs here
// ignore-cloudabi
// ignore-emscripten
+// ignore-sgx no dynamic lib support
// error-pattern:`panic_unwind` is not compiled with this crate's panic strategy
// This is a test where the local crate, compiled with `panic=abort`, links to
--- /dev/null
+error[E0303]: pattern bindings are not allowed after an `@`
+ --> $DIR/pattern-bindings-after-at.rs:8:31
+ |
+LL | ref mut z @ &mut Some(ref a) => {
+ | ^^^^^ not allowed after `@`
+
+error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable
+ --> $DIR/pattern-bindings-after-at.rs:8:31
+ |
+LL | ref mut z @ &mut Some(ref a) => {
+ | ----------------------^^^^^-
+ | | |
+ | | immutable borrow occurs here
+ | mutable borrow occurs here
+...
+LL | **z = None;
+ | ---------- mutable borrow later used here
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0303, E0502.
+For more information about an error, try `rustc --explain E0303`.
Four(D)
}
+pub union Union1<A: Copy> {
+ a: A,
+}
+
+pub union Union2<A: Copy, B: Copy> {
+ a: A,
+ b: B,
+}
+
#[start]
fn start(_: isize, _: *const *const u8) -> isize {
let _x: MyOption<NonZeroU32> = Default::default();
let _e: Enum4<(), char, (), ()> = Enum4::One(());
let _f: Enum4<(), (), bool, ()> = Enum4::One(());
let _g: Enum4<(), (), (), MyOption<u8>> = Enum4::One(());
+
+ // Unions do not currently participate in niche filling.
+ let _h: MyOption<Union2<NonZeroU32, u32>> = Default::default();
+
+ // ...even when theoretically possible.
+ let _i: MyOption<Union1<NonZeroU32>> = Default::default();
+ let _j: MyOption<Union2<NonZeroU32, NonZeroU32>> = Default::default();
+
0
}
print-type-size field `.pre`: 1 bytes
print-type-size variant `None`: 0 bytes
print-type-size end padding: 1 bytes
+print-type-size type: `MyOption<Union1<std::num::NonZeroU32>>`: 8 bytes, alignment: 4 bytes
+print-type-size discriminant: 4 bytes
+print-type-size variant `Some`: 4 bytes
+print-type-size field `.0`: 4 bytes
+print-type-size variant `None`: 0 bytes
+print-type-size type: `MyOption<Union2<std::num::NonZeroU32, std::num::NonZeroU32>>`: 8 bytes, alignment: 4 bytes
+print-type-size discriminant: 4 bytes
+print-type-size variant `Some`: 4 bytes
+print-type-size field `.0`: 4 bytes
+print-type-size variant `None`: 0 bytes
+print-type-size type: `MyOption<Union2<std::num::NonZeroU32, u32>>`: 8 bytes, alignment: 4 bytes
+print-type-size discriminant: 4 bytes
+print-type-size variant `Some`: 4 bytes
+print-type-size field `.0`: 4 bytes
+print-type-size variant `None`: 0 bytes
print-type-size type: `NestedNonZero`: 8 bytes, alignment: 4 bytes
print-type-size field `.val`: 4 bytes
print-type-size field `.post`: 2 bytes
print-type-size variant `Some`: 4 bytes
print-type-size field `.0`: 4 bytes
print-type-size variant `None`: 0 bytes
+print-type-size type: `Union1<std::num::NonZeroU32>`: 4 bytes, alignment: 4 bytes
+print-type-size variant `Union1`: 4 bytes
+print-type-size field `.a`: 4 bytes
+print-type-size type: `Union2<std::num::NonZeroU32, std::num::NonZeroU32>`: 4 bytes, alignment: 4 bytes
+print-type-size variant `Union2`: 4 bytes
+print-type-size field `.a`: 4 bytes
+print-type-size field `.b`: 4 bytes, offset: 0 bytes, alignment: 4 bytes
+print-type-size type: `Union2<std::num::NonZeroU32, u32>`: 4 bytes, alignment: 4 bytes
+print-type-size variant `Union2`: 4 bytes
+print-type-size field `.a`: 4 bytes
+print-type-size field `.b`: 4 bytes, offset: 0 bytes, alignment: 4 bytes
print-type-size type: `std::num::NonZeroU32`: 4 bytes, alignment: 4 bytes
print-type-size field `.0`: 4 bytes
print-type-size type: `Enum4<(), (), (), MyOption<u8>>`: 2 bytes, alignment: 1 bytes
--- /dev/null
+error[E0005]: refutable pattern in local binding: `Err(_)` not covered
+ --> $DIR/recursive-types-are-not-uninhabited.rs:6:9
+ |
+LL | let Ok(x) = res;
+ | ^^^^^ pattern `Err(_)` not covered
+
+error[E0381]: use of possibly uninitialized variable: `x`
+ --> $DIR/recursive-types-are-not-uninhabited.rs:8:5
+ |
+LL | x
+ | ^ use of possibly uninitialized `x`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0005, E0381.
+For more information about an error, try `rustc --explain E0005`.
--- /dev/null
+error[E0521]: borrowed data escapes outside of function
+ --> $DIR/region-invariant-static-error-reporting.rs:15:9
+ |
+LL | fn unify<'a>(x: Option<Invariant<'a>>, f: fn(Invariant<'a>)) {
+ | - `x` is a reference that is only valid in the function body
+LL | let bad = if x.is_some() {
+LL | x.unwrap()
+ | ^^^^^^^^^^ `x` escapes the function body here
+
+error: aborting due to previous error
+
--- /dev/null
+error[E0308]: mismatched types
+ --> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:20:43
+ |
+LL | let _: fn(&mut &isize, &mut &isize) = a;
+ | ^ expected concrete lifetime, found bound lifetime parameter
+ |
+ = note: expected type `for<'r, 's, 't0, 't1> fn(&'r mut &'s isize, &'t0 mut &'t1 isize)`
+ found type `for<'r, 's> fn(&'r mut &isize, &'s mut &isize) {a::<'_, '_>}`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
--- /dev/null
+error[E0308]: mismatched types
+ --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:22:56
+ |
+LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a;
+ | ^ expected concrete lifetime, found bound lifetime parameter
+ |
+ = note: expected type `for<'r, 's, 't0, 't1, 't2, 't3> fn(&'r mut &'s isize, &'t0 mut &'t1 isize, &'t2 mut &'t3 isize)`
+ found type `for<'r, 's, 't0> fn(&'r mut &isize, &'s mut &isize, &'t0 mut &isize) {a::<'_, '_, '_>}`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/region-object-lifetime-2.rs:10:5
+ |
+LL | fn borrowed_receiver_different_lifetimes<'a,'b>(x: &'a Foo) -> &'b () {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | x.borrowed()
+ | ^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'b`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/region-object-lifetime-4.rs:12:5
+ |
+LL | fn borrowed_receiver_related_lifetimes2<'a,'b>(x: &'a (Foo+'b)) -> &'b () {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | x.borrowed()
+ | ^^^^^^^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+
+error: aborting due to previous error
+
--- /dev/null
+error[E0621]: explicit lifetime required in the type of `v`
+ --> $DIR/region-object-lifetime-in-coercion.rs:8:12
+ |
+LL | fn a(v: &[u8]) -> Box<Foo + 'static> {
+ | ----- help: add explicit lifetime `'static` to the type of `v`: `&'static [u8]`
+LL | let x: Box<Foo + 'static> = Box::new(v);
+ | ^^^^^^^^^^^^^^^^^^ lifetime `'static` required
+
+error[E0621]: explicit lifetime required in the type of `v`
+ --> $DIR/region-object-lifetime-in-coercion.rs:14:5
+ |
+LL | fn b(v: &[u8]) -> Box<Foo + 'static> {
+ | ----- help: add explicit lifetime `'static` to the type of `v`: `&'static [u8]`
+LL | Box::new(v)
+ | ^^^^^^^^^^^ lifetime `'static` required
+
+error[E0621]: explicit lifetime required in the type of `v`
+ --> $DIR/region-object-lifetime-in-coercion.rs:21:5
+ |
+LL | fn c(v: &[u8]) -> Box<Foo> {
+ | ----- help: add explicit lifetime `'static` to the type of `v`: `&'static [u8]`
+...
+LL | Box::new(v)
+ | ^^^^^^^^^^^ lifetime `'static` required
+
+error: lifetime may not live long enough
+ --> $DIR/region-object-lifetime-in-coercion.rs:26:5
+ |
+LL | fn d<'a,'b>(v: &'a [u8]) -> Box<Foo+'b> {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | Box::new(v)
+ | ^^^^^^^^^^^ returning this value requires that `'a` must outlive `'b`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0621`.
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-addr-of-self.rs:7:16
+ |
+LL | pub fn chase_cat(&mut self) {
+ | - let's call the lifetime of this reference `'1`
+LL | let p: &'static mut usize = &mut self.cats_chased;
+ | ^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-addr-of-upvar-self.rs:10:20
+ |
+LL | let _f = || {
+ | -- lifetime `'1` represents this closure's body
+LL | let p: &'static mut usize = &mut self.food;
+ | ^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static`
+ |
+ = note: closure implements `FnMut`, so references to captured variables can't escape the closure
+
+error: lifetime may not live long enough
+ --> $DIR/regions-addr-of-upvar-self.rs:10:20
+ |
+LL | pub fn chase_cat(&mut self) {
+ | - let's call the lifetime of this reference `'1`
+LL | let _f = || {
+LL | let p: &'static mut usize = &mut self.food;
+ | ^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static`
+
+error[E0597]: `self` does not live long enough
+ --> $DIR/regions-addr-of-upvar-self.rs:10:46
+ |
+LL | let _f = || {
+ | -- value captured here
+LL | let p: &'static mut usize = &mut self.food;
+ | ------------------ ^^^^ borrowed value does not live long enough
+ | |
+ | type annotation requires that `self` is borrowed for `'static`
+...
+LL | }
+ | - `self` dropped here while still borrowed
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:43:12
+ |
+LL | fn with_assoc<'a,'b>() {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | let _: &'a WithAssoc<TheType<'b>> = loop { };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-bounded-by-trait-requiring-static.rs:22:5
+ |
+LL | fn param_not_ok<'a>(x: &'a isize) {
+ | -- lifetime `'a` defined here
+LL | assert_send::<&'a isize>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/regions-bounded-by-trait-requiring-static.rs:26:5
+ |
+LL | fn param_not_ok1<'a>(_: &'a isize) {
+ | -- lifetime `'a` defined here
+LL | assert_send::<&'a str>();
+ | ^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/regions-bounded-by-trait-requiring-static.rs:30:5
+ |
+LL | fn param_not_ok2<'a>(_: &'a isize) {
+ | -- lifetime `'a` defined here
+LL | assert_send::<&'a [isize]>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/regions-bounded-by-trait-requiring-static.rs:44:5
+ |
+LL | fn box_with_region_not_ok<'a>() {
+ | -- lifetime `'a` defined here
+LL | assert_send::<Box<&'a isize>>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/regions-bounded-by-trait-requiring-static.rs:55:5
+ |
+LL | fn unsafe_ok2<'a>(_: &'a isize) {
+ | -- lifetime `'a` defined here
+LL | assert_send::<*const &'a isize>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/regions-bounded-by-trait-requiring-static.rs:59:5
+ |
+LL | fn unsafe_ok3<'a>(_: &'a isize) {
+ | -- lifetime `'a` defined here
+LL | assert_send::<*mut &'a isize>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
+
+error: aborting due to 6 previous errors
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-bounded-method-type-parameters-cross-crate.rs:20:5
+ |
+LL | fn call_bigger_region<'x, 'y>(a: Inv<'x>, b: Inv<'y>) {
+ | -- -- lifetime `'y` defined here
+ | |
+ | lifetime `'x` defined here
+LL | // Here the value provided for 'y is 'y, and hence 'y:'x does not hold.
+LL | a.bigger_region(b)
+ | ^^^^^^^^^^^^^^^^^^ argument requires that `'y` must outlive `'x`
+
+error: aborting due to previous error
+
--- /dev/null
+error[E0521]: borrowed data escapes outside of function
+ --> $DIR/regions-bounded-method-type-parameters-trait-bound.rs:20:5
+ |
+LL | fn caller2<'a,'b,F:Foo<'a>>(a: Inv<'a>, b: Inv<'b>, f: F) {
+ | - - `b` is a reference that is only valid in the function body
+ | |
+ | `a` is declared here, outside of the function body
+LL | // Here the value provided for 'y is 'b, and hence 'b:'a does not hold.
+LL | f.method(b);
+ | ^^^^^^^^^^^ `b` escapes the function body here
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-bounded-method-type-parameters.rs:12:9
+ |
+LL | fn caller<'a>(x: &isize) {
+ | -- lifetime `'a` defined here
+LL | Foo.some_method::<&'a isize>();
+ | ^^^^^^^^^^^ requires that `'a` must outlive `'static`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-bounds.rs:9:12
+ |
+LL | fn a_fn1<'a,'b>(e: TupleStruct<'a>) -> TupleStruct<'b> {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | return e;
+ | ^ returning this value requires that `'a` must outlive `'b`
+
+error: lifetime may not live long enough
+ --> $DIR/regions-bounds.rs:13:12
+ |
+LL | fn a_fn3<'a,'b>(e: Struct<'a>) -> Struct<'b> {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | return e;
+ | ^ returning this value requires that `'a` must outlive `'b`
+
+error: aborting due to 2 previous errors
+
--- /dev/null
+error[E0310]: the associated type `<T as Iter>::Item` may not live long enough
+ --> $DIR/regions-close-associated-type-into-object.rs:15:5
+ |
+LL | Box::new(item)
+ | ^^^^^^^^^^^^^^
+ |
+ = help: consider adding an explicit lifetime bound `<T as Iter>::Item: 'static`...
+
+error[E0310]: the associated type `<T as Iter>::Item` may not live long enough
+ --> $DIR/regions-close-associated-type-into-object.rs:22:5
+ |
+LL | Box::new(item)
+ | ^^^^^^^^^^^^^^
+ |
+ = help: consider adding an explicit lifetime bound `<T as Iter>::Item: 'static`...
+
+error[E0309]: the associated type `<T as Iter>::Item` may not live long enough
+ --> $DIR/regions-close-associated-type-into-object.rs:28:5
+ |
+LL | Box::new(item)
+ | ^^^^^^^^^^^^^^
+ |
+ = help: consider adding an explicit lifetime bound `<T as Iter>::Item: 'a`...
+
+error[E0309]: the associated type `<T as Iter>::Item` may not live long enough
+ --> $DIR/regions-close-associated-type-into-object.rs:35:5
+ |
+LL | Box::new(item)
+ | ^^^^^^^^^^^^^^
+ |
+ = help: consider adding an explicit lifetime bound `<T as Iter>::Item: 'a`...
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0309, E0310.
+For more information about an error, try `rustc --explain E0309`.
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-close-object-into-object-2.rs:10:5
+ |
+LL | fn g<'a, T: 'static>(v: Box<A<T>+'a>) -> Box<X+'static> {
+ | -- lifetime `'a` defined here
+LL | box B(&*v) as Box<X>
+ | ^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+
+error[E0515]: cannot return value referencing local data `*v`
+ --> $DIR/regions-close-object-into-object-2.rs:10:5
+ |
+LL | box B(&*v) as Box<X>
+ | ^^^^^^---^^^^^^^^^^^
+ | | |
+ | | `*v` is borrowed here
+ | returns a value referencing data owned by the current function
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0515`.
--- /dev/null
+error[E0310]: the parameter type `U` may not live long enough
+ --> $DIR/regions-close-object-into-object-4.rs:10:5
+ |
+LL | box B(&*v) as Box<X>
+ | ^^^^^^^^^^
+ |
+ = help: consider adding an explicit lifetime bound `U: 'static`...
+
+error: lifetime may not live long enough
+ --> $DIR/regions-close-object-into-object-4.rs:10:5
+ |
+LL | fn i<'a, T, U>(v: Box<A<U>+'a>) -> Box<X+'static> {
+ | -- lifetime `'a` defined here
+LL | box B(&*v) as Box<X>
+ | ^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+
+error[E0515]: cannot return value referencing local data `*v`
+ --> $DIR/regions-close-object-into-object-4.rs:10:5
+ |
+LL | box B(&*v) as Box<X>
+ | ^^^^^^---^^^^^^^^^^^
+ | | |
+ | | `*v` is borrowed here
+ | returns a value referencing data owned by the current function
+
+error[E0310]: the parameter type `U` may not live long enough
+ --> $DIR/regions-close-object-into-object-4.rs:10:9
+ |
+LL | box B(&*v) as Box<X>
+ | ^^^^^^
+ |
+ = help: consider adding an explicit lifetime bound `U: 'static`...
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0310, E0515.
+For more information about an error, try `rustc --explain E0310`.
--- /dev/null
+error[E0310]: the parameter type `T` may not live long enough
+ --> $DIR/regions-close-object-into-object-5.rs:17:5
+ |
+LL | box B(&*v) as Box<X>
+ | ^^^^^^^^^^
+ |
+ = help: consider adding an explicit lifetime bound `T: 'static`...
+
+error[E0515]: cannot return value referencing local data `*v`
+ --> $DIR/regions-close-object-into-object-5.rs:17:5
+ |
+LL | box B(&*v) as Box<X>
+ | ^^^^^^---^^^^^^^^^^^
+ | | |
+ | | `*v` is borrowed here
+ | returns a value referencing data owned by the current function
+
+error[E0310]: the parameter type `T` may not live long enough
+ --> $DIR/regions-close-object-into-object-5.rs:17:9
+ |
+LL | box B(&*v) as Box<X>
+ | ^^^^^^
+ |
+ = help: consider adding an explicit lifetime bound `T: 'static`...
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0310, E0515.
+For more information about an error, try `rustc --explain E0310`.
--- /dev/null
+error[E0310]: the parameter type `A` may not live long enough
+ --> $DIR/regions-close-over-type-parameter-1.rs:10:5
+ |
+LL | box v as Box<SomeTrait+'static>
+ | ^^^^^
+ |
+ = help: consider adding an explicit lifetime bound `A: 'static`...
+
+error[E0309]: the parameter type `A` may not live long enough
+ --> $DIR/regions-close-over-type-parameter-1.rs:20:5
+ |
+LL | box v as Box<SomeTrait+'b>
+ | ^^^^^
+ |
+ = help: consider adding an explicit lifetime bound `A: 'b`...
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0309, E0310.
+For more information about an error, try `rustc --explain E0309`.
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-close-over-type-parameter-multiple.rs:20:5
+ |
+LL | fn make_object_bad<'a,'b,'c,A:SomeTrait+'a+'b>(v: A) -> Box<SomeTrait+'c> {
+ | -- -- lifetime `'c` defined here
+ | |
+ | lifetime `'a` defined here
+LL | // A outlives 'a AND 'b...but not 'c.
+LL | box v as Box<SomeTrait+'a>
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'c`
+
+error: aborting due to previous error
+
--- /dev/null
+error[E0310]: the parameter type `T` may not live long enough
+ --> $DIR/regions-close-param-into-object.rs:6:5
+ |
+LL | Box::new(v)
+ | ^^^^^^^^^^^
+ |
+ = help: consider adding an explicit lifetime bound `T: 'static`...
+
+error[E0310]: the parameter type `T` may not live long enough
+ --> $DIR/regions-close-param-into-object.rs:12:5
+ |
+LL | Box::new(v)
+ | ^^^^^^^^^^^
+ |
+ = help: consider adding an explicit lifetime bound `T: 'static`...
+
+error[E0309]: the parameter type `T` may not live long enough
+ --> $DIR/regions-close-param-into-object.rs:18:5
+ |
+LL | Box::new(v)
+ | ^^^^^^^^^^^
+ |
+ = help: consider adding an explicit lifetime bound `T: 'a`...
+
+error[E0309]: the parameter type `T` may not live long enough
+ --> $DIR/regions-close-param-into-object.rs:24:5
+ |
+LL | Box::new(v)
+ | ^^^^^^^^^^^
+ |
+ = help: consider adding an explicit lifetime bound `T: 'a`...
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0309, E0310.
+For more information about an error, try `rustc --explain E0309`.
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-creating-enums3.rs:7:5
+ |
+LL | fn mk_add_bad1<'a,'b>(x: &'a Ast<'a>, y: &'b Ast<'b>) -> Ast<'a> {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | Ast::Add(x, y)
+ | ^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-creating-enums4.rs:7:5
+ |
+LL | fn mk_add_bad2<'a,'b>(x: &'a Ast<'a>, y: &'a Ast<'a>, z: &Ast) -> Ast<'b> {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | Ast::Add(x, y)
+ | ^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'b`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-early-bound-error-method.rs:20:9
+ |
+LL | impl<'a> Box<'a> {
+ | -- lifetime `'a` defined here
+LL | fn or<'b,G:GetRef<'b>>(&self, g2: G) -> &'a isize {
+ | -- lifetime `'b` defined here
+LL | g2.get()
+ | ^^^^^^^^ returning this value requires that `'b` must outlive `'a`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-early-bound-error.rs:19:5
+ |
+LL | fn get<'a,'b,G:GetRef<'a, isize>>(g1: G, b: &'b isize) -> &'b isize {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | g1.get()
+ | ^^^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-escape-method.rs:15:13
+ |
+LL | s.f(|p| p)
+ | -- ^ returning this value requires that `'1` must outlive `'2`
+ | ||
+ | |return type of closure is &'2 i32
+ | has type `&'1 i32`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-escape-via-trait-or-not.rs:18:14
+ |
+LL | with(|o| o)
+ | -- ^ returning this value requires that `'1` must outlive `'2`
+ | ||
+ | |return type of closure is &'2 isize
+ | has type `&'1 isize`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-free-region-ordering-callee.rs:13:5
+ |
+LL | fn ordering2<'a, 'b>(x: &'a &'b usize, y: &'a usize) -> &'b usize {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | // However, it is not safe to assume that 'b <= 'a
+LL | &*y
+ | ^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+
+error: lifetime may not live long enough
+ --> $DIR/regions-free-region-ordering-callee.rs:18:12
+ |
+LL | fn ordering3<'a, 'b>(x: &'a usize, y: &'b usize) -> &'a &'b usize {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | // Do not infer an ordering from the return value.
+LL | let z: &'b usize = &*x;
+ | ^^^^^^^^^ type annotation requires that `'a` must outlive `'b`
+
+error: aborting due to 2 previous errors
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-free-region-ordering-caller.rs:11:12
+ |
+LL | fn call2<'a, 'b>(a: &'a usize, b: &'b usize) {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | let z: Option<&'b &'a usize> = None;
+ | ^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'b`
+
+error: lifetime may not live long enough
+ --> $DIR/regions-free-region-ordering-caller.rs:17:12
+ |
+LL | fn call3<'a, 'b>(a: &'a usize, b: &'b usize) {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | let y: Paramd<'a> = Paramd { x: a };
+LL | let z: Option<&'b Paramd<'a>> = None;
+ | ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'b`
+
+error: lifetime may not live long enough
+ --> $DIR/regions-free-region-ordering-caller.rs:22:12
+ |
+LL | fn call4<'a, 'b>(a: &'a usize, b: &'b usize) {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | let z: Option<&'a &'b usize> = None;
+ | ^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
+
+error: aborting due to 3 previous errors
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-free-region-ordering-incorrect.rs:15:9
+ |
+LL | impl<'b, T> Node<'b, T> {
+ | -- lifetime `'b` defined here
+LL | fn get<'a>(&'a self) -> &'b T {
+ | -- lifetime `'a` defined here
+LL | / match self.next {
+LL | | Some(ref next) => next.get(),
+LL | | None => &self.val
+LL | | }
+ | |_________^ returning this value requires that `'a` must outlive `'b`
+
+error: aborting due to previous error
+
--- /dev/null
+error[E0309]: the parameter type `T` may not live long enough
+ --> $DIR/regions-implied-bounds-projection-gap-1.rs:16:5
+ |
+LL | wf::<&'x T>();
+ | ^^^^^^^^^^^
+ |
+ = help: consider adding an explicit lifetime bound `T: 'x`...
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0309`.
--- /dev/null
+error[E0309]: the parameter type `Self` may not live long enough
+ --> $DIR/regions-infer-bound-from-trait-self.rs:46:9
+ |
+LL | check_bound(x, self)
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider adding an explicit lifetime bound `Self: 'a`...
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0309`.
--- /dev/null
+error[E0309]: the parameter type `A` may not live long enough
+ --> $DIR/regions-infer-bound-from-trait.rs:33:5
+ |
+LL | check_bound(x, a)
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider adding an explicit lifetime bound `A: 'a`...
+
+error[E0309]: the parameter type `A` may not live long enough
+ --> $DIR/regions-infer-bound-from-trait.rs:37:5
+ |
+LL | check_bound(x, a)
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = help: consider adding an explicit lifetime bound `A: 'a`...
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0309`.
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-infer-call-3.rs:8:24
+ |
+LL | let z = with(|y| { select(x, y) });
+ | -- ^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2`
+ | ||
+ | |return type of closure is &'2 isize
+ | has type `&'1 isize`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-infer-contravariance-due-to-decl.rs:25:12
+ |
+LL | fn use_<'short,'long>(c: Contravariant<'short>,
+ | ------ ----- lifetime `'long` defined here
+ | |
+ | lifetime `'short` defined here
+...
+LL | let _: Contravariant<'long> = c;
+ | ^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-infer-covariance-due-to-decl.rs:22:12
+ |
+LL | fn use_<'short,'long>(c: Covariant<'long>,
+ | ------ ----- lifetime `'long` defined here
+ | |
+ | lifetime `'short` defined here
+...
+LL | let _: Covariant<'short> = c;
+ | ^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-infer-invariance-due-to-decl.rs:12:5
+ |
+LL | fn to_longer_lifetime<'r>(b_isize: Invariant<'r>) -> Invariant<'static> {
+ | -- lifetime `'r` defined here
+LL | b_isize
+ | ^^^^^^^ returning this value requires that `'r` must outlive `'static`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-infer-invariance-due-to-mutability-3.rs:10:5
+ |
+LL | fn to_longer_lifetime<'r>(b_isize: Invariant<'r>) -> Invariant<'static> {
+ | -- lifetime `'r` defined here
+LL | b_isize
+ | ^^^^^^^ returning this value requires that `'r` must outlive `'static`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-infer-invariance-due-to-mutability-4.rs:10:5
+ |
+LL | fn to_longer_lifetime<'r>(b_isize: Invariant<'r>) -> Invariant<'static> {
+ | -- lifetime `'r` defined here
+LL | b_isize
+ | ^^^^^^^ returning this value requires that `'r` must outlive `'static`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-infer-not-param.rs:15:54
+ |
+LL | fn take_direct<'a,'b>(p: Direct<'a>) -> Direct<'b> { p }
+ | -- -- lifetime `'b` defined here ^ returning this value requires that `'a` must outlive `'b`
+ | |
+ | lifetime `'a` defined here
+
+error: lifetime may not live long enough
+ --> $DIR/regions-infer-not-param.rs:19:63
+ |
+LL | fn take_indirect2<'a,'b>(p: Indirect2<'a>) -> Indirect2<'b> { p }
+ | -- -- lifetime `'b` defined here ^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
+ | |
+ | lifetime `'a` defined here
+
+error: lifetime may not live long enough
+ --> $DIR/regions-infer-not-param.rs:19:63
+ |
+LL | fn take_indirect2<'a,'b>(p: Indirect2<'a>) -> Indirect2<'b> { p }
+ | -- -- lifetime `'b` defined here ^ returning this value requires that `'a` must outlive `'b`
+ | |
+ | lifetime `'a` defined here
+
+error: aborting due to 3 previous errors
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-infer-paramd-indirect.rs:22:9
+ |
+LL | impl<'a> SetF<'a> for C<'a> {
+ | -- lifetime `'a` defined here
+...
+LL | fn set_f_bad(&mut self, b: Box<B>) {
+ | - has type `std::boxed::Box<std::boxed::Box<&'1 isize>>`
+LL | self.f = b;
+ | ^^^^^^ assignment requires that `'1` must outlive `'a`
+
+error: aborting due to previous error
+
--- /dev/null
+error[E0308]: mismatched types
+ --> $DIR/regions-lifetime-bounds-on-fns.rs:20:43
+ |
+LL | let _: fn(&mut &isize, &mut &isize) = a;
+ | ^ expected concrete lifetime, found bound lifetime parameter
+ |
+ = note: expected type `for<'r, 's, 't0, 't1> fn(&'r mut &'s isize, &'t0 mut &'t1 isize)`
+ found type `for<'r, 's> fn(&'r mut &isize, &'s mut &isize) {a::<'_, '_>}`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
--- /dev/null
+error[E0521]: borrowed data escapes outside of closure
+ --> $DIR/regions-nested-fns.rs:10:9
+ |
+LL | let mut ay = &y;
+ | ------ `ay` is declared here, outside of the closure body
+LL |
+LL | ignore::<Box<for<'z> FnMut(&'z isize)>>(Box::new(|z| {
+ | - `z` is a reference that is only valid in the closure body
+...
+LL | ay = z;
+ | ^^^^^^ `z` escapes the closure body here
+
+error[E0597]: `y` does not live long enough
+ --> $DIR/regions-nested-fns.rs:5:18
+ |
+LL | let mut ay = &y;
+ | ^^ borrowed value does not live long enough
+...
+LL | if false { return ay; }
+ | -- returning this value requires that `y` is borrowed for `'static`
+...
+LL | }
+ | - `y` dropped here while still borrowed
+
+error[E0597]: `y` does not live long enough
+ --> $DIR/regions-nested-fns.rs:9:15
+ |
+LL | ignore::<Box<for<'z> FnMut(&'z isize)>>(Box::new(|z| {
+ | --- value captured here
+LL | ay = x;
+LL | ay = &y;
+ | ^ borrowed value does not live long enough
+...
+LL | if false { return ay; }
+ | -- returning this value requires that `y` is borrowed for `'static`
+...
+LL | }
+ | - `y` dropped here while still borrowed
+
+error: lifetime may not live long enough
+ --> $DIR/regions-nested-fns.rs:14:27
+ |
+LL | fn nested<'x>(x: &'x isize) {
+ | -- lifetime `'x` defined here
+...
+LL | if false { return x; }
+ | ^ returning this value requires that `'x` must outlive `'static`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-outlives-projection-container-hrtb.rs:35:12
+ |
+LL | fn with_assoc<'a,'b>() {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | let _: &'a WithHrAssoc<TheType<'b>> = loop { };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
+
+error: lifetime may not live long enough
+ --> $DIR/regions-outlives-projection-container-hrtb.rs:57:12
+ |
+LL | fn with_assoc_sub<'a,'b>() {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | let _: &'a WithHrAssocSub<TheType<'b>> = loop { };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
+
+error: aborting due to 2 previous errors
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-outlives-projection-container-wc.rs:37:12
+ |
+LL | fn with_assoc<'a,'b>() {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | let _: &'a WithAssoc<TheType<'b>> = loop { };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-outlives-projection-container.rs:40:13
+ |
+LL | fn with_assoc<'a,'b>() {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | let _x: &'a WithAssoc<TheType<'b>> = loop { };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
+
+error: lifetime may not live long enough
+ --> $DIR/regions-outlives-projection-container.rs:58:13
+ |
+LL | fn without_assoc<'a,'b>() {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | let _x: &'a WithoutAssoc<TheType<'b>> = loop { };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
+
+error: lifetime may not live long enough
+ --> $DIR/regions-outlives-projection-container.rs:67:5
+ |
+LL | fn call_with_assoc<'a,'b>() {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | call::<&'a WithAssoc<TheType<'b>>>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'a`
+
+error: lifetime may not live long enough
+ --> $DIR/regions-outlives-projection-container.rs:74:5
+ |
+LL | fn call_without_assoc<'a,'b>() {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | call::<&'a WithoutAssoc<TheType<'b>>>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'a`
+
+error: aborting due to 4 previous errors
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-reborrow-from-shorter-mut-ref-mut-ref.rs:4:5
+ |
+LL | fn copy_borrowed_ptr<'a, 'b, 'c>(p: &'a mut &'b mut &'c mut isize) -> &'b mut isize {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | &mut ***p
+ | ^^^^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-reborrow-from-shorter-mut-ref.rs:6:5
+ |
+LL | fn copy_borrowed_ptr<'a, 'b>(p: &'a mut &'b mut isize) -> &'b mut isize {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | &mut **p
+ | ^^^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-ret-borrowed-1.rs:10:14
+ |
+LL | with(|o| o)
+ | -- ^ returning this value requires that `'1` must outlive `'2`
+ | ||
+ | |return type of closure is &'2 isize
+ | has type `&'1 isize`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-ret-borrowed.rs:13:14
+ |
+LL | with(|o| o)
+ | -- ^ returning this value requires that `'1` must outlive `'2`
+ | ||
+ | |return type of closure is &'2 isize
+ | has type `&'1 isize`
+
+error: aborting due to previous error
+
--- /dev/null
+error: captured variable cannot escape `FnMut` closure body
+ --> $DIR/regions-return-ref-to-upvar-issue-17403.rs:7:24
+ |
+LL | let mut f = || &mut x;
+ | - ^^^^^^ returns a reference to a captured variable which escapes the closure body
+ | |
+ | inferred to be a `FnMut` closure
+ |
+ = note: `FnMut` closures only have access to their captured variables while they are executing...
+ = note: ...therefore, they cannot allow references to captured variables to escape
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-static-bound.rs:9:5
+ |
+LL | fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a {
+ | -- lifetime `'a` defined here
+LL | t //[ll]~ ERROR E0312
+ | ^ returning this value requires that `'a` must outlive `'static`
+
+error[E0621]: explicit lifetime required in the type of `u`
+ --> $DIR/regions-static-bound.rs:14:5
+ |
+LL | fn error(u: &(), v: &()) {
+ | --- help: add explicit lifetime `'static` to the type of `u`: `&'static ()`
+LL | static_id(&u); //[ll]~ ERROR explicit lifetime required in the type of `u` [E0621]
+ | ^^^^^^^^^^^^^ lifetime `'static` required
+
+error[E0621]: explicit lifetime required in the type of `v`
+ --> $DIR/regions-static-bound.rs:16:5
+ |
+LL | fn error(u: &(), v: &()) {
+ | --- help: add explicit lifetime `'static` to the type of `v`: `&'static ()`
+...
+LL | static_id_indirect(&v); //[ll]~ ERROR explicit lifetime required in the type of `v` [E0621]
+ | ^^^^^^^^^^^^^^^^^^^^^^ lifetime `'static` required
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0621`.
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-static-bound.rs:9:5
+ |
+LL | fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a {
+ | -- lifetime `'a` defined here
+LL | t
+ | ^ returning this value requires that `'a` must outlive `'static`
+
+error[E0621]: explicit lifetime required in the type of `u`
+ --> $DIR/regions-static-bound.rs:14:5
+ |
+LL | fn error(u: &(), v: &()) {
+ | --- help: add explicit lifetime `'static` to the type of `u`: `&'static ()`
+LL | static_id(&u);
+ | ^^^^^^^^^^^^^ lifetime `'static` required
+
+error[E0621]: explicit lifetime required in the type of `v`
+ --> $DIR/regions-static-bound.rs:16:5
+ |
+LL | fn error(u: &(), v: &()) {
+ | --- help: add explicit lifetime `'static` to the type of `v`: `&'static ()`
+...
+LL | static_id_indirect(&v);
+ | ^^^^^^^^^^^^^^^^^^^^^^ lifetime `'static` required
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0621`.
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-trait-object-subtyping.rs:15:5
+ |
+LL | fn foo3<'a,'b>(x: &'a mut Dummy) -> &'b mut Dummy {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | // Without knowing 'a:'b, we can't coerce
+LL | x
+ | ^ returning this value requires that `'a` must outlive `'b`
+
+error: lifetime may not live long enough
+ --> $DIR/regions-trait-object-subtyping.rs:22:5
+ |
+LL | fn foo4<'a:'b,'b>(x: Wrapper<&'a mut Dummy>) -> Wrapper<&'b mut Dummy> {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | // We can't coerce because it is packed in `Wrapper`
+LL | x
+ | ^ returning this value requires that `'b` must outlive `'a`
+
+error: aborting due to 2 previous errors
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-variance-contravariant-use-covariant-in-second-position.rs:25:12
+ |
+LL | fn use_<'short,'long>(c: S<'long, 'short>,
+ | ------ ----- lifetime `'long` defined here
+ | |
+ | lifetime `'short` defined here
+...
+LL | let _: S<'long, 'long> = c;
+ | ^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-variance-contravariant-use-covariant.rs:23:12
+ |
+LL | fn use_<'short,'long>(c: Contravariant<'short>,
+ | ------ ----- lifetime `'long` defined here
+ | |
+ | lifetime `'short` defined here
+...
+LL | let _: Contravariant<'long> = c;
+ | ^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-variance-covariant-use-contravariant.rs:23:12
+ |
+LL | fn use_<'short,'long>(c: Covariant<'long>,
+ | ------ ----- lifetime `'long` defined here
+ | |
+ | lifetime `'short` defined here
+...
+LL | let _: Covariant<'short> = c;
+ | ^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-variance-invariant-use-contravariant.rs:20:12
+ |
+LL | fn use_<'short,'long>(c: Invariant<'long>,
+ | ------ ----- lifetime `'long` defined here
+ | |
+ | lifetime `'short` defined here
+...
+LL | let _: Invariant<'short> = c;
+ | ^^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/regions-variance-invariant-use-covariant.rs:17:12
+ |
+LL | fn use_<'b>(c: Invariant<'b>) {
+ | -- lifetime `'b` defined here
+...
+LL | let _: Invariant<'static> = c;
+ | ^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'static`
+
+error: aborting due to previous error
+
// compile-pass
-#![feature(nll)]
#![feature(bind_by_move_pattern_guards)]
use std::sync::mpsc::channel;
-#![feature(nll)]
#![feature(bind_by_move_pattern_guards)]
// compile-pass
--- /dev/null
+error[E0502]: cannot borrow `foo` as mutable because it is also borrowed as immutable
+ --> $DIR/borrowck-issue-49631.rs:20:9
+ |
+LL | while let Some(Ok(string)) = foo.get() {
+ | --- immutable borrow occurs here
+LL | foo.mutate();
+ | ^^^ mutable borrow occurs here
+LL |
+LL | println!("foo={:?}", *string);
+ | ------- immutable borrow later used here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0502`.
// run-pass
// ignore-cloudabi no processes
// ignore-emscripten no processes
+// ignore-sgx no processes
// Tests ensuring that `dbg!(expr)` has the expected run-time behavior.
// as well as some compile time properties we expect.
fn validate_stderr(stderr: Vec<String>) {
assert_eq!(stderr, &[
- ":21] Unit = Unit",
+ ":22] Unit = Unit",
- ":22] a = Unit",
+ ":23] a = Unit",
- ":28] Point{x: 42, y: 24,} = Point {",
+ ":29] Point{x: 42, y: 24,} = Point {",
" x: 42,",
" y: 24,",
"}",
- ":29] b = Point {",
+ ":30] b = Point {",
" x: 42,",
" y: 24,",
"}",
- ":37]",
+ ":38]",
- ":41] &a = NoCopy(",
+ ":42] &a = NoCopy(",
" 1337,",
")",
- ":41] dbg!(& a) = NoCopy(",
+ ":42] dbg!(& a) = NoCopy(",
" 1337,",
")",
- ":46] f(&42) = 42",
+ ":47] f(&42) = 42",
"before",
- ":51] { foo += 1; eprintln!(\"before\"); 7331 } = 7331",
+ ":52] { foo += 1; eprintln!(\"before\"); 7331 } = 7331",
- ":59] (\"Yeah\",) = (",
+ ":60] (\"Yeah\",) = (",
" \"Yeah\",",
")",
- ":62] 1 = 1",
- ":62] 2 = 2",
+ ":63] 1 = 1",
+ ":63] 2 = 2",
- ":66] 1u8 = 1",
- ":66] 2u32 = 2",
- ":66] \"Yeah\" = \"Yeah\"",
+ ":67] 1u8 = 1",
+ ":67] 2u32 = 2",
+ ":67] \"Yeah\" = \"Yeah\"",
]);
}
//~^ ERROR unused extern crate
-use edition_lint_paths as bar;
-//~^ ERROR `extern crate` is not idiomatic in the new edition
+// Shouldn't suggest changing to `use`, as `bar`
+// would no longer be added to the prelude which could cause
+// compilation errors for imports that use `bar` in other
+// modules. See #57672.
+extern crate edition_lint_paths as bar;
fn main() {
// This is not considered to *use* the `extern crate` in Rust 2018:
extern crate edition_lint_paths;
//~^ ERROR unused extern crate
+// Shouldn't suggest changing to `use`, as `bar`
+// would no longer be added to the prelude which could cause
+// compilation errors for imports that use `bar` in other
+// modules. See #57672.
extern crate edition_lint_paths as bar;
-//~^ ERROR `extern crate` is not idiomatic in the new edition
fn main() {
// This is not considered to *use* the `extern crate` in Rust 2018:
| ^^^^^^^^^^^^^^^^
= note: #[deny(unused_extern_crates)] implied by #[deny(rust_2018_idioms)]
-error: `extern crate` is not idiomatic in the new edition
- --> $DIR/extern-crate-idiomatic-in-2018.rs:15:1
- |
-LL | extern crate edition_lint_paths as bar;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `use`
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
#![warn(rust_2018_idioms)]
-use core as another_name;
+// Shouldn't suggest changing to `use`, as `another_name`
+// would no longer be added to the prelude which could cause
+// compilation errors for imports that use `another_name` in other
+// modules. See #57672.
+extern crate core as another_name;
use remove_extern_crate;
#[macro_use]
extern crate remove_extern_crate as something_else;
#![warn(rust_2018_idioms)]
extern crate core;
+// Shouldn't suggest changing to `use`, as `another_name`
+// would no longer be added to the prelude which could cause
+// compilation errors for imports that use `another_name` in other
+// modules. See #57672.
extern crate core as another_name;
use remove_extern_crate;
#[macro_use]
= note: #[warn(unused_extern_crates)] implied by #[warn(rust_2018_idioms)]
warning: `extern crate` is not idiomatic in the new edition
- --> $DIR/remove-extern-crate.rs:10:1
- |
-LL | extern crate core as another_name;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `use`
-
-warning: `extern crate` is not idiomatic in the new edition
- --> $DIR/remove-extern-crate.rs:28:5
+ --> $DIR/remove-extern-crate.rs:32:5
|
LL | extern crate core;
| ^^^^^^^^^^^^^^^^^^ help: convert it to a `use`
--- /dev/null
+#![feature(arbitrary_self_types)]
+
+use std::rc::Rc;
+
+trait Foo {
+ fn foo(self: &Rc<Self>) -> usize;
+}
+
+trait Bar {
+ fn foo(self: &Rc<Self>) -> usize where Self: Sized;
+ fn bar(self: Rc<Self>) -> usize;
+}
+
+impl Foo for usize {
+ fn foo(self: &Rc<Self>) -> usize {
+ **self
+ }
+}
+
+impl Bar for usize {
+ fn foo(self: &Rc<Self>) -> usize {
+ **self
+ }
+
+ fn bar(self: Rc<Self>) -> usize {
+ *self
+ }
+}
+
+fn make_foo() {
+ let x = Rc::new(5usize) as Rc<Foo>;
+ //~^ ERROR E0038
+ //~| ERROR E0038
+}
+
+fn make_bar() {
+ let x = Rc::new(5usize) as Rc<Bar>;
+ x.bar();
+}
+
+fn main() {}
--- /dev/null
+error[E0038]: the trait `Foo` cannot be made into an object
+ --> $DIR/arbitrary-self-types-not-object-safe.rs:31:32
+ |
+LL | let x = Rc::new(5usize) as Rc<Foo>;
+ | ^^^^^^^ the trait `Foo` cannot be made into an object
+ |
+ = note: method `foo`'s receiver cannot be dispatched on
+
+error[E0038]: the trait `Foo` cannot be made into an object
+ --> $DIR/arbitrary-self-types-not-object-safe.rs:31:13
+ |
+LL | let x = Rc::new(5usize) as Rc<Foo>;
+ | ^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object
+ |
+ = note: method `foo`'s receiver cannot be dispatched on
+ = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<std::rc::Rc<dyn Foo>>` for `std::rc::Rc<usize>`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0038`.
--- /dev/null
+// run-pass
+#![feature(arbitrary_self_types, unsize, coerce_unsized, dispatch_from_dyn)]
+#![feature(rustc_attrs)]
+
+use std::{
+ ops::{Deref, CoerceUnsized, DispatchFromDyn},
+ marker::Unsize,
+};
+
+struct Ptr<T: ?Sized>(Box<T>);
+
+impl<T: ?Sized> Deref for Ptr<T> {
+ type Target = T;
+
+ fn deref(&self) -> &T {
+ &*self.0
+ }
+}
+
+impl<T: Unsize<U> + ?Sized, U: ?Sized> CoerceUnsized<Ptr<U>> for Ptr<T> {}
+impl<T: Unsize<U> + ?Sized, U: ?Sized> DispatchFromDyn<Ptr<U>> for Ptr<T> {}
+
+struct Wrapper<T: ?Sized>(T);
+
+impl<T: ?Sized> Deref for Wrapper<T> {
+ type Target = T;
+
+ fn deref(&self) -> &T {
+ &self.0
+ }
+}
+
+impl<T: CoerceUnsized<U>, U> CoerceUnsized<Wrapper<U>> for Wrapper<T> {}
+impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<Wrapper<U>> for Wrapper<T> {}
+
+
+trait Trait {
+ // This method isn't object-safe yet. Unsized by-value `self` is object-safe (but not callable
+ // without unsized_locals), but wrappers arond `Self` currently are not.
+ // FIXME (mikeyhew) uncomment this when unsized rvalues object-safety is implemented
+ // fn wrapper(self: Wrapper<Self>) -> i32;
+ fn ptr_wrapper(self: Ptr<Wrapper<Self>>) -> i32;
+ fn wrapper_ptr(self: Wrapper<Ptr<Self>>) -> i32;
+ fn wrapper_ptr_wrapper(self: Wrapper<Ptr<Wrapper<Self>>>) -> i32;
+}
+
+impl Trait for i32 {
+ fn ptr_wrapper(self: Ptr<Wrapper<Self>>) -> i32 {
+ **self
+ }
+ fn wrapper_ptr(self: Wrapper<Ptr<Self>>) -> i32 {
+ **self
+ }
+ fn wrapper_ptr_wrapper(self: Wrapper<Ptr<Wrapper<Self>>>) -> i32 {
+ ***self
+ }
+}
+
+fn main() {
+ let pw = Ptr(Box::new(Wrapper(5))) as Ptr<Wrapper<dyn Trait>>;
+ assert_eq!(pw.ptr_wrapper(), 5);
+
+ let wp = Wrapper(Ptr(Box::new(6))) as Wrapper<Ptr<dyn Trait>>;
+ assert_eq!(wp.wrapper_ptr(), 6);
+
+ let wpw = Wrapper(Ptr(Box::new(Wrapper(7)))) as Wrapper<Ptr<Wrapper<dyn Trait>>>;
+ assert_eq!(wpw.wrapper_ptr_wrapper(), 7);
+}
--- /dev/null
+// run-pass
+#![feature(arbitrary_self_types)]
+
+use std::rc::Rc;
+
+struct Foo(String);
+
+impl Foo {
+ unsafe fn foo(self: *const Self) -> *const str {
+ (*self).0.as_ref()
+ }
+
+ fn complicated_1(self: *const Rc<Self>) -> &'static str {
+ "Foo::complicated_1"
+ }
+
+ unsafe fn complicated_2(self: Rc<*const Self>) -> *const str {
+ (**self).0.as_ref()
+ }
+}
+
+fn main() {
+ let foo = Foo("abc123".into());
+ assert_eq!("abc123", unsafe { &*(&foo as *const Foo).foo() });
+ assert_eq!("Foo::complicated_1", std::ptr::null::<Rc<Foo>>().complicated_1());
+ let rc = Rc::new(&foo as *const Foo);
+ assert_eq!("abc123", unsafe { &*rc.complicated_2()});
+}
--- /dev/null
+// run-pass
+#![feature(arbitrary_self_types)]
+
+use std::ptr;
+
+trait Foo {
+ fn foo(self: *const Self) -> &'static str;
+
+ unsafe fn bar(self: *const Self) -> i64;
+
+ unsafe fn complicated(self: *const *const Self) -> i64 where Self: Sized {
+ (*self).bar()
+ }
+}
+
+impl Foo for i32 {
+ fn foo(self: *const Self) -> &'static str {
+ "I'm an i32!"
+ }
+
+ unsafe fn bar(self: *const Self) -> i64 {
+ *self as i64
+ }
+}
+
+impl Foo for u32 {
+ fn foo(self: *const Self) -> &'static str {
+ "I'm a u32!"
+ }
+
+ unsafe fn bar(self: *const Self) -> i64 {
+ *self as i64
+ }
+}
+
+fn main() {
+ let null_i32 = ptr::null::<i32>() as *const Foo;
+ let null_u32 = ptr::null::<u32>() as *const Foo;
+
+ assert_eq!("I'm an i32!", null_i32.foo());
+ assert_eq!("I'm a u32!", null_u32.foo());
+
+ let valid_i32 = 5i32;
+ let valid_i32_thin = &valid_i32 as *const i32;
+ assert_eq!("I'm an i32!", valid_i32_thin.foo());
+ assert_eq!(5, unsafe { valid_i32_thin.bar() });
+ assert_eq!(5, unsafe { (&valid_i32_thin as *const *const i32).complicated() });
+ let valid_i32_fat = valid_i32_thin as *const Foo;
+ assert_eq!("I'm an i32!", valid_i32_fat.foo());
+ assert_eq!(5, unsafe { valid_i32_fat.bar() });
+
+ let valid_u32 = 18u32;
+ let valid_u32_thin = &valid_u32 as *const u32;
+ assert_eq!("I'm a u32!", valid_u32_thin.foo());
+ assert_eq!(18, unsafe { valid_u32_thin.bar() });
+ assert_eq!(18, unsafe { (&valid_u32_thin as *const *const u32).complicated() });
+ let valid_u32_fat = valid_u32_thin as *const Foo;
+ assert_eq!("I'm a u32!", valid_u32_fat.foo());
+ assert_eq!(18, unsafe { valid_u32_fat.bar() });
+
+}
--- /dev/null
+// run-pass
+#![feature(arbitrary_self_types)]
+
+struct Foo;
+struct Bar;
+
+impl std::ops::Deref for Bar {
+ type Target = Foo;
+
+ fn deref(&self) -> &Foo {
+ &Foo
+ }
+}
+
+impl Foo {
+ fn bar(self: Bar) -> i32 { 3 }
+}
+
+fn main() {
+ assert_eq!(3, Bar.bar());
+}
--- /dev/null
+// run-pass
+#![feature(arbitrary_self_types)]
+#![feature(rustc_attrs)]
+
+use std::{
+ rc::Rc,
+ sync::Arc,
+ pin::Pin,
+};
+
+trait Trait {
+ fn by_rc(self: Rc<Self>) -> i64;
+ fn by_arc(self: Arc<Self>) -> i64;
+ fn by_pin_mut(self: Pin<&mut Self>) -> i64;
+ fn by_pin_box(self: Pin<Box<Self>>) -> i64;
+ fn by_pin_pin_pin_ref(self: Pin<Pin<Pin<&Self>>>) -> i64;
+}
+
+impl Trait for i64 {
+ fn by_rc(self: Rc<Self>) -> i64 {
+ *self
+ }
+ fn by_arc(self: Arc<Self>) -> i64 {
+ *self
+ }
+ fn by_pin_mut(self: Pin<&mut Self>) -> i64 {
+ *self
+ }
+ fn by_pin_box(self: Pin<Box<Self>>) -> i64 {
+ *self
+ }
+ fn by_pin_pin_pin_ref(self: Pin<Pin<Pin<&Self>>>) -> i64 {
+ *self
+ }
+}
+
+fn main() {
+ let rc = Rc::new(1i64) as Rc<dyn Trait>;
+ assert_eq!(1, rc.by_rc());
+
+ let arc = Arc::new(2i64) as Arc<dyn Trait>;
+ assert_eq!(2, arc.by_arc());
+
+ let mut value = 3i64;
+ let pin_mut = Pin::new(&mut value) as Pin<&mut dyn Trait>;
+ assert_eq!(3, pin_mut.by_pin_mut());
+
+ let pin_box = Into::<Pin<Box<i64>>>::into(Box::new(4i64)) as Pin<Box<dyn Trait>>;
+ assert_eq!(4, pin_box.by_pin_box());
+
+ let value = 5i64;
+ let pin_pin_pin_ref = Pin::new(Pin::new(Pin::new(&value))) as Pin<Pin<Pin<&dyn Trait>>>;
+ assert_eq!(5, pin_pin_pin_ref.by_pin_pin_pin_ref());
+}
--- /dev/null
+// run-pass
+#![feature(arbitrary_self_types)]
+
+use std::rc::Rc;
+
+struct Foo {
+ x: i32,
+ y: i32,
+}
+
+impl Foo {
+ fn x(self: &Rc<Self>) -> i32 {
+ self.x
+ }
+
+ fn y(self: Rc<Self>) -> i32 {
+ self.y
+ }
+}
+
+fn main() {
+ let foo = Rc::new(Foo {x: 3, y: 4});
+ assert_eq!(3, foo.x());
+ assert_eq!(4, foo.y());
+}
--- /dev/null
+// run-pass
+#![feature(arbitrary_self_types)]
+
+use std::rc::Rc;
+
+trait Trait {
+ fn trait_method<'a>(self: &'a Box<Rc<Self>>) -> &'a [i32];
+}
+
+impl Trait for Vec<i32> {
+ fn trait_method<'a>(self: &'a Box<Rc<Self>>) -> &'a [i32] {
+ &***self
+ }
+}
+
+fn main() {
+ let v = vec![1,2,3];
+
+ assert_eq!(&[1,2,3], Box::new(Rc::new(v)).trait_method());
+}
--- /dev/null
+// run-pass
+#![feature(arbitrary_self_types)]
+
+use std::rc::Rc;
+
+struct Foo<T: ?Sized>(T);
+
+impl Foo<[u8]> {
+ fn len(self: Rc<Self>) -> usize {
+ self.0.len()
+ }
+}
+
+fn main() {
+ let rc = Rc::new(Foo([1u8,2,3])) as Rc<Foo<[u8]>>;
+ assert_eq!(3, rc.len());
+}
--- /dev/null
+pub trait Foo {
+ #[inline(always)]
+ fn f(&self);
+}
+
+pub struct Bar {
+ pub x: String
+}
+
+impl Foo for Bar {
+ #[inline(always)]
+ fn f(&self) {
+ println!("{}", (*self).x);
+ }
+}
--- /dev/null
+// run-pass
+// Tests the ability for the Self type in default methods to use
+// capabilities granted by builtin kinds as supertraits.
+
+
+use std::sync::mpsc::{Sender, channel};
+
+trait Foo : Send + Sized + 'static {
+ fn foo(self, tx: Sender<Self>) {
+ tx.send(self).unwrap();
+ }
+}
+
+impl <T: Send + 'static> Foo for T { }
+
+pub fn main() {
+ let (tx, rx) = channel();
+ 1193182.foo(tx);
+ assert_eq!(rx.recv().unwrap(), 1193182);
+}
--- /dev/null
+// run-pass
+
+struct X {
+ a: isize
+}
+
+trait Changer {
+ fn change(self) -> Self;
+}
+
+impl Changer for X {
+ fn change(mut self) -> X {
+ self.a = 55;
+ self
+ }
+}
+
+pub fn main() {
+ let x = X { a: 32 };
+ let new_x = x.change();
+ assert_eq!(new_x.a, 55);
+}
--- /dev/null
+// compile-pass
+#![allow(dead_code)]
+// Test to make sure that explicit self params work inside closures
+
+// pretty-expanded FIXME #23616
+
+struct Box {
+ x: usize
+}
+
+impl Box {
+ pub fn set_many(&mut self, xs: &[usize]) {
+ for x in xs { self.x = *x; }
+ }
+}
+
+pub fn main() {}
--- /dev/null
+// run-pass
+#![allow(dead_code)]
+#![feature(box_syntax)]
+
+#[derive(Copy, Clone)]
+struct LM { resize_at: usize, size: usize }
+
+enum HashMap<K,V> {
+ HashMap_(LM, Vec<(K,V)>)
+}
+
+fn linear_map<K,V>() -> HashMap<K,V> {
+ HashMap::HashMap_(LM{
+ resize_at: 32,
+ size: 0}, Vec::new())
+}
+
+impl<K,V> HashMap<K,V> {
+ pub fn len(&mut self) -> usize {
+ match *self {
+ HashMap::HashMap_(ref l, _) => l.size
+ }
+ }
+}
+
+pub fn main() {
+ let mut m: Box<_> = box linear_map::<(),()>();
+ assert_eq!(m.len(), 0);
+}
--- /dev/null
+// run-pass
+#![feature(box_syntax)]
+
+trait Foo {
+ fn f(self: Box<Self>);
+}
+
+struct S {
+ x: isize
+}
+
+impl Foo for S {
+ fn f(self: Box<S>) {
+ assert_eq!(self.x, 3);
+ }
+}
+
+pub fn main() {
+ let x = box S { x: 3 };
+ let y = x as Box<Foo>;
+ y.f();
+}
--- /dev/null
+// run-pass
+#![allow(dead_code)]
+#![allow(non_camel_case_types)]
+#![allow(non_upper_case_globals)]
+
+#![feature(box_syntax)]
+
+static tau: f64 = 2.0*3.14159265358979323;
+
+struct Point {x: f64, y: f64}
+struct Size {w: f64, h: f64}
+enum shape {
+ circle(Point, f64),
+ rectangle(Point, Size)
+}
+
+
+fn compute_area(shape: &shape) -> f64 {
+ match *shape {
+ shape::circle(_, radius) => 0.5 * tau * radius * radius,
+ shape::rectangle(_, ref size) => size.w * size.h
+ }
+}
+
+impl shape {
+ // self is in the implicit self region
+ pub fn select<'r, T>(&self, threshold: f64, a: &'r T, b: &'r T)
+ -> &'r T {
+ if compute_area(self) > threshold {a} else {b}
+ }
+}
+
+fn select_based_on_unit_circle<'r, T>(
+ threshold: f64, a: &'r T, b: &'r T) -> &'r T {
+
+ let shape = &shape::circle(Point{x: 0.0, y: 0.0}, 1.0);
+ shape.select(threshold, a, b)
+}
+
+#[derive(Clone)]
+struct thing {
+ x: A
+}
+
+#[derive(Clone)]
+struct A {
+ a: isize
+}
+
+fn thing(x: A) -> thing {
+ thing {
+ x: x
+ }
+}
+
+impl thing {
+ pub fn bar(self: Box<thing>) -> isize { self.x.a }
+ pub fn quux(&self) -> isize { self.x.a }
+ pub fn baz<'a>(&'a self) -> &'a A { &self.x }
+ pub fn spam(self) -> isize { self.x.a }
+}
+
+trait Nus { fn f(&self); }
+impl Nus for thing { fn f(&self) {} }
+
+pub fn main() {
+ let y: Box<_> = box thing(A {a: 10});
+ assert_eq!(y.clone().bar(), 10);
+ assert_eq!(y.quux(), 10);
+
+ let z = thing(A {a: 11});
+ assert_eq!(z.spam(), 11);
+}
--- /dev/null
+// run-pass
+// aux-build:explicit_self_xcrate.rs
+
+// pretty-expanded FIXME #23616
+
+extern crate explicit_self_xcrate;
+use explicit_self_xcrate::{Foo, Bar};
+
+pub fn main() {
+ let x = Bar { x: "hello".to_string() };
+ x.f();
+}
--- /dev/null
+// run-pass
+struct S {
+ x: String
+}
+
+impl S {
+ pub fn foo(self) {
+ self.bar();
+ }
+
+ pub fn bar(self) {
+ println!("{}", self.x);
+ }
+}
+
+pub fn main() {
+ let x = S { x: "Hello!".to_string() };
+ x.foo();
+}
--- /dev/null
+// run-pass
+#![allow(unused_mut)]
+// Check that a trait is still object-safe (and usable) if it has
+// methods with by-value self so long as they require `Self : Sized`.
+
+
+trait Counter {
+ fn tick(&mut self) -> u32;
+ fn get(self) -> u32 where Self : Sized;
+}
+
+struct CCounter {
+ c: u32
+}
+
+impl Counter for CCounter {
+ fn tick(&mut self) -> u32 { self.c += 1; self.c }
+ fn get(self) -> u32 where Self : Sized { self.c }
+}
+
+fn tick1<C:Counter>(mut c: C) -> u32 {
+ tick2(&mut c);
+ c.get()
+}
+
+fn tick2(c: &mut Counter) {
+ tick3(c);
+}
+
+fn tick3<C:?Sized+Counter>(c: &mut C) {
+ c.tick();
+ c.tick();
+}
+
+fn main() {
+ let mut c = CCounter { c: 0 };
+ let value = tick1(c);
+ assert_eq!(value, 2);
+}
--- /dev/null
+// run-pass
+#![allow(unused_variables)]
+// Check that a trait is still object-safe (and usable) if it has
+// generic methods so long as they require `Self : Sized`.
+
+
+trait Counter {
+ fn tick(&mut self) -> u32;
+ fn with<F:FnOnce(u32)>(&self, f: F) where Self : Sized;
+}
+
+struct CCounter {
+ c: u32
+}
+
+impl Counter for CCounter {
+ fn tick(&mut self) -> u32 { self.c += 1; self.c }
+ fn with<F:FnOnce(u32)>(&self, f: F) { f(self.c); }
+}
+
+fn tick1<C:Counter>(c: &mut C) {
+ tick2(c);
+ c.with(|i| ());
+}
+
+fn tick2(c: &mut Counter) {
+ tick3(c);
+}
+
+fn tick3<C:?Sized+Counter>(c: &mut C) {
+ c.tick();
+ c.tick();
+}
+
+fn main() {
+ let mut c = CCounter { c: 0 };
+ tick1(&mut c);
+ assert_eq!(c.tick(), 3);
+}
--- /dev/null
+// run-pass
+// Check that a trait is still object-safe (and usable) if it has
+// methods that return `Self` so long as they require `Self : Sized`.
+
+
+trait Counter {
+ fn new() -> Self where Self : Sized;
+ fn tick(&mut self) -> u32;
+}
+
+struct CCounter {
+ c: u32
+}
+
+impl Counter for CCounter {
+ fn new() -> CCounter { CCounter { c: 0 } }
+ fn tick(&mut self) -> u32 { self.c += 1; self.c }
+}
+
+fn preticked<C:Counter>() -> C {
+ let mut c: C = Counter::new();
+ tick(&mut c);
+ c
+}
+
+fn tick(c: &mut Counter) {
+ tick_generic(c);
+}
+
+fn tick_generic<C:?Sized+Counter>(c: &mut C) {
+ c.tick();
+ c.tick();
+}
+
+fn main() {
+ let mut c = preticked::<CCounter>();
+ tick(&mut c);
+ assert_eq!(c.tick(), 5);
+}
--- /dev/null
+// run-pass
+#![allow(dead_code)]
+#![allow(unused_variables)]
+// Test that we can use `Self` types in impls in the expected way.
+
+// pretty-expanded FIXME #23616
+
+#![feature(box_syntax)]
+
+struct Foo;
+
+// Test uses on inherent impl.
+impl Foo {
+ fn foo(_x: Self, _y: &Self, _z: Box<Self>) -> Self {
+ Foo
+ }
+
+ fn baz() {
+ // Test that Self cannot be shadowed.
+ type Foo = i32;
+ // There is no empty method on i32.
+ Self::empty();
+
+ let _: Self = Foo;
+ }
+
+ fn empty() {}
+}
+
+// Test uses when implementing a trait and with a type parameter.
+pub struct Baz<X> {
+ pub f: X,
+}
+
+trait SuperBar {
+ type SuperQux;
+}
+
+trait Bar<X>: SuperBar {
+ type Qux;
+
+ fn bar(x: Self, y: &Self, z: Box<Self>, _: Self::SuperQux) -> Self;
+ fn dummy(&self, x: X) { }
+}
+
+impl SuperBar for Box<Baz<isize>> {
+ type SuperQux = bool;
+}
+
+impl Bar<isize> for Box<Baz<isize>> {
+ type Qux = i32;
+
+ fn bar(_x: Self, _y: &Self, _z: Box<Self>, _: Self::SuperQux) -> Self {
+ let _: Self::Qux = 42;
+ let _: <Self as Bar<isize>>::Qux = 42;
+
+ let _: Self::SuperQux = true;
+ let _: <Self as SuperBar>::SuperQux = true;
+
+ box Baz { f: 42 }
+ }
+}
+
+fn main() {
+ let _: Foo = Foo::foo(Foo, &Foo, box Foo);
+ let _: Box<Baz<isize>> = Bar::bar(box Baz { f: 42 },
+ &box Baz { f: 42 },
+ box box Baz { f: 42 },
+ true);
+}
--- /dev/null
+// run-pass
+#![feature(box_syntax)]
+
+struct X {
+ a: isize
+}
+
+trait Changer : Sized {
+ fn change(mut self) -> Self {
+ self.set_to(55);
+ self
+ }
+
+ fn change_again(mut self: Box<Self>) -> Box<Self> {
+ self.set_to(45);
+ self
+ }
+
+ fn set_to(&mut self, a: isize);
+}
+
+impl Changer for X {
+ fn set_to(&mut self, a: isize) {
+ self.a = a;
+ }
+}
+
+pub fn main() {
+ let x = X { a: 32 };
+ let new_x = x.change();
+ assert_eq!(new_x.a, 55);
+
+ let x: Box<_> = box new_x;
+ let new_x = x.change_again();
+ assert_eq!(new_x.a, 45);
+}
--- /dev/null
+// run-pass
+// Assert that `mut self` on an immediate value doesn't
+// allow mutating the original - issue #10615.
+
+
+#[derive(Copy, Clone)]
+struct Value {
+ n: isize
+}
+
+impl Value {
+ fn squared(mut self) -> Value {
+ self.n *= self.n;
+ self
+ }
+}
+
+pub fn main() {
+ let x = Value { n: 3 };
+ let y = x.squared();
+ assert_eq!(x.n, 3);
+ assert_eq!(y.n, 9);
+}
--- /dev/null
+// compile-pass
+
+#![feature(untagged_unions)]
+
+#![allow(dead_code)]
+#![allow(unions_with_drop_fields)]
+
+enum A<'a, T: 'a>
+where
+ Self: Send, T: PartialEq<Self>
+{
+ Foo(&'a Self),
+ Bar(T),
+}
+
+struct B<'a, T: 'a>
+where
+ Self: Send, T: PartialEq<Self>
+{
+ foo: &'a Self,
+ bar: T,
+}
+
+union C<'a, T: 'a>
+where
+ Self: Send, T: PartialEq<Self>
+{
+ foo: &'a Self,
+ bar: T,
+}
+
+fn main() {}
--- /dev/null
+// run-pass
+// Ensure assigning an owned or managed variable to itself works. In particular,
+// that we do not glue_drop before we glue_take (#3290).
+
+#![feature(box_syntax)]
+
+use std::rc::Rc;
+
+pub fn main() {
+ let mut x: Box<_> = box 3;
+ x = x;
+ assert_eq!(*x, 3);
+
+ let mut x = Rc::new(3);
+ x = x;
+ assert_eq!(*x, 3);
+}
--- /dev/null
+// run-pass
+
+mod a {
+ pub mod b {
+ pub mod a {
+ pub fn foo() -> isize { return 1; }
+ }
+ }
+}
+
+mod c {
+ use a::b::a;
+ pub fn bar() { assert_eq!(a::foo(), 1); }
+}
+
+pub fn main() { c::bar(); }
--- /dev/null
+// compile-pass
+#![allow(dead_code)]
+// pretty-expanded FIXME #23616
+
+trait MyTrait {
+ fn f(&self) -> Self;
+}
+
+struct S {
+ x: isize
+}
+
+impl MyTrait for S {
+ fn f(&self) -> S {
+ S { x: 3 }
+ }
+}
+
+pub fn main() {}
--- /dev/null
+// run-pass
+pub fn main() {
+ // Make sure we properly handle repeated self-appends.
+ let mut a: String = "A".to_string();
+ let mut i = 20;
+ let mut expected_len = 1;
+ while i > 0 {
+ println!("{}", a.len());
+ assert_eq!(a.len(), expected_len);
+ a = format!("{}{}", a, a);
+ i -= 1;
+ expected_len *= 2;
+ }
+}
--- /dev/null
+// run-pass
+#![feature(box_syntax)]
+
+#[derive(Copy, Clone)]
+struct Foo {
+ f: isize,
+}
+
+impl Foo {
+ fn foo(self: Foo, x: isize) -> isize {
+ self.f + x
+ }
+ fn bar(self: &Foo, x: isize) -> isize {
+ self.f + x
+ }
+ fn baz(self: Box<Foo>, x: isize) -> isize {
+ self.f + x
+ }
+}
+
+#[derive(Copy, Clone)]
+struct Bar<T> {
+ f: T,
+}
+
+impl<T> Bar<T> {
+ fn foo(self: Bar<T>, x: isize) -> isize {
+ x
+ }
+ fn bar<'a>(self: &'a Bar<T>, x: isize) -> isize {
+ x
+ }
+ fn baz(self: Bar<T>, x: isize) -> isize {
+ x
+ }
+}
+
+fn main() {
+ let foo: Box<_> = box Foo {
+ f: 1,
+ };
+ println!("{} {} {}", foo.foo(2), foo.bar(2), foo.baz(2));
+ let bar: Box<_> = box Bar {
+ f: 1,
+ };
+ println!("{} {} {}", bar.foo(2), bar.bar(2), bar.baz(2));
+ let bar: Box<Bar<isize>> = bar;
+ println!("{} {} {}", bar.foo(2), bar.bar(2), bar.baz(2));
+}
--- /dev/null
+// run-pass
+#![feature(box_syntax)]
+
+struct X {
+ a: isize
+}
+
+trait Changer {
+ fn change(self: Box<Self>) -> Box<Self>;
+}
+
+impl Changer for X {
+ fn change(mut self: Box<X>) -> Box<X> {
+ self.a = 55;
+ self
+ }
+}
+
+pub fn main() {
+ let x: Box<_> = box X { a: 32 };
+ let new_x = x.change();
+ assert_eq!(new_x.a, 55);
+}
--- /dev/null
+// run-pass
+// Test that we can quantify lifetimes outside a constraint (i.e., including
+// the self type) in a where clause.
+
+
+static mut COUNT: u32 = 1;
+
+trait Bar<'a> {
+ fn bar(&self);
+}
+
+trait Baz<'a>
+{
+ fn baz(&self);
+}
+
+impl<'a, 'b> Bar<'b> for &'a u32 {
+ fn bar(&self) {
+ unsafe { COUNT *= 2; }
+ }
+}
+
+impl<'a, 'b> Baz<'b> for &'a u32 {
+ fn baz(&self) {
+ unsafe { COUNT *= 3; }
+ }
+}
+
+// Test we can use the syntax for HRL including the self type.
+fn foo1<T>(x: &T)
+ where for<'a, 'b> &'a T: Bar<'b>
+{
+ x.bar()
+}
+
+// Test we can quantify multiple bounds (i.e., the precedence is sensible).
+fn foo2<T>(x: &T)
+ where for<'a, 'b> &'a T: Bar<'b> + Baz<'b>
+{
+ x.baz();
+ x.bar()
+}
+
+fn main() {
+ let x = 42;
+ foo1(&x);
+ foo2(&x);
+ unsafe {
+ assert_eq!(COUNT, 12);
+ }
+}
Hello,
Goodbye,
}
+
+fn foo() {
+ let a = String::new();
+ let b = String::new();
+ let c = "";
+ let d = "";
+ let e = &a;
+ let _ = &a + &b; //~ ERROR binary operation
+ let _ = &a + b; //~ ERROR binary operation
+ let _ = a + &b; // ok
+ let _ = a + b; //~ ERROR mismatched types
+ let _ = e + b; //~ ERROR binary operation
+ let _ = e + &b; //~ ERROR binary operation
+ let _ = e + d; //~ ERROR binary operation
+ let _ = e + &d; //~ ERROR binary operation
+ let _ = &c + &d; //~ ERROR binary operation
+ let _ = &c + d; //~ ERROR binary operation
+ let _ = c + &d; //~ ERROR binary operation
+ let _ = c + d; //~ ERROR binary operation
+}
LL | let x = "Hello " + "World!";
| -------- ^ -------- &str
| | |
- | | `+` can't be used to concatenate two `&str` strings
+ | | `+` cannot be used to concatenate two `&str` strings
| &str
help: `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left
|
--> $DIR/issue-39018.rs:11:22
|
LL | let x = "Hello " + "World!".to_owned();
- | ---------^--------------------
- | | |
- | | std::string::String
+ | -------- ^ ------------------- std::string::String
+ | | |
+ | | `+` cannot be used to concatenate a `&str` with a `String`
| &str
- | `+` can't be used to concatenate a `&str` with a `String`
help: `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left
|
LL | let x = "Hello ".to_owned() + &"World!".to_owned();
| ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^
-error: aborting due to 3 previous errors
+error[E0369]: binary operation `+` cannot be applied to type `&std::string::String`
+ --> $DIR/issue-39018.rs:26:16
+ |
+LL | let _ = &a + &b;
+ | -- ^ -- &std::string::String
+ | | |
+ | | `+` cannot be used to concatenate two `&str` strings
+ | &std::string::String
+help: String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left
+ |
+LL | let _ = a + &b;
+ | ^
+
+error[E0369]: binary operation `+` cannot be applied to type `&std::string::String`
+ --> $DIR/issue-39018.rs:27:16
+ |
+LL | let _ = &a + b;
+ | -- ^ - std::string::String
+ | | |
+ | | `+` cannot be used to concatenate a `&str` with a `String`
+ | &std::string::String
+help: `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left
+ |
+LL | let _ = a + &b;
+ | ^ ^^
+
+error[E0308]: mismatched types
+ --> $DIR/issue-39018.rs:29:17
+ |
+LL | let _ = a + b;
+ | ^
+ | |
+ | expected &str, found struct `std::string::String`
+ | help: consider borrowing here: `&b`
+ |
+ = note: expected type `&str`
+ found type `std::string::String`
+
+error[E0369]: binary operation `+` cannot be applied to type `&std::string::String`
+ --> $DIR/issue-39018.rs:30:15
+ |
+LL | let _ = e + b;
+ | - ^ - std::string::String
+ | | |
+ | | `+` cannot be used to concatenate a `&str` with a `String`
+ | &std::string::String
+help: `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left
+ |
+LL | let _ = e.to_owned() + &b;
+ | ^^^^^^^^^^^^ ^^
+
+error[E0369]: binary operation `+` cannot be applied to type `&std::string::String`
+ --> $DIR/issue-39018.rs:31:15
+ |
+LL | let _ = e + &b;
+ | - ^ -- &std::string::String
+ | | |
+ | | `+` cannot be used to concatenate two `&str` strings
+ | &std::string::String
+help: `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left
+ |
+LL | let _ = e.to_owned() + &b;
+ | ^^^^^^^^^^^^
+
+error[E0369]: binary operation `+` cannot be applied to type `&std::string::String`
+ --> $DIR/issue-39018.rs:32:15
+ |
+LL | let _ = e + d;
+ | - ^ - &str
+ | | |
+ | | `+` cannot be used to concatenate two `&str` strings
+ | &std::string::String
+help: `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left
+ |
+LL | let _ = e.to_owned() + d;
+ | ^^^^^^^^^^^^
+
+error[E0369]: binary operation `+` cannot be applied to type `&std::string::String`
+ --> $DIR/issue-39018.rs:33:15
+ |
+LL | let _ = e + &d;
+ | - ^ -- &&str
+ | | |
+ | | `+` cannot be used to concatenate two `&str` strings
+ | &std::string::String
+help: `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left
+ |
+LL | let _ = e.to_owned() + &d;
+ | ^^^^^^^^^^^^
+
+error[E0369]: binary operation `+` cannot be applied to type `&&str`
+ --> $DIR/issue-39018.rs:34:16
+ |
+LL | let _ = &c + &d;
+ | -- ^ -- &&str
+ | |
+ | &&str
+ |
+ = note: an implementation of `std::ops::Add` might be missing for `&&str`
+
+error[E0369]: binary operation `+` cannot be applied to type `&&str`
+ --> $DIR/issue-39018.rs:35:16
+ |
+LL | let _ = &c + d;
+ | -- ^ - &str
+ | |
+ | &&str
+ |
+ = note: an implementation of `std::ops::Add` might be missing for `&&str`
+
+error[E0369]: binary operation `+` cannot be applied to type `&str`
+ --> $DIR/issue-39018.rs:36:15
+ |
+LL | let _ = c + &d;
+ | - ^ -- &&str
+ | | |
+ | | `+` cannot be used to concatenate two `&str` strings
+ | &str
+help: `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left
+ |
+LL | let _ = c.to_owned() + &d;
+ | ^^^^^^^^^^^^
+
+error[E0369]: binary operation `+` cannot be applied to type `&str`
+ --> $DIR/issue-39018.rs:37:15
+ |
+LL | let _ = c + d;
+ | - ^ - &str
+ | | |
+ | | `+` cannot be used to concatenate two `&str` strings
+ | &str
+help: `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left
+ |
+LL | let _ = c.to_owned() + d;
+ | ^^^^^^^^^^^^
+
+error: aborting due to 14 previous errors
-For more information about this error, try `rustc --explain E0369`.
+Some errors have detailed explanations: E0308, E0369.
+For more information about an error, try `rustc --explain E0308`.
|
LL | let c = a + b;
| - ^ - &str
- | |
+ | | |
+ | | `+` cannot be used to concatenate two `&str` strings
| &std::string::String
+help: `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left
|
- = note: an implementation of `std::ops::Add` might be missing for `&std::string::String`
+LL | let c = a.to_owned() + b;
+ | ^^^^^^^^^^^^
error: aborting due to previous error
-#![feature(nll)]
-
#[derive(Clone)]
enum Either {
One(X),
error[E0507]: cannot move out of borrowed content
- --> $DIR/duplicate-suggestions.rs:41:27
+ --> $DIR/duplicate-suggestions.rs:39:27
|
LL | let &(X(_t), X(_u)) = &(x.clone(), x.clone());
| --------------- ^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
| help: consider removing the `&`: `(X(_t), X(_u))`
|
note: move occurs because these variables have types that don't implement the `Copy` trait
- --> $DIR/duplicate-suggestions.rs:41:13
+ --> $DIR/duplicate-suggestions.rs:39:13
|
LL | let &(X(_t), X(_u)) = &(x.clone(), x.clone());
| ^^ ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/duplicate-suggestions.rs:45:50
+ --> $DIR/duplicate-suggestions.rs:43:50
|
LL | if let &(Either::One(_t), Either::Two(_u)) = &(e.clone(), e.clone()) { }
| ----------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
| help: consider removing the `&`: `(Either::One(_t), Either::Two(_u))`
|
note: move occurs because these variables have types that don't implement the `Copy` trait
- --> $DIR/duplicate-suggestions.rs:45:26
+ --> $DIR/duplicate-suggestions.rs:43:26
|
LL | if let &(Either::One(_t), Either::Two(_u)) = &(e.clone(), e.clone()) { }
| ^^ ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/duplicate-suggestions.rs:49:53
+ --> $DIR/duplicate-suggestions.rs:47:53
|
LL | while let &(Either::One(_t), Either::Two(_u)) = &(e.clone(), e.clone()) { }
| ----------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
| help: consider removing the `&`: `(Either::One(_t), Either::Two(_u))`
|
note: move occurs because these variables have types that don't implement the `Copy` trait
- --> $DIR/duplicate-suggestions.rs:49:29
+ --> $DIR/duplicate-suggestions.rs:47:29
|
LL | while let &(Either::One(_t), Either::Two(_u)) = &(e.clone(), e.clone()) { }
| ^^ ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/duplicate-suggestions.rs:53:11
+ --> $DIR/duplicate-suggestions.rs:51:11
|
LL | match &(e.clone(), e.clone()) {
| ^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
| -- ...and here -- ...and here
|
note: move occurs because these variables have types that don't implement the `Copy` trait
- --> $DIR/duplicate-suggestions.rs:55:23
+ --> $DIR/duplicate-suggestions.rs:53:23
|
LL | &(Either::One(_t), Either::Two(_u)) => (),
| ^^ ^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/duplicate-suggestions.rs:63:11
+ --> $DIR/duplicate-suggestions.rs:61:11
|
LL | match &(e.clone(), e.clone()) {
| ^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
| help: consider removing the `&`: `(Either::One(_t), Either::Two(_u))`
|
note: move occurs because these variables have types that don't implement the `Copy` trait
- --> $DIR/duplicate-suggestions.rs:65:23
+ --> $DIR/duplicate-suggestions.rs:63:23
|
LL | &(Either::One(_t), Either::Two(_u))
| ^^ ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/duplicate-suggestions.rs:72:11
+ --> $DIR/duplicate-suggestions.rs:70:11
|
LL | match &(e.clone(), e.clone()) {
| ^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
| help: consider removing the `&`: `(Either::One(_t), Either::Two(_u))`
|
note: move occurs because these variables have types that don't implement the `Copy` trait
- --> $DIR/duplicate-suggestions.rs:74:23
+ --> $DIR/duplicate-suggestions.rs:72:23
|
LL | &(Either::One(_t), Either::Two(_u)) => (),
| ^^ ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/duplicate-suggestions.rs:80:11
+ --> $DIR/duplicate-suggestions.rs:78:11
|
LL | match &(e.clone(), e.clone()) {
| ^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
| help: consider removing the `&`: `(Either::One(_t), Either::Two(_u))`
|
note: move occurs because these variables have types that don't implement the `Copy` trait
- --> $DIR/duplicate-suggestions.rs:82:23
+ --> $DIR/duplicate-suggestions.rs:80:23
|
LL | &(Either::One(_t), Either::Two(_u)) => (),
| ^^ ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/duplicate-suggestions.rs:93:31
+ --> $DIR/duplicate-suggestions.rs:91:31
|
LL | let &mut (X(_t), X(_u)) = &mut (xm.clone(), xm.clone());
| ------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
| help: consider removing the `&mut`: `(X(_t), X(_u))`
|
note: move occurs because these variables have types that don't implement the `Copy` trait
- --> $DIR/duplicate-suggestions.rs:93:17
+ --> $DIR/duplicate-suggestions.rs:91:17
|
LL | let &mut (X(_t), X(_u)) = &mut (xm.clone(), xm.clone());
| ^^ ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/duplicate-suggestions.rs:97:54
+ --> $DIR/duplicate-suggestions.rs:95:54
|
LL | if let &mut (Either::One(_t), Either::Two(_u)) = &mut (em.clone(), em.clone()) { }
| --------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
| help: consider removing the `&mut`: `(Either::One(_t), Either::Two(_u))`
|
note: move occurs because these variables have types that don't implement the `Copy` trait
- --> $DIR/duplicate-suggestions.rs:97:30
+ --> $DIR/duplicate-suggestions.rs:95:30
|
LL | if let &mut (Either::One(_t), Either::Two(_u)) = &mut (em.clone(), em.clone()) { }
| ^^ ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/duplicate-suggestions.rs:101:57
+ --> $DIR/duplicate-suggestions.rs:99:57
|
LL | while let &mut (Either::One(_t), Either::Two(_u)) = &mut (em.clone(), em.clone()) { }
| --------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
| help: consider removing the `&mut`: `(Either::One(_t), Either::Two(_u))`
|
note: move occurs because these variables have types that don't implement the `Copy` trait
- --> $DIR/duplicate-suggestions.rs:101:33
+ --> $DIR/duplicate-suggestions.rs:99:33
|
LL | while let &mut (Either::One(_t), Either::Two(_u)) = &mut (em.clone(), em.clone()) { }
| ^^ ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/duplicate-suggestions.rs:105:11
+ --> $DIR/duplicate-suggestions.rs:103:11
|
LL | match &mut (em.clone(), em.clone()) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
| -- ...and here -- ...and here
|
note: move occurs because these variables have types that don't implement the `Copy` trait
- --> $DIR/duplicate-suggestions.rs:107:27
+ --> $DIR/duplicate-suggestions.rs:105:27
|
LL | &mut (Either::One(_t), Either::Two(_u)) => (),
| ^^ ^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/duplicate-suggestions.rs:115:11
+ --> $DIR/duplicate-suggestions.rs:113:11
|
LL | match &mut (em.clone(), em.clone()) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
| help: consider removing the `&mut`: `(Either::One(_t), Either::Two(_u))`
|
note: move occurs because these variables have types that don't implement the `Copy` trait
- --> $DIR/duplicate-suggestions.rs:117:27
+ --> $DIR/duplicate-suggestions.rs:115:27
|
LL | &mut (Either::One(_t), Either::Two(_u))
| ^^ ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/duplicate-suggestions.rs:124:11
+ --> $DIR/duplicate-suggestions.rs:122:11
|
LL | match &mut (em.clone(), em.clone()) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
| help: consider removing the `&mut`: `(Either::One(_t), Either::Two(_u))`
|
note: move occurs because these variables have types that don't implement the `Copy` trait
- --> $DIR/duplicate-suggestions.rs:126:27
+ --> $DIR/duplicate-suggestions.rs:124:27
|
LL | &mut (Either::One(_t), Either::Two(_u)) => (),
| ^^ ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/duplicate-suggestions.rs:132:11
+ --> $DIR/duplicate-suggestions.rs:130:11
|
LL | match &mut (em.clone(), em.clone()) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
| help: consider removing the `&mut`: `(Either::One(_t), Either::Two(_u))`
|
note: move occurs because these variables have types that don't implement the `Copy` trait
- --> $DIR/duplicate-suggestions.rs:134:27
+ --> $DIR/duplicate-suggestions.rs:132:27
|
LL | &mut (Either::One(_t), Either::Two(_u)) => (),
| ^^ ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/duplicate-suggestions.rs:140:11
+ --> $DIR/duplicate-suggestions.rs:138:11
|
LL | match &mut (em.clone(), em.clone()) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
| help: consider removing the `&mut`: `(Either::One(_t), Either::Two(_u))`
|
note: move occurs because these variables have types that don't implement the `Copy` trait
- --> $DIR/duplicate-suggestions.rs:142:27
+ --> $DIR/duplicate-suggestions.rs:140:27
|
LL | &mut (Either::One(_t), Either::Two(_u)) => (),
| ^^ ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/duplicate-suggestions.rs:88:11
+ --> $DIR/duplicate-suggestions.rs:86:11
|
LL | fn f5(&(X(_t), X(_u)): &(X, X)) { }
| ^^^^--^^^^^--^^
| help: consider removing the `&`: `(X(_t), X(_u))`
|
note: move occurs because these variables have types that don't implement the `Copy` trait
- --> $DIR/duplicate-suggestions.rs:88:15
+ --> $DIR/duplicate-suggestions.rs:86:15
|
LL | fn f5(&(X(_t), X(_u)): &(X, X)) { }
| ^^ ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/duplicate-suggestions.rs:148:11
+ --> $DIR/duplicate-suggestions.rs:146:11
|
LL | fn f6(&mut (X(_t), X(_u)): &mut (X, X)) { }
| ^^^^^^^^--^^^^^--^^
| help: consider removing the `&mut`: `(X(_t), X(_u))`
|
note: move occurs because these variables have types that don't implement the `Copy` trait
- --> $DIR/duplicate-suggestions.rs:148:19
+ --> $DIR/duplicate-suggestions.rs:146:19
|
LL | fn f6(&mut (X(_t), X(_u)): &mut (X, X)) { }
| ^^ ^^
-#![feature(nll)]
-
#[derive(Clone)]
enum Either {
One(X),
error[E0507]: cannot move out of captured variable in an `Fn` closure
- --> $DIR/move-into-closure.rs:30:21
+ --> $DIR/move-into-closure.rs:28:21
|
LL | let x = X(Y);
| - captured outer variable
| data moved here
|
note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
- --> $DIR/move-into-closure.rs:30:15
+ --> $DIR/move-into-closure.rs:28:15
|
LL | let X(_t) = x;
| ^^
error[E0507]: cannot move out of captured variable in an `Fn` closure
- --> $DIR/move-into-closure.rs:34:34
+ --> $DIR/move-into-closure.rs:32:34
|
LL | let e = Either::One(X(Y));
| - captured outer variable
| data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/move-into-closure.rs:34:28
+ --> $DIR/move-into-closure.rs:32:28
|
LL | if let Either::One(_t) = e { }
| ^^
error[E0507]: cannot move out of captured variable in an `Fn` closure
- --> $DIR/move-into-closure.rs:38:37
+ --> $DIR/move-into-closure.rs:36:37
|
LL | let e = Either::One(X(Y));
| - captured outer variable
| data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/move-into-closure.rs:38:31
+ --> $DIR/move-into-closure.rs:36:31
|
LL | while let Either::One(_t) = e { }
| ^^
error[E0507]: cannot move out of captured variable in an `Fn` closure
- --> $DIR/move-into-closure.rs:42:15
+ --> $DIR/move-into-closure.rs:40:15
|
LL | let e = Either::One(X(Y));
| - captured outer variable
| -- data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/move-into-closure.rs:46:25
+ --> $DIR/move-into-closure.rs:44:25
|
LL | Either::One(_t)
| ^^
error[E0507]: cannot move out of captured variable in an `Fn` closure
- --> $DIR/move-into-closure.rs:49:15
+ --> $DIR/move-into-closure.rs:47:15
|
LL | let e = Either::One(X(Y));
| - captured outer variable
| -- data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/move-into-closure.rs:53:25
+ --> $DIR/move-into-closure.rs:51:25
|
LL | Either::One(_t) => (),
| ^^
error[E0507]: cannot move out of captured variable in an `Fn` closure
- --> $DIR/move-into-closure.rs:58:25
+ --> $DIR/move-into-closure.rs:56:25
|
LL | let x = X(Y);
| - captured outer variable
| data moved here
|
note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
- --> $DIR/move-into-closure.rs:58:15
+ --> $DIR/move-into-closure.rs:56:15
|
LL | let X(mut _t) = x;
| ^^^^^^
error[E0507]: cannot move out of captured variable in an `Fn` closure
- --> $DIR/move-into-closure.rs:62:38
+ --> $DIR/move-into-closure.rs:60:38
|
LL | let mut em = Either::One(X(Y));
| ------ captured outer variable
| data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/move-into-closure.rs:62:28
+ --> $DIR/move-into-closure.rs:60:28
|
LL | if let Either::One(mut _t) = em { }
| ^^^^^^
error[E0507]: cannot move out of captured variable in an `Fn` closure
- --> $DIR/move-into-closure.rs:66:41
+ --> $DIR/move-into-closure.rs:64:41
|
LL | let mut em = Either::One(X(Y));
| ------ captured outer variable
| data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/move-into-closure.rs:66:31
+ --> $DIR/move-into-closure.rs:64:31
|
LL | while let Either::One(mut _t) = em { }
| ^^^^^^
error[E0507]: cannot move out of captured variable in an `Fn` closure
- --> $DIR/move-into-closure.rs:70:15
+ --> $DIR/move-into-closure.rs:68:15
|
LL | let mut em = Either::One(X(Y));
| ------ captured outer variable
| ------ data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/move-into-closure.rs:74:25
+ --> $DIR/move-into-closure.rs:72:25
|
LL | Either::One(mut _t)
| ^^^^^^
error[E0507]: cannot move out of captured variable in an `Fn` closure
- --> $DIR/move-into-closure.rs:77:15
+ --> $DIR/move-into-closure.rs:75:15
|
LL | let mut em = Either::One(X(Y));
| ------ captured outer variable
| ------ data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/move-into-closure.rs:81:25
+ --> $DIR/move-into-closure.rs:79:25
|
LL | Either::One(mut _t) => (),
| ^^^^^^
error[E0507]: cannot move out of captured variable in an `FnMut` closure
- --> $DIR/move-into-closure.rs:97:21
+ --> $DIR/move-into-closure.rs:95:21
|
LL | let x = X(Y);
| - captured outer variable
| data moved here
|
note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
- --> $DIR/move-into-closure.rs:97:15
+ --> $DIR/move-into-closure.rs:95:15
|
LL | let X(_t) = x;
| ^^
error[E0507]: cannot move out of captured variable in an `FnMut` closure
- --> $DIR/move-into-closure.rs:101:34
+ --> $DIR/move-into-closure.rs:99:34
|
LL | let e = Either::One(X(Y));
| - captured outer variable
| data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/move-into-closure.rs:101:28
+ --> $DIR/move-into-closure.rs:99:28
|
LL | if let Either::One(_t) = e { }
| ^^
error[E0507]: cannot move out of captured variable in an `FnMut` closure
- --> $DIR/move-into-closure.rs:105:37
+ --> $DIR/move-into-closure.rs:103:37
|
LL | let e = Either::One(X(Y));
| - captured outer variable
| data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/move-into-closure.rs:105:31
+ --> $DIR/move-into-closure.rs:103:31
|
LL | while let Either::One(_t) = e { }
| ^^
error[E0507]: cannot move out of captured variable in an `FnMut` closure
- --> $DIR/move-into-closure.rs:109:15
+ --> $DIR/move-into-closure.rs:107:15
|
LL | let e = Either::One(X(Y));
| - captured outer variable
| -- data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/move-into-closure.rs:113:25
+ --> $DIR/move-into-closure.rs:111:25
|
LL | Either::One(_t)
| ^^
error[E0507]: cannot move out of captured variable in an `FnMut` closure
- --> $DIR/move-into-closure.rs:116:15
+ --> $DIR/move-into-closure.rs:114:15
|
LL | let e = Either::One(X(Y));
| - captured outer variable
| -- data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/move-into-closure.rs:120:25
+ --> $DIR/move-into-closure.rs:118:25
|
LL | Either::One(_t) => (),
| ^^
error[E0507]: cannot move out of captured variable in an `FnMut` closure
- --> $DIR/move-into-closure.rs:125:25
+ --> $DIR/move-into-closure.rs:123:25
|
LL | let x = X(Y);
| - captured outer variable
| data moved here
|
note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
- --> $DIR/move-into-closure.rs:125:15
+ --> $DIR/move-into-closure.rs:123:15
|
LL | let X(mut _t) = x;
| ^^^^^^
error[E0507]: cannot move out of captured variable in an `FnMut` closure
- --> $DIR/move-into-closure.rs:129:38
+ --> $DIR/move-into-closure.rs:127:38
|
LL | let mut em = Either::One(X(Y));
| ------ captured outer variable
| data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/move-into-closure.rs:129:28
+ --> $DIR/move-into-closure.rs:127:28
|
LL | if let Either::One(mut _t) = em { }
| ^^^^^^
error[E0507]: cannot move out of captured variable in an `FnMut` closure
- --> $DIR/move-into-closure.rs:133:41
+ --> $DIR/move-into-closure.rs:131:41
|
LL | let mut em = Either::One(X(Y));
| ------ captured outer variable
| data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/move-into-closure.rs:133:31
+ --> $DIR/move-into-closure.rs:131:31
|
LL | while let Either::One(mut _t) = em { }
| ^^^^^^
error[E0507]: cannot move out of captured variable in an `FnMut` closure
- --> $DIR/move-into-closure.rs:137:15
+ --> $DIR/move-into-closure.rs:135:15
|
LL | let mut em = Either::One(X(Y));
| ------ captured outer variable
| ------ data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/move-into-closure.rs:141:25
+ --> $DIR/move-into-closure.rs:139:25
|
LL | Either::One(mut _t)
| ^^^^^^
error[E0507]: cannot move out of captured variable in an `FnMut` closure
- --> $DIR/move-into-closure.rs:144:15
+ --> $DIR/move-into-closure.rs:142:15
|
LL | let mut em = Either::One(X(Y));
| ------ captured outer variable
| ------ data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/move-into-closure.rs:148:25
+ --> $DIR/move-into-closure.rs:146:25
|
LL | Either::One(mut _t) => (),
| ^^^^^^
error[E0507]: cannot move out of captured variable in an `FnMut` closure
- --> $DIR/move-into-closure.rs:152:15
+ --> $DIR/move-into-closure.rs:150:15
|
LL | let mut em = Either::One(X(Y));
| ------ captured outer variable
| ------ data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/move-into-closure.rs:156:25
+ --> $DIR/move-into-closure.rs:154:25
|
LL | Either::One(mut _t) => (),
| ^^^^^^
-#![feature(nll)]
-
#[derive(Clone)]
enum Either {
One(X),
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:40:17
+ --> $DIR/simple.rs:38:17
|
LL | let X(_t) = *s;
| -- ^^
| data moved here
|
note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:40:11
+ --> $DIR/simple.rs:38:11
|
LL | let X(_t) = *s;
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:44:30
+ --> $DIR/simple.rs:42:30
|
LL | if let Either::One(_t) = *r { }
| -- ^^
| data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:44:24
+ --> $DIR/simple.rs:42:24
|
LL | if let Either::One(_t) = *r { }
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:48:33
+ --> $DIR/simple.rs:46:33
|
LL | while let Either::One(_t) = *r { }
| -- ^^
| data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:48:27
+ --> $DIR/simple.rs:46:27
|
LL | while let Either::One(_t) = *r { }
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:52:11
+ --> $DIR/simple.rs:50:11
|
LL | match *r {
| ^^
| -- data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:56:21
+ --> $DIR/simple.rs:54:21
|
LL | Either::One(_t)
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:59:11
+ --> $DIR/simple.rs:57:11
|
LL | match *r {
| ^^
| -- data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:63:21
+ --> $DIR/simple.rs:61:21
|
LL | Either::One(_t) => (),
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:68:17
+ --> $DIR/simple.rs:66:17
|
LL | let X(_t) = *sm;
| -- ^^^
| data moved here
|
note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:68:11
+ --> $DIR/simple.rs:66:11
|
LL | let X(_t) = *sm;
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:72:30
+ --> $DIR/simple.rs:70:30
|
LL | if let Either::One(_t) = *rm { }
| -- ^^^
| data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:72:24
+ --> $DIR/simple.rs:70:24
|
LL | if let Either::One(_t) = *rm { }
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:76:33
+ --> $DIR/simple.rs:74:33
|
LL | while let Either::One(_t) = *rm { }
| -- ^^^
| data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:76:27
+ --> $DIR/simple.rs:74:27
|
LL | while let Either::One(_t) = *rm { }
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:80:11
+ --> $DIR/simple.rs:78:11
|
LL | match *rm {
| ^^^
| -- data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:84:21
+ --> $DIR/simple.rs:82:21
|
LL | Either::One(_t)
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:87:11
+ --> $DIR/simple.rs:85:11
|
LL | match *rm {
| ^^^
| -- data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:91:21
+ --> $DIR/simple.rs:89:21
|
LL | Either::One(_t) => (),
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:95:11
+ --> $DIR/simple.rs:93:11
|
LL | match *rm {
| ^^^
| -- data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:99:21
+ --> $DIR/simple.rs:97:21
|
LL | Either::One(_t) => (),
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:104:17
+ --> $DIR/simple.rs:102:17
|
LL | let X(_t) = vs[0];
| -- ^^^^^
| data moved here
|
note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:104:11
+ --> $DIR/simple.rs:102:11
|
LL | let X(_t) = vs[0];
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:108:30
+ --> $DIR/simple.rs:106:30
|
LL | if let Either::One(_t) = vr[0] { }
| -- ^^^^^
| data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:108:24
+ --> $DIR/simple.rs:106:24
|
LL | if let Either::One(_t) = vr[0] { }
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:112:33
+ --> $DIR/simple.rs:110:33
|
LL | while let Either::One(_t) = vr[0] { }
| -- ^^^^^
| data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:112:27
+ --> $DIR/simple.rs:110:27
|
LL | while let Either::One(_t) = vr[0] { }
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:116:11
+ --> $DIR/simple.rs:114:11
|
LL | match vr[0] {
| ^^^^^
| -- data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:120:21
+ --> $DIR/simple.rs:118:21
|
LL | Either::One(_t)
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:123:11
+ --> $DIR/simple.rs:121:11
|
LL | match vr[0] {
| ^^^^^
| -- data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:127:21
+ --> $DIR/simple.rs:125:21
|
LL | Either::One(_t) => (),
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:132:17
+ --> $DIR/simple.rs:130:17
|
LL | let X(_t) = vsm[0];
| -- ^^^^^^
| data moved here
|
note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:132:11
+ --> $DIR/simple.rs:130:11
|
LL | let X(_t) = vsm[0];
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:136:30
+ --> $DIR/simple.rs:134:30
|
LL | if let Either::One(_t) = vrm[0] { }
| -- ^^^^^^
| data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:136:24
+ --> $DIR/simple.rs:134:24
|
LL | if let Either::One(_t) = vrm[0] { }
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:140:33
+ --> $DIR/simple.rs:138:33
|
LL | while let Either::One(_t) = vrm[0] { }
| -- ^^^^^^
| data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:140:27
+ --> $DIR/simple.rs:138:27
|
LL | while let Either::One(_t) = vrm[0] { }
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:144:11
+ --> $DIR/simple.rs:142:11
|
LL | match vrm[0] {
| ^^^^^^
| -- data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:148:21
+ --> $DIR/simple.rs:146:21
|
LL | Either::One(_t)
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:151:11
+ --> $DIR/simple.rs:149:11
|
LL | match vrm[0] {
| ^^^^^^
| -- data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:155:21
+ --> $DIR/simple.rs:153:21
|
LL | Either::One(_t) => (),
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:159:11
+ --> $DIR/simple.rs:157:11
|
LL | match vrm[0] {
| ^^^^^^
| -- data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:163:21
+ --> $DIR/simple.rs:161:21
|
LL | Either::One(_t) => (),
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:170:18
+ --> $DIR/simple.rs:168:18
|
LL | let &X(_t) = s;
| ------ ^ cannot move out of borrowed content
| help: consider removing the `&`: `X(_t)`
|
note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:170:12
+ --> $DIR/simple.rs:168:12
|
LL | let &X(_t) = s;
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:174:31
+ --> $DIR/simple.rs:172:31
|
LL | if let &Either::One(_t) = r { }
| ---------------- ^ cannot move out of borrowed content
| help: consider removing the `&`: `Either::One(_t)`
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:174:25
+ --> $DIR/simple.rs:172:25
|
LL | if let &Either::One(_t) = r { }
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:178:34
+ --> $DIR/simple.rs:176:34
|
LL | while let &Either::One(_t) = r { }
| ---------------- ^ cannot move out of borrowed content
| help: consider removing the `&`: `Either::One(_t)`
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:178:28
+ --> $DIR/simple.rs:176:28
|
LL | while let &Either::One(_t) = r { }
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:182:11
+ --> $DIR/simple.rs:180:11
|
LL | match r {
| ^ cannot move out of borrowed content
| help: consider removing the `&`: `Either::One(_t)`
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:184:22
+ --> $DIR/simple.rs:182:22
|
LL | &Either::One(_t)
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:190:11
+ --> $DIR/simple.rs:188:11
|
LL | match r {
| ^ cannot move out of borrowed content
| help: consider removing the `&`: `Either::One(_t)`
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:192:22
+ --> $DIR/simple.rs:190:22
|
LL | &Either::One(_t) => (),
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:197:11
+ --> $DIR/simple.rs:195:11
|
LL | match r {
| ^ cannot move out of borrowed content
| help: consider removing the `&`: `Either::One(_t)`
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:199:22
+ --> $DIR/simple.rs:197:22
|
LL | &Either::One(_t) => (),
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:209:22
+ --> $DIR/simple.rs:207:22
|
LL | let &mut X(_t) = sm;
| ---------- ^^ cannot move out of borrowed content
| help: consider removing the `&mut`: `X(_t)`
|
note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:209:16
+ --> $DIR/simple.rs:207:16
|
LL | let &mut X(_t) = sm;
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:213:35
+ --> $DIR/simple.rs:211:35
|
LL | if let &mut Either::One(_t) = rm { }
| -------------------- ^^ cannot move out of borrowed content
| help: consider removing the `&mut`: `Either::One(_t)`
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:213:29
+ --> $DIR/simple.rs:211:29
|
LL | if let &mut Either::One(_t) = rm { }
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:217:38
+ --> $DIR/simple.rs:215:38
|
LL | while let &mut Either::One(_t) = rm { }
| -------------------- ^^ cannot move out of borrowed content
| help: consider removing the `&mut`: `Either::One(_t)`
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:217:32
+ --> $DIR/simple.rs:215:32
|
LL | while let &mut Either::One(_t) = rm { }
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:221:11
+ --> $DIR/simple.rs:219:11
|
LL | match rm {
| ^^ cannot move out of borrowed content
| -- ...and here
|
note: move occurs because these variables have types that don't implement the `Copy` trait
- --> $DIR/simple.rs:223:26
+ --> $DIR/simple.rs:221:26
|
LL | &mut Either::One(_t) => (),
| ^^
| ^^^^^^^^^^^^^^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:230:11
+ --> $DIR/simple.rs:228:11
|
LL | match rm {
| ^^ cannot move out of borrowed content
| help: consider removing the `&mut`: `Either::One(_t)`
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:232:26
+ --> $DIR/simple.rs:230:26
|
LL | &mut Either::One(_t) => (),
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:237:11
+ --> $DIR/simple.rs:235:11
|
LL | match rm {
| ^^ cannot move out of borrowed content
| help: consider removing the `&mut`: `Either::One(_t)`
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:239:26
+ --> $DIR/simple.rs:237:26
|
LL | &mut Either::One(_t) => (),
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:244:11
+ --> $DIR/simple.rs:242:11
|
LL | match rm {
| ^^ cannot move out of borrowed content
| help: consider removing the `&mut`: `Either::One(_t)`
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:246:26
+ --> $DIR/simple.rs:244:26
|
LL | &mut Either::One(_t) => (),
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:260:21
+ --> $DIR/simple.rs:258:21
|
LL | let (&X(_t),) = (&x.clone(),);
| -- ^^^^^^^^^^^^^ cannot move out of borrowed content
| data moved here
|
note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:260:13
+ --> $DIR/simple.rs:258:13
|
LL | let (&X(_t),) = (&x.clone(),);
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:262:34
+ --> $DIR/simple.rs:260:34
|
LL | if let (&Either::One(_t),) = (&e.clone(),) { }
| -- ^^^^^^^^^^^^^ cannot move out of borrowed content
| data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:262:26
+ --> $DIR/simple.rs:260:26
|
LL | if let (&Either::One(_t),) = (&e.clone(),) { }
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:264:37
+ --> $DIR/simple.rs:262:37
|
LL | while let (&Either::One(_t),) = (&e.clone(),) { }
| -- ^^^^^^^^^^^^^ cannot move out of borrowed content
| data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:264:29
+ --> $DIR/simple.rs:262:29
|
LL | while let (&Either::One(_t),) = (&e.clone(),) { }
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:266:11
+ --> $DIR/simple.rs:264:11
|
LL | match (&e.clone(),) {
| ^^^^^^^^^^^^^ cannot move out of borrowed content
| -- data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:268:23
+ --> $DIR/simple.rs:266:23
|
LL | (&Either::One(_t),)
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:274:25
+ --> $DIR/simple.rs:272:25
|
LL | let (&mut X(_t),) = (&mut xm.clone(),);
| -- ^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
| data moved here
|
note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:274:17
+ --> $DIR/simple.rs:272:17
|
LL | let (&mut X(_t),) = (&mut xm.clone(),);
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:276:38
+ --> $DIR/simple.rs:274:38
|
LL | if let (&mut Either::One(_t),) = (&mut em.clone(),) { }
| -- ^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
| data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:276:30
+ --> $DIR/simple.rs:274:30
|
LL | if let (&mut Either::One(_t),) = (&mut em.clone(),) { }
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:278:41
+ --> $DIR/simple.rs:276:41
|
LL | while let (&mut Either::One(_t),) = (&mut em.clone(),) { }
| -- ^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
| data moved here
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:278:33
+ --> $DIR/simple.rs:276:33
|
LL | while let (&mut Either::One(_t),) = (&mut em.clone(),) { }
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:280:11
+ --> $DIR/simple.rs:278:11
|
LL | match (&mut em.clone(),) {
| ^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
| -- ...and here
|
note: move occurs because these variables have types that don't implement the `Copy` trait
- --> $DIR/simple.rs:282:27
+ --> $DIR/simple.rs:280:27
|
LL | (&mut Either::One(_t),) => (),
| ^^
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:290:18
+ --> $DIR/simple.rs:288:18
|
LL | let &X(_t) = &x;
| ------ ^^ cannot move out of borrowed content
| help: consider removing the `&`: `X(_t)`
|
note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:290:12
+ --> $DIR/simple.rs:288:12
|
LL | let &X(_t) = &x;
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:294:31
+ --> $DIR/simple.rs:292:31
|
LL | if let &Either::One(_t) = &e { }
| ---------------- ^^ cannot move out of borrowed content
| help: consider removing the `&`: `Either::One(_t)`
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:294:25
+ --> $DIR/simple.rs:292:25
|
LL | if let &Either::One(_t) = &e { }
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:298:34
+ --> $DIR/simple.rs:296:34
|
LL | while let &Either::One(_t) = &e { }
| ---------------- ^^ cannot move out of borrowed content
| help: consider removing the `&`: `Either::One(_t)`
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:298:28
+ --> $DIR/simple.rs:296:28
|
LL | while let &Either::One(_t) = &e { }
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:302:11
+ --> $DIR/simple.rs:300:11
|
LL | match &e {
| ^^ cannot move out of borrowed content
| help: consider removing the `&`: `Either::One(_t)`
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:304:22
+ --> $DIR/simple.rs:302:22
|
LL | &Either::One(_t)
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:310:11
+ --> $DIR/simple.rs:308:11
|
LL | match &e {
| ^^ cannot move out of borrowed content
| help: consider removing the `&`: `Either::One(_t)`
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:312:22
+ --> $DIR/simple.rs:310:22
|
LL | &Either::One(_t) => (),
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:317:11
+ --> $DIR/simple.rs:315:11
|
LL | match &e {
| ^^ cannot move out of borrowed content
| help: consider removing the `&`: `Either::One(_t)`
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:319:22
+ --> $DIR/simple.rs:317:22
|
LL | &Either::One(_t) => (),
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:325:22
+ --> $DIR/simple.rs:323:22
|
LL | let &mut X(_t) = &mut xm;
| ---------- ^^^^^^^ cannot move out of borrowed content
| help: consider removing the `&mut`: `X(_t)`
|
note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:325:16
+ --> $DIR/simple.rs:323:16
|
LL | let &mut X(_t) = &mut xm;
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:329:35
+ --> $DIR/simple.rs:327:35
|
LL | if let &mut Either::One(_t) = &mut em { }
| -------------------- ^^^^^^^ cannot move out of borrowed content
| help: consider removing the `&mut`: `Either::One(_t)`
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:329:29
+ --> $DIR/simple.rs:327:29
|
LL | if let &mut Either::One(_t) = &mut em { }
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:333:38
+ --> $DIR/simple.rs:331:38
|
LL | while let &mut Either::One(_t) = &mut em { }
| -------------------- ^^^^^^^ cannot move out of borrowed content
| help: consider removing the `&mut`: `Either::One(_t)`
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:333:32
+ --> $DIR/simple.rs:331:32
|
LL | while let &mut Either::One(_t) = &mut em { }
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:337:11
+ --> $DIR/simple.rs:335:11
|
LL | match &mut em {
| ^^^^^^^ cannot move out of borrowed content
| help: consider removing the `&mut`: `Either::One(_t)`
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:339:26
+ --> $DIR/simple.rs:337:26
|
LL | &mut Either::One(_t)
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:345:11
+ --> $DIR/simple.rs:343:11
|
LL | match &mut em {
| ^^^^^^^ cannot move out of borrowed content
| help: consider removing the `&mut`: `Either::One(_t)`
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:347:26
+ --> $DIR/simple.rs:345:26
|
LL | &mut Either::One(_t) => (),
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:352:11
+ --> $DIR/simple.rs:350:11
|
LL | match &mut em {
| ^^^^^^^ cannot move out of borrowed content
| help: consider removing the `&mut`: `Either::One(_t)`
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:354:26
+ --> $DIR/simple.rs:352:26
|
LL | &mut Either::One(_t) => (),
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:359:11
+ --> $DIR/simple.rs:357:11
|
LL | match &mut em {
| ^^^^^^^ cannot move out of borrowed content
| help: consider removing the `&mut`: `Either::One(_t)`
|
note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:361:26
+ --> $DIR/simple.rs:359:26
|
LL | &mut Either::One(_t) => (),
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:204:11
+ --> $DIR/simple.rs:202:11
|
LL | fn f1(&X(_t): &X) { }
| ^^^--^
| help: consider removing the `&`: `X(_t)`
|
note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:204:14
+ --> $DIR/simple.rs:202:14
|
LL | fn f1(&X(_t): &X) { }
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:251:11
+ --> $DIR/simple.rs:249:11
|
LL | fn f2(&mut X(_t): &mut X) { }
| ^^^^^^^--^
| help: consider removing the `&mut`: `X(_t)`
|
note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:251:18
+ --> $DIR/simple.rs:249:18
|
LL | fn f2(&mut X(_t): &mut X) { }
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:271:11
+ --> $DIR/simple.rs:269:11
|
LL | fn f3((&X(_t),): (&X,)) { }
| ^^^^--^^^
| cannot move out of borrowed content
|
note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:271:15
+ --> $DIR/simple.rs:269:15
|
LL | fn f3((&X(_t),): (&X,)) { }
| ^^
error[E0507]: cannot move out of borrowed content
- --> $DIR/simple.rs:285:11
+ --> $DIR/simple.rs:283:11
|
LL | fn f4((&mut X(_t),): (&mut X,)) { }
| ^^^^^^^^--^^^
| cannot move out of borrowed content
|
note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
- --> $DIR/simple.rs:285:19
+ --> $DIR/simple.rs:283:19
|
LL | fn f4((&mut X(_t),): (&mut X,)) { }
| ^^
--- /dev/null
+// aux-build:foo.rs
+// compile-flags:--extern foo
+// compile-pass
+// edition:2018
+
+#![deny(unused_extern_crates)]
+
+extern crate foo as foo_renamed;
+
+pub mod m {
+ pub use foo_renamed::Foo;
+}
+
+fn main() {}
--- /dev/null
+error[E0310]: the parameter type `impl Debug` may not live long enough
+ --> $DIR/suggest-impl-trait-lifetime.rs:7:5
+ |
+LL | bar(d);
+ | ^^^^^^
+ |
+ = help: consider adding an explicit lifetime bound `impl Debug: 'static`...
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0310`.
-#![feature(nll)]
-
struct X(usize);
impl X {
error[E0594]: cannot assign to `self.0` which is behind a `&` reference
- --> $DIR/suggest-ref-mut.rs:9:9
+ --> $DIR/suggest-ref-mut.rs:7:9
|
LL | fn zap(&self) {
| ----- help: consider changing this to be a mutable reference: `&mut self`
| ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be written
error[E0594]: cannot assign to `*foo` which is behind a `&` reference
- --> $DIR/suggest-ref-mut.rs:18:5
+ --> $DIR/suggest-ref-mut.rs:16:5
|
LL | let ref foo = 16;
| ------- help: consider changing this to be a mutable reference: `ref mut foo`
| ^^^^^^^^^ `foo` is a `&` reference, so the data it refers to cannot be written
error[E0594]: cannot assign to `*bar` which is behind a `&` reference
- --> $DIR/suggest-ref-mut.rs:23:9
+ --> $DIR/suggest-ref-mut.rs:21:9
|
LL | if let Some(ref bar) = Some(16) {
| ------- help: consider changing this to be a mutable reference: `ref mut bar`
| ^^^^^^^^^ `bar` is a `&` reference, so the data it refers to cannot be written
error[E0594]: cannot assign to `*quo` which is behind a `&` reference
- --> $DIR/suggest-ref-mut.rs:27:22
+ --> $DIR/suggest-ref-mut.rs:25:22
|
LL | ref quo => { *quo = 32; },
| ------- ^^^^^^^^^ `quo` is a `&` reference, so the data it refers to cannot be written
--- /dev/null
+error[E0625]: thread-local statics cannot be accessed at compile-time
+ --> $DIR/thread-local-in-ctfe.rs:6:17
+ |
+LL | static B: u32 = A;
+ | ^
+
+error[E0625]: thread-local statics cannot be accessed at compile-time
+ --> $DIR/thread-local-in-ctfe.rs:9:18
+ |
+LL | static C: &u32 = &A;
+ | ^^
+
+error[E0712]: thread-local variable borrowed past end of function
+ --> $DIR/thread-local-in-ctfe.rs:9:18
+ |
+LL | static C: &u32 = &A;
+ | ^^- end of enclosing function is here
+ | |
+ | thread-local variables cannot be borrowed beyond the end of the function
+
+error[E0625]: thread-local statics cannot be accessed at compile-time
+ --> $DIR/thread-local-in-ctfe.rs:15:16
+ |
+LL | const D: u32 = A;
+ | ^
+
+error[E0625]: thread-local statics cannot be accessed at compile-time
+ --> $DIR/thread-local-in-ctfe.rs:18:17
+ |
+LL | const E: &u32 = &A;
+ | ^^
+
+error[E0712]: thread-local variable borrowed past end of function
+ --> $DIR/thread-local-in-ctfe.rs:18:17
+ |
+LL | const E: &u32 = &A;
+ | ^^- end of enclosing function is here
+ | |
+ | thread-local variables cannot be borrowed beyond the end of the function
+
+error[E0625]: thread-local statics cannot be accessed at compile-time
+ --> $DIR/thread-local-in-ctfe.rs:25:5
+ |
+LL | A
+ | ^
+
+error: aborting due to 7 previous errors
+
+For more information about this error, try `rustc --explain E0712`.
LL | Err("")?;
| ^ the trait `std::convert::From<&str>` is not implemented for `i32`
|
+ = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
= help: the following implementations were found:
<i32 as std::convert::From<bool>>
<i32 as std::convert::From<i16>>
LL | x?;
| ^ the trait `std::convert::From<std::option::NoneError>` is not implemented for `()`
|
+ = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
= note: required by `std::convert::From::from`
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `std::ops::Try`)
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/unboxed-closures-infer-argument-types-two-region-pointers.rs:17:9
+ |
+LL | doit(0, &|x, y| {
+ | - - has type `&'1 i32`
+ | |
+ | has type `&std::cell::Cell<&'2 i32>`
+LL | x.set(y);
+ | ^^^^^^^^ argument requires that `'1` must outlive `'2`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/dyn-trait-underscore.rs:8:5
+ |
+LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
+ | - let's call the lifetime of this reference `'1`
+LL | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
+LL | Box::new(items.iter())
+ | ^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/underscore-lifetime-elison-mismatch.rs:1:42
+ |
+LL | fn foo(x: &mut Vec<&'_ u8>, y: &'_ u8) { x.push(y); }
+ | - - ^^^^^^^^^ argument requires that `'1` must outlive `'2`
+ | | |
+ | | let's call the lifetime of this reference `'1`
+ | let's call the lifetime of this reference `'2`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/variance-btree-invariant-types.rs:4:5
+ |
+LL | fn iter_cov_key<'a, 'new>(v: IterMut<'a, &'static (), ()>) -> IterMut<'a, &'new (), ()> {
+ | ---- lifetime `'new` defined here
+LL | v
+ | ^ returning this value requires that `'new` must outlive `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/variance-btree-invariant-types.rs:7:5
+ |
+LL | fn iter_cov_val<'a, 'new>(v: IterMut<'a, (), &'static ()>) -> IterMut<'a, (), &'new ()> {
+ | ---- lifetime `'new` defined here
+LL | v
+ | ^ returning this value requires that `'new` must outlive `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/variance-btree-invariant-types.rs:10:5
+ |
+LL | fn iter_contra_key<'a, 'new>(v: IterMut<'a, &'new (), ()>) -> IterMut<'a, &'static (), ()> {
+ | ---- lifetime `'new` defined here
+LL | v
+ | ^ returning this value requires that `'new` must outlive `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/variance-btree-invariant-types.rs:13:5
+ |
+LL | fn iter_contra_val<'a, 'new>(v: IterMut<'a, (), &'new ()>) -> IterMut<'a, (), &'static ()> {
+ | ---- lifetime `'new` defined here
+LL | v
+ | ^ returning this value requires that `'new` must outlive `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/variance-btree-invariant-types.rs:18:5
+ |
+LL | fn occ_cov_key<'a, 'new>(v: OccupiedEntry<'a, &'static (), ()>)
+ | ---- lifetime `'new` defined here
+LL | -> OccupiedEntry<'a, &'new (), ()> {
+LL | v
+ | ^ returning this value requires that `'new` must outlive `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/variance-btree-invariant-types.rs:22:5
+ |
+LL | fn occ_cov_val<'a, 'new>(v: OccupiedEntry<'a, (), &'static ()>)
+ | ---- lifetime `'new` defined here
+LL | -> OccupiedEntry<'a, (), &'new ()> {
+LL | v
+ | ^ returning this value requires that `'new` must outlive `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/variance-btree-invariant-types.rs:26:5
+ |
+LL | fn occ_contra_key<'a, 'new>(v: OccupiedEntry<'a, &'new (), ()>)
+ | ---- lifetime `'new` defined here
+LL | -> OccupiedEntry<'a, &'static (), ()> {
+LL | v
+ | ^ returning this value requires that `'new` must outlive `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/variance-btree-invariant-types.rs:30:5
+ |
+LL | fn occ_contra_val<'a, 'new>(v: OccupiedEntry<'a, (), &'new ()>)
+ | ---- lifetime `'new` defined here
+LL | -> OccupiedEntry<'a, (), &'static ()> {
+LL | v
+ | ^ returning this value requires that `'new` must outlive `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/variance-btree-invariant-types.rs:35:5
+ |
+LL | fn vac_cov_key<'a, 'new>(v: VacantEntry<'a, &'static (), ()>)
+ | ---- lifetime `'new` defined here
+LL | -> VacantEntry<'a, &'new (), ()> {
+LL | v
+ | ^ returning this value requires that `'new` must outlive `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/variance-btree-invariant-types.rs:39:5
+ |
+LL | fn vac_cov_val<'a, 'new>(v: VacantEntry<'a, (), &'static ()>)
+ | ---- lifetime `'new` defined here
+LL | -> VacantEntry<'a, (), &'new ()> {
+LL | v
+ | ^ returning this value requires that `'new` must outlive `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/variance-btree-invariant-types.rs:43:5
+ |
+LL | fn vac_contra_key<'a, 'new>(v: VacantEntry<'a, &'new (), ()>)
+ | ---- lifetime `'new` defined here
+LL | -> VacantEntry<'a, &'static (), ()> {
+LL | v
+ | ^ returning this value requires that `'new` must outlive `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/variance-btree-invariant-types.rs:47:5
+ |
+LL | fn vac_contra_val<'a, 'new>(v: VacantEntry<'a, (), &'new ()>)
+ | ---- lifetime `'new` defined here
+LL | -> VacantEntry<'a, (), &'static ()> {
+LL | v
+ | ^ returning this value requires that `'new` must outlive `'static`
+
+error: aborting due to 12 previous errors
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/variance-cell-is-invariant.rs:14:12
+ |
+LL | fn use_<'short,'long>(c: Foo<'short>,
+ | ------ ----- lifetime `'long` defined here
+ | |
+ | lifetime `'short` defined here
+...
+LL | let _: Foo<'long> = c;
+ | ^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/variance-contravariant-arg-object.rs:14:5
+ |
+LL | fn get_min_from_max<'min, 'max>(v: Box<Get<&'max i32>>)
+ | ---- ---- lifetime `'max` defined here
+ | |
+ | lifetime `'min` defined here
+...
+LL | v
+ | ^ returning this value requires that `'min` must outlive `'max`
+
+error: lifetime may not live long enough
+ --> $DIR/variance-contravariant-arg-object.rs:22:5
+ |
+LL | fn get_max_from_min<'min, 'max, G>(v: Box<Get<&'min i32>>)
+ | ---- ---- lifetime `'max` defined here
+ | |
+ | lifetime `'min` defined here
+...
+LL | v
+ | ^ returning this value requires that `'min` must outlive `'max`
+
+error: aborting due to 2 previous errors
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/variance-contravariant-arg-trait-match.rs:13:5
+ |
+LL | fn get_min_from_max<'min, 'max, G>()
+ | ---- ---- lifetime `'max` defined here
+ | |
+ | lifetime `'min` defined here
+...
+LL | impls_get::<G,&'min i32>()
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'min` must outlive `'max`
+
+error: lifetime may not live long enough
+ --> $DIR/variance-contravariant-arg-trait-match.rs:21:5
+ |
+LL | fn get_max_from_min<'min, 'max, G>()
+ | ---- ---- lifetime `'max` defined here
+ | |
+ | lifetime `'min` defined here
+...
+LL | impls_get::<G,&'max i32>()
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'min` must outlive `'max`
+
+error: aborting due to 2 previous errors
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/variance-contravariant-self-trait-match.rs:13:5
+ |
+LL | fn get_min_from_max<'min, 'max, G>()
+ | ---- ---- lifetime `'max` defined here
+ | |
+ | lifetime `'min` defined here
+...
+LL | impls_get::<&'min G>();
+ | ^^^^^^^^^^^^^^^^^^^^ requires that `'min` must outlive `'max`
+
+error: lifetime may not live long enough
+ --> $DIR/variance-contravariant-self-trait-match.rs:22:5
+ |
+LL | fn get_max_from_min<'min, 'max, G>()
+ | ---- ---- lifetime `'max` defined here
+ | |
+ | lifetime `'min` defined here
+...
+LL | impls_get::<&'max G>();
+ | ^^^^^^^^^^^^^^^^^^^^ requires that `'min` must outlive `'max`
+
+error: aborting due to 2 previous errors
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/variance-covariant-arg-object.rs:15:5
+ |
+LL | fn get_min_from_max<'min, 'max>(v: Box<Get<&'max i32>>)
+ | ---- ---- lifetime `'max` defined here
+ | |
+ | lifetime `'min` defined here
+...
+LL | v
+ | ^ returning this value requires that `'min` must outlive `'max`
+
+error: lifetime may not live long enough
+ --> $DIR/variance-covariant-arg-object.rs:22:5
+ |
+LL | fn get_max_from_min<'min, 'max, G>(v: Box<Get<&'min i32>>)
+ | ---- ---- lifetime `'max` defined here
+ | |
+ | lifetime `'min` defined here
+...
+LL | v
+ | ^ returning this value requires that `'min` must outlive `'max`
+
+error: aborting due to 2 previous errors
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/variance-covariant-arg-trait-match.rs:14:5
+ |
+LL | fn get_min_from_max<'min, 'max, G>()
+ | ---- ---- lifetime `'max` defined here
+ | |
+ | lifetime `'min` defined here
+...
+LL | impls_get::<G,&'min i32>()
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'min` must outlive `'max`
+
+error: lifetime may not live long enough
+ --> $DIR/variance-covariant-arg-trait-match.rs:20:5
+ |
+LL | fn get_max_from_min<'min, 'max, G>()
+ | ---- ---- lifetime `'max` defined here
+ | |
+ | lifetime `'min` defined here
+...
+LL | impls_get::<G,&'max i32>()
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'min` must outlive `'max`
+
+error: aborting due to 2 previous errors
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/variance-covariant-self-trait-match.rs:14:5
+ |
+LL | fn get_min_from_max<'min, 'max, G>()
+ | ---- ---- lifetime `'max` defined here
+ | |
+ | lifetime `'min` defined here
+...
+LL | impls_get::<&'min G>();
+ | ^^^^^^^^^^^^^^^^^^^^ requires that `'min` must outlive `'max`
+
+error: lifetime may not live long enough
+ --> $DIR/variance-covariant-self-trait-match.rs:20:5
+ |
+LL | fn get_max_from_min<'min, 'max, G>()
+ | ---- ---- lifetime `'max` defined here
+ | |
+ | lifetime `'min` defined here
+...
+LL | impls_get::<&'max G>();
+ | ^^^^^^^^^^^^^^^^^^^^ requires that `'min` must outlive `'max`
+
+error: aborting due to 2 previous errors
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/variance-invariant-arg-object.rs:11:5
+ |
+LL | fn get_min_from_max<'min, 'max>(v: Box<Get<&'max i32>>)
+ | ---- ---- lifetime `'max` defined here
+ | |
+ | lifetime `'min` defined here
+...
+LL | v
+ | ^ returning this value requires that `'min` must outlive `'max`
+
+error: lifetime may not live long enough
+ --> $DIR/variance-invariant-arg-object.rs:18:5
+ |
+LL | fn get_max_from_min<'min, 'max, G>(v: Box<Get<&'min i32>>)
+ | ---- ---- lifetime `'max` defined here
+ | |
+ | lifetime `'min` defined here
+...
+LL | v
+ | ^ returning this value requires that `'min` must outlive `'max`
+
+error: aborting due to 2 previous errors
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/variance-invariant-arg-trait-match.rs:10:5
+ |
+LL | fn get_min_from_max<'min, 'max, G>()
+ | ---- ---- lifetime `'max` defined here
+ | |
+ | lifetime `'min` defined here
+...
+LL | impls_get::<G,&'min i32>()
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'min` must outlive `'max`
+
+error: lifetime may not live long enough
+ --> $DIR/variance-invariant-arg-trait-match.rs:16:5
+ |
+LL | fn get_max_from_min<'min, 'max, G>()
+ | ---- ---- lifetime `'max` defined here
+ | |
+ | lifetime `'min` defined here
+...
+LL | impls_get::<G,&'max i32>()
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'min` must outlive `'max`
+
+error: aborting due to 2 previous errors
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/variance-invariant-self-trait-match.rs:10:5
+ |
+LL | fn get_min_from_max<'min, 'max, G>()
+ | ---- ---- lifetime `'max` defined here
+ | |
+ | lifetime `'min` defined here
+...
+LL | impls_get::<&'min G>();
+ | ^^^^^^^^^^^^^^^^^^^^ requires that `'min` must outlive `'max`
+
+error: lifetime may not live long enough
+ --> $DIR/variance-invariant-self-trait-match.rs:16:5
+ |
+LL | fn get_max_from_min<'min, 'max, G>()
+ | ---- ---- lifetime `'max` defined here
+ | |
+ | lifetime `'min` defined here
+...
+LL | impls_get::<&'max G>();
+ | ^^^^^^^^^^^^^^^^^^^^ requires that `'min` must outlive `'max`
+
+error: aborting due to 2 previous errors
+
--- /dev/null
+error[E0621]: explicit lifetime required in the type of `get`
+ --> $DIR/variance-trait-matching.rs:24:5
+ |
+LL | fn get<'a, G>(get: &G) -> i32
+ | -- help: add explicit lifetime `'a` to the type of `get`: `&'a G`
+...
+LL | pick(get, &22)
+ | ^^^^^^^^^^^^^^ lifetime `'a` required
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0621`.
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/variance-use-contravariant-struct-1.rs:12:5
+ |
+LL | fn foo<'min,'max>(v: SomeStruct<&'max ()>)
+ | ---- ---- lifetime `'max` defined here
+ | |
+ | lifetime `'min` defined here
+...
+LL | v
+ | ^ returning this value requires that `'min` must outlive `'max`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/variance-use-covariant-struct-1.rs:10:5
+ |
+LL | fn foo<'min,'max>(v: SomeStruct<&'min ()>)
+ | ---- ---- lifetime `'max` defined here
+ | |
+ | lifetime `'min` defined here
+...
+LL | v
+ | ^ returning this value requires that `'min` must outlive `'max`
+
+error: aborting due to previous error
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/variance-use-invariant-struct-1.rs:12:5
+ |
+LL | fn foo<'min,'max>(v: SomeStruct<&'max ()>)
+ | ---- ---- lifetime `'max` defined here
+ | |
+ | lifetime `'min` defined here
+...
+LL | v
+ | ^ returning this value requires that `'min` must outlive `'max`
+
+error: lifetime may not live long enough
+ --> $DIR/variance-use-invariant-struct-1.rs:19:5
+ |
+LL | fn bar<'min,'max>(v: SomeStruct<&'min ()>)
+ | ---- ---- lifetime `'max` defined here
+ | |
+ | lifetime `'min` defined here
+...
+LL | v
+ | ^ returning this value requires that `'min` must outlive `'max`
+
+error: aborting due to 2 previous errors
+
--- /dev/null
+error: lifetime may not live long enough
+ --> $DIR/wf-static-method.rs:17:9
+ |
+LL | impl<'a, 'b> Foo<'a, 'b, Evil<'a, 'b>> for () {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | u
+ | ^ returning this value requires that `'b` must outlive `'a`
+
+error: lifetime may not live long enough
+ --> $DIR/wf-static-method.rs:26:18
+ |
+LL | impl<'a, 'b> Foo<'a, 'b, ()> for IndirectEvil<'a, 'b> {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | let me = Self::make_me();
+ | ^^^^^^^^^^^^^ requires that `'b` must outlive `'a`
+
+error: lifetime may not live long enough
+ --> $DIR/wf-static-method.rs:33:9
+ |
+LL | impl<'a, 'b> Evil<'a, 'b> {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | fn inherent_evil(u: &'b u32) -> &'a u32 {
+LL | u
+ | ^ returning this value requires that `'b` must outlive `'a`
+
+error: lifetime may not live long enough
+ --> $DIR/wf-static-method.rs:41:5
+ |
+LL | fn evil<'a, 'b>(b: &'b u32) -> &'a u32 {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | <()>::static_evil(b)
+ | ^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'b` must outlive `'a`
+
+error: lifetime may not live long enough
+ --> $DIR/wf-static-method.rs:45:5
+ |
+LL | fn indirect_evil<'a, 'b>(b: &'b u32) -> &'a u32 {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | <IndirectEvil>::static_evil(b)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'b` must outlive `'a`
+
+error: lifetime may not live long enough
+ --> $DIR/wf-static-method.rs:50:5
+ |
+LL | fn inherent_evil<'a, 'b>(b: &'b u32) -> &'a u32 {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | <Evil>::inherent_evil(b) // bug? shouldn't this be an error
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'b` must outlive `'a`
+
+error: aborting due to 6 previous errors
+
-Subproject commit 759b6161a328db1d4863139e90875308ecd25a75
+Subproject commit c4fcfb725b4be00c72eb9cf30c7d8b095577c280
-Subproject commit ad3269c4b510b94b7c0082f4bb341bee6ed1eca4
+Subproject commit 60a609acaed3bf2b3ec6ab995bccf0f03bc26060
[dependencies]
diff = "0.1.10"
env_logger = { version = "0.5", default-features = false }
-filetime = "0.2"
getopts = "0.2"
log = "0.4"
regex = "1.0"
use crate::common::{expected_output_path, output_base_dir, output_relative_path, UI_EXTENSIONS};
use crate::common::{Config, TestPaths};
use crate::common::{DebugInfoBoth, DebugInfoGdb, DebugInfoLldb, Mode, Pretty};
-use filetime::FileTime;
use getopts::Options;
use std::env;
use std::ffi::OsString;
use std::io::{self, ErrorKind};
use std::path::{Path, PathBuf};
use std::process::Command;
+use std::time::SystemTime;
use test::ColorConfig;
use crate::util::logv;
use walkdir::WalkDir;
#[derive(Debug, PartialEq, PartialOrd, Ord, Eq)]
struct Stamp {
- time: FileTime,
+ time: SystemTime,
file: PathBuf,
}
impl Stamp {
fn from_path(p: &Path) -> Self {
+ let time = fs::metadata(p)
+ .and_then(|metadata| metadata.modified())
+ .unwrap_or(SystemTime::UNIX_EPOCH);
+
Stamp {
- time: mtime(&p),
+ time,
file: p.into(),
}
}
- fn from_dir(path: &Path) -> impl Iterator<Item=Stamp> {
+ fn from_dir(path: &Path) -> impl Iterator<Item = Stamp> {
WalkDir::new(path)
.into_iter()
.map(|entry| entry.unwrap())
.filter(|entry| entry.file_type().is_file())
- .map(|entry| Stamp::from_path(entry.path()))
- }
-}
+ .map(|entry| {
+ let time = (|| -> io::Result<_> { entry.metadata()?.modified() })();
-fn mtime(path: &Path) -> FileTime {
- fs::metadata(path)
- .map(|f| FileTime::from_last_modification_time(&f))
- .unwrap_or_else(|_| FileTime::zero())
+ Stamp {
+ time: time.unwrap_or(SystemTime::UNIX_EPOCH),
+ file: entry.path().into(),
+ }
+ })
+ }
}
fn make_test_name(
use crate::common::{Incremental, MirOpt, RunMake, Ui, JsDocTest, Assembly};
use diff;
use crate::errors::{self, Error, ErrorKind};
-use filetime::FileTime;
use crate::header::TestProps;
use crate::json;
use regex::{Captures, Regex};
match self.config.compare_mode {
Some(CompareMode::Nll) => {
- // FIXME(#56993) use -Zborrowck=mir
- rustc.args(&["-Zborrowck=migrate"]);
+ rustc.args(&["-Zborrowck=mir"]);
}
Some(CompareMode::Polonius) => {
rustc.args(&["-Zpolonius", "-Zborrowck=mir"]);
}
fn check_mir_test_timestamp(&self, test_name: &str, output_file: &Path) {
- let t = |file| FileTime::from_last_modification_time(&fs::metadata(file).unwrap());
+ let t = |file| fs::metadata(file).unwrap().modified().unwrap();
let source_file = &self.testpaths.file;
let output_time = t(output_file);
let source_time = t(source_file);
use std::path::PathBuf;
use std::cell::RefCell;
+use syntax::edition::DEFAULT_EDITION;
use syntax::diagnostics::metadata::{get_metadata_dir, ErrorMetadataMap, ErrorMetadata};
use rustdoc::html::markdown::{Markdown, IdMap, ErrorCodes, PLAYGROUND};
Some(ref desc) => {
let mut id_map = self.0.borrow_mut();
write!(output, "{}",
- Markdown(desc, &[], RefCell::new(&mut id_map), ErrorCodes::Yes))?
+ Markdown(desc, &[], RefCell::new(&mut id_map),
+ ErrorCodes::Yes, DEFAULT_EDITION))?
},
None => write!(output, "<p>No description.</p>\n")?,
}
*slot.borrow_mut() = Some((None, String::from("https://play.rust-lang.org/")));
});
let (format, dst) = parse_args();
- let result = syntax::with_globals(move || {
+ let result = syntax::with_default_globals(move || {
main_with_result(format, &dst)
});
if let Err(e) = result {
-Subproject commit bc0c76d861a178911f3f506196a7404eda1e690d
+Subproject commit 0c85dbf3df0f545133dca24eccfc9f0f6107c7f8
-Subproject commit 5b8e99bb61958ca8abcb7c5eda70521726be1065
+Subproject commit 9692ca8fd82a8f96a4113dc4b88c1fb1d79c1c60
authors = ["The Rust Project Developers"]
name = "rustbook"
version = "0.1.0"
-license = "MIT/Apache-2.0"
+license = "MIT OR Apache-2.0"
edition = "2018"
[dependencies]
name = "rustc-std-workspace-alloc"
version = "1.0.0"
authors = ["Alex Crichton <alex@alexcrichton.com>"]
-license = 'MIT/Apache-2.0'
+license = 'MIT OR Apache-2.0'
description = """
Hack for the compiler's own build system
"""
name = "rustc-std-workspace-core"
version = "1.0.0"
authors = ["Alex Crichton <alex@alexcrichton.com>"]
-license = 'MIT/Apache-2.0'
+license = 'MIT OR Apache-2.0'
description = """
Hack for the compiler's own build system
"""
name = "rustc-workspace-hack"
version = "1.0.0"
authors = ["Alex Crichton <alex@alexcrichton.com>"]
-license = 'MIT/Apache-2.0'
+license = 'MIT OR Apache-2.0'
description = """
Hack for the compiler's own build system
"""
"The Rust Project Developers"]
name = "unstable-book-gen"
version = "0.1.0"
-license = "MIT/Apache-2.0"
+license = "MIT OR Apache-2.0"
edition = "2018"
[dependencies]
# I-* without I-nominated
"I-compilemem", "I-compiletime", "I-crash", "I-hang", "I-ICE", "I-slow",
]
+
+[assign]