diff options
Diffstat (limited to 'src')
264 files changed, 2820 insertions, 1193 deletions
diff --git a/src/Cargo.lock b/src/Cargo.lock index 09baaeadaee..747d72e604e 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -87,7 +87,7 @@ dependencies = [ [[package]] name = "atty" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", @@ -187,20 +187,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "cargo" version = "0.30.0" dependencies = [ - "atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "crates-io 0.18.0", "crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "curl 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "curl 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "git2 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "git2 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "git2-curl 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -210,12 +210,12 @@ dependencies = [ "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazycell 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "libgit2-sys 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)", + "libgit2-sys 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustfix 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustfix 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "same-file 1.0.2 (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.70 (registry+https://github.com/rust-lang/crates.io-index)", @@ -225,7 +225,7 @@ dependencies = [ "shell-escape 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "tar 0.4.16 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "termcolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -303,7 +303,7 @@ version = "2.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -410,7 +410,7 @@ dependencies = [ "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "rustfix 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rustfix 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", @@ -464,7 +464,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "crates-io" version = "0.18.0" dependencies = [ - "curl 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "curl 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", @@ -521,10 +521,10 @@ dependencies = [ [[package]] name = "curl" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "curl-sys 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "curl-sys 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -536,7 +536,7 @@ dependencies = [ [[package]] name = "curl-sys" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", @@ -622,7 +622,7 @@ name = "env_logger" version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -787,12 +787,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "git2" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "libgit2-sys 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)", + "libgit2-sys 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.9.33 (registry+https://github.com/rust-lang/crates.io-index)", @@ -804,8 +804,8 @@ name = "git2-curl" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "curl 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "git2 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "curl 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "git2 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1050,12 +1050,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libgit2-sys" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", "cmake 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", - "curl-sys 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "curl-sys 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", "libssh2-sys 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1383,7 +1383,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1844,7 +1844,7 @@ name = "rustc-ap-rustc_errors" version = "182.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-ap-rustc_data_structures 182.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-ap-serialize 182.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-ap-syntax_pos 182.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2097,7 +2097,7 @@ dependencies = [ name = "rustc_errors" version = "0.0.0" dependencies = [ - "atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_data_structures 0.0.0", "serialize 0.0.0", "syntax_pos 0.0.0", @@ -2354,19 +2354,7 @@ dependencies = [ [[package]] name = "rustfix" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rustfix" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2497,8 +2485,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "smallvec" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "socket2" @@ -2785,6 +2776,14 @@ dependencies = [ ] [[package]] +name = "termcolor" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "wincolor 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "termion" version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3026,6 +3025,14 @@ dependencies = [ ] [[package]] +name = "wincolor" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "workspace_symbol" version = "0.1.0" @@ -3056,7 +3063,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" "checksum assert_cli 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98589b0e465a6c510d95fceebd365bb79bedece7f6e18a480897f2015f85ec51" -"checksum atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2fc4a1aa4c24c0718a250f0681885c1af91419d242f29eb8f2ab28502d80dbd1" +"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" "checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a" "checksum backtrace-sys 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)" = "bff67d0c06556c0b8e6b5f090f0eac52d950d9dfd1d35ba04e4ca3543eaf6a7e" "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" @@ -3084,8 +3091,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" "checksum crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "09de9ee0fc255ace04c7fa0763c9395a945c37c8292bb554f8d48361d1dcf1b4" -"checksum curl 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "aaf20bbe084f285f215eef2165feed70d6b75ba29cad24469badb853a4a287d0" -"checksum curl-sys 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "db735aaa19154d8d4ba28e4a3546e90f13a14016a7a8ac10c799bae6929c00a4" +"checksum curl 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "893713db705eab9847e050268507b0e2a2aad64e90a831874bd4e8e0d67f9523" +"checksum curl-sys 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "de9cf174efdf90b5887c4e2e900769373c89c5e18152e8f3ed75b501a6f1c0fb" "checksum datafrog 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16d724bf4ffe77cdceeecd461009b5f8d9e23c5d645d68bedb4586bf43e7e142" "checksum derive-new 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ceed73957c449214f8440eec8ad7fa282b67dc9eacbb24a3085b15d60397a17a" "checksum diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3c2b69f912779fbb121ceb775d74d51e915af17aaebc38d28a592843a2dd0a3a" @@ -3113,7 +3120,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum futf 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7c9c1ce3fa9336301af935ab852c437817d14cd33690446569392e65170aac3b" "checksum futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "1a70b146671de62ec8c8ed572219ca5d594d9b06c0b364d5e67b722fc559b48c" "checksum getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "b900c08c1939860ce8b54dc6a89e26e00c04c380fd0e09796799bd7f12861e05" -"checksum git2 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "910a2df52d2354e4eb27aa12f3803ea86bf461a93e17028908ec0e356572aa7b" +"checksum git2 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b87cffac882c99f9654ca5eb4c6c61527b47bc1e113304f8c57333567cd31f2" "checksum git2-curl 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b502f6b1b467957403d168f0039e0c46fa6a1220efa2adaef25d5b267b5fe024" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" "checksum globset 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "142754da2c9b3722affd909f9e27f2a6700a7a303f362971e0a74c652005a43d" @@ -3138,7 +3145,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fb497c35d362b6a331cfd94956a07fc2c78a4604cdbee844a81170386b996dd3" "checksum lazycell 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d33a48d0365c96081958cc663eef834975cb1e8d8bea3378513fc72bdbf11e50" "checksum libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b685088df2b950fccadf07a7187c8ef846a959c142338a48f9dc0b94517eb5f1" -"checksum libgit2-sys 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)" = "9dcce5a1ecca1891ab06c1545a422fd4b35f65c19acec51ea638c66d5be0810d" +"checksum libgit2-sys 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c9051a4b288ba6f8728e9e52bb2510816946b8bcb2e20259e4d4cdc93b9ecafd" "checksum libssh2-sys 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c628b499e8d1a4f4bd09a95d6cb1f8aeb231b46a9d40959bbd0408f14dd63adf" "checksum libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "87f737ad6cc6fd6eefe3d9dc5412f1573865bded441300904d2f42269e140f16" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" @@ -3222,8 +3229,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rustc-rayon-core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40f06724db71e18d68b3b946fdf890ca8c921d9edccc1404fdfdb537b0d12649" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a54aa04a10c68c1c4eacb4337fd883b435997ede17a9385784b990777686b09a" -"checksum rustfix 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9da3cf9b79dc889a2c9879643f26d7a53e37e9361c7566b7d2787d5ace0d8396" -"checksum rustfix 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6e2613df31a403754605dba168ded93d529a2b88c5a63b78cf2421bb5d62c936" +"checksum rustfix 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "86f77b09d42bae4adfbcd105a8914e2d9fb46b63612c1a765b824a2b4a4bb814" "checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637" "checksum schannel 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "dc1fabf2a7b6483a141426e1afd09ad543520a77ac49bd03c286e7696ccfd77f" "checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" @@ -3237,7 +3243,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum shell-escape 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "170a13e64f2a51b77a45702ba77287f5c6829375b04a69cf2222acd17d0cfab9" "checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" "checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537" -"checksum smallvec 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "312a7df010092e73d6bbaf141957e868d4f30efd2bfd9bb1028ad91abec58514" +"checksum smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "26df3bb03ca5eac2e64192b723d51f56c1b1e0860e7c766281f4598f181acdc8" "checksum socket2 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "962a516af4d3a7c272cb3a1d50a8cc4e5b41802e4ad54cfb7bee8ba61d37d703" "checksum stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ffbc596e092fe5f598b12ef46cc03754085ac2f4d8c739ad61c4ae266cc3b3fa" "checksum string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25d70109977172b127fe834e5449e5ab1740b9ba49fa18a2020f509174f25423" @@ -3260,6 +3266,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1" "checksum term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e6b677dd1e8214ea1ef4297f85dbcbed8e8cdddb561040cc998ca2551c37561" "checksum termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "adc4587ead41bf016f11af03e55a624c06568b5a19db4e90fde573d805074f83" +"checksum termcolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "722426c4a0539da2c4ffd9b419d90ad540b4cff4a053be9069c908d4d07e2836" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" "checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" "checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" @@ -3290,6 +3297,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum wincolor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eeb06499a3a4d44302791052df005d5232b927ed1a9658146d842165c4de7767" +"checksum wincolor 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b9dc3aa9dcda98b5a16150c54619c1ead22e3d3a5d458778ae914be760aa981a" "checksum xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" "checksum xz2 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "df8bf41d3030c3577c9458fd6640a05afbf43b150d0b531b16bd77d3f794f27a" "checksum yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e66366e18dc58b46801afbf2ca7661a9f59cc8c5962c29892b6039b4f86fa992" diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index f2b2f6f1eeb..7192cae8956 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -296,8 +296,10 @@ fn main() { cmd.arg("--color=always"); } - if env::var_os("RUSTC_DENY_WARNINGS").is_some() { + if env::var_os("RUSTC_DENY_WARNINGS").is_some() && env::var_os("RUSTC_EXTERNAL_TOOL").is_none() + { cmd.arg("-Dwarnings"); + cmd.arg("-Dbare_trait_objects"); } if verbose > 1 { diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index 39c5c832831..8838cdeed86 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -12,7 +12,7 @@ use compile::{run_cargo, std_cargo, test_cargo, rustc_cargo, rustc_cargo_env, add_to_sysroot}; use builder::{RunConfig, Builder, ShouldRun, Step}; -use tool::{self, prepare_tool_cargo}; +use tool::{self, prepare_tool_cargo, SourceType}; use {Compiler, Mode}; use cache::{INTERNER, Interned}; use std::path::PathBuf; @@ -222,7 +222,8 @@ impl Step for Rustdoc { Mode::ToolRustc, target, "check", - "src/tools/rustdoc"); + "src/tools/rustdoc", + SourceType::InTree); let _folder = builder.fold_output(|| format!("stage{}-rustdoc", compiler.stage)); println!("Checking rustdoc artifacts ({} -> {})", &compiler.host, target); diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index f71cb119b77..fd3730ffc78 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -28,7 +28,7 @@ use build_helper::up_to_date; use util::symlink_dir; use builder::{Builder, Compiler, RunConfig, ShouldRun, Step}; -use tool::{self, prepare_tool_cargo, Tool}; +use tool::{self, prepare_tool_cargo, Tool, SourceType}; use compile; use cache::{INTERNER, Interned}; use config::Config; @@ -814,6 +814,7 @@ impl Step for Rustdoc { target, "doc", "src/tools/rustdoc", + SourceType::InTree, ); cargo.env("RUSTDOCFLAGS", "--document-private-items"); diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 639c96bc208..7c69197885c 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -30,7 +30,7 @@ use compile; use dist; use flags::Subcommand; use native; -use tool::{self, Tool}; +use tool::{self, Tool, SourceType}; use toolstate::ToolState; use util::{self, dylib_path, dylib_path_var}; use Crate as CargoCrate; @@ -222,17 +222,18 @@ impl Step for Cargo { compiler, target: self.host, }); - let mut cargo = builder.cargo(compiler, Mode::ToolRustc, self.host, "test"); - cargo - .arg("--manifest-path") - .arg(builder.src.join("src/tools/cargo/Cargo.toml")); + let mut cargo = tool::prepare_tool_cargo(builder, + compiler, + Mode::ToolRustc, + self.host, + "test", + "src/tools/cargo", + SourceType::Submodule); + if !builder.fail_fast { cargo.arg("--no-fail-fast"); } - // Don't build tests dynamically, just a pain to work with - cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1"); - // Don't run cross-compile tests, we may not have cross-compiled libstd libs // available. cargo.env("CFG_DISABLE_CROSS_TESTS", "1"); @@ -286,10 +287,8 @@ impl Step for Rls { Mode::ToolRustc, host, "test", - "src/tools/rls"); - - // Don't build tests dynamically, just a pain to work with - cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1"); + "src/tools/rls", + SourceType::Submodule); builder.add_rustc_lib_path(compiler, &mut cargo); @@ -341,10 +340,9 @@ impl Step for Rustfmt { Mode::ToolRustc, host, "test", - "src/tools/rustfmt"); + "src/tools/rustfmt", + SourceType::Submodule); - // Don't build tests dynamically, just a pain to work with - cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1"); let dir = testdir(builder, compiler.host); t!(fs::create_dir_all(&dir)); cargo.env("RUSTFMT_TEST_DIR", dir); @@ -392,13 +390,14 @@ impl Step for Miri { extra_features: Vec::new(), }); if let Some(miri) = miri { - let mut cargo = builder.cargo(compiler, Mode::ToolRustc, host, "test"); - cargo - .arg("--manifest-path") - .arg(builder.src.join("src/tools/miri/Cargo.toml")); + let mut cargo = tool::prepare_tool_cargo(builder, + compiler, + Mode::ToolRustc, + host, + "test", + "src/tools/miri", + SourceType::Submodule); - // Don't build tests dynamically, just a pain to work with - cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1"); // miri tests need to know about the stage sysroot cargo.env("MIRI_SYSROOT", builder.sysroot(compiler)); cargo.env("RUSTC_TEST_SUITE", builder.rustc(compiler)); @@ -450,13 +449,14 @@ impl Step for Clippy { extra_features: Vec::new(), }); if let Some(clippy) = clippy { - let mut cargo = builder.cargo(compiler, Mode::ToolRustc, host, "test"); - cargo - .arg("--manifest-path") - .arg(builder.src.join("src/tools/clippy/Cargo.toml")); + let mut cargo = tool::prepare_tool_cargo(builder, + compiler, + Mode::ToolRustc, + host, + "test", + "src/tools/clippy", + SourceType::Submodule); - // Don't build tests dynamically, just a pain to work with - cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1"); // clippy tests need to know about the stage sysroot cargo.env("SYSROOT", builder.sysroot(compiler)); cargo.env("RUSTC_TEST_SUITE", builder.rustc(compiler)); @@ -1739,7 +1739,8 @@ impl Step for CrateRustdoc { Mode::ToolRustc, target, test_kind.subcommand(), - "src/tools/rustdoc"); + "src/tools/rustdoc", + SourceType::InTree); if test_kind.subcommand() == "test" && !builder.fail_fast { cargo.arg("--no-fail-fast"); } diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 0969e5abe07..5e68b797b3d 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -76,13 +76,20 @@ impl Step for CleanTools { } #[derive(Debug, Clone, Hash, PartialEq, Eq)] +pub enum SourceType { + InTree, + Submodule, +} + +#[derive(Debug, Clone, Hash, PartialEq, Eq)] struct ToolBuild { compiler: Compiler, target: Interned<String>, tool: &'static str, path: &'static str, mode: Mode, - is_ext_tool: bool, + is_optional_tool: bool, + source_type: SourceType, extra_features: Vec<String>, } @@ -102,7 +109,7 @@ impl Step for ToolBuild { let target = self.target; let tool = self.tool; let path = self.path; - let is_ext_tool = self.is_ext_tool; + let is_optional_tool = self.is_optional_tool; match self.mode { Mode::ToolRustc => { @@ -115,7 +122,15 @@ impl Step for ToolBuild { _ => panic!("unexpected Mode for tool build") } - let mut cargo = prepare_tool_cargo(builder, compiler, self.mode, target, "build", path); + let mut cargo = prepare_tool_cargo( + builder, + compiler, + self.mode, + target, + "build", + path, + self.source_type, + ); cargo.arg("--features").arg(self.extra_features.join(" ")); let _folder = builder.fold_output(|| format!("stage{}-{}", compiler.stage, tool)); @@ -216,7 +231,7 @@ impl Step for ToolBuild { }); if !is_expected { - if !is_ext_tool { + if !is_optional_tool { exit(1); } else { return None; @@ -238,6 +253,7 @@ pub fn prepare_tool_cargo( target: Interned<String>, command: &'static str, path: &'static str, + source_type: SourceType, ) -> Command { let mut cargo = builder.cargo(compiler, mode, target, command); let dir = builder.src.join(path); @@ -247,6 +263,10 @@ pub fn prepare_tool_cargo( // stages and such and it's just easier if they're not dynamically linked. cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1"); + if source_type == SourceType::Submodule { + cargo.env("RUSTC_EXTERNAL_TOOL", "1"); + } + if let Some(dir) = builder.openssl_install_dir(target) { cargo.env("OPENSSL_STATIC", "1"); cargo.env("OPENSSL_DIR", dir); @@ -274,7 +294,8 @@ pub fn prepare_tool_cargo( } macro_rules! tool { - ($($name:ident, $path:expr, $tool_name:expr, $mode:expr $(,llvm_tools = $llvm:expr)*;)+) => { + ($($name:ident, $path:expr, $tool_name:expr, $mode:expr + $(,llvm_tools = $llvm:expr)* $(,is_external_tool = $external:expr)*;)+) => { #[derive(Copy, PartialEq, Eq, Clone)] pub enum Tool { $( @@ -351,7 +372,12 @@ macro_rules! tool { tool: $tool_name, mode: $mode, path: $path, - is_ext_tool: false, + is_optional_tool: false, + source_type: if false $(|| $external)* { + SourceType::Submodule + } else { + SourceType::InTree + }, extra_features: Vec::new(), }).expect("expected to build -- essential tool") } @@ -370,7 +396,8 @@ tool!( Compiletest, "src/tools/compiletest", "compiletest", Mode::ToolBootstrap, llvm_tools = true; BuildManifest, "src/tools/build-manifest", "build-manifest", Mode::ToolBootstrap; RemoteTestClient, "src/tools/remote-test-client", "remote-test-client", Mode::ToolBootstrap; - RustInstaller, "src/tools/rust-installer", "fabricate", Mode::ToolBootstrap; + RustInstaller, "src/tools/rust-installer", "fabricate", Mode::ToolBootstrap, + is_external_tool = true; RustdocTheme, "src/tools/rustdoc-themes", "rustdoc-themes", Mode::ToolBootstrap; ); @@ -401,7 +428,8 @@ impl Step for RemoteTestServer { tool: "remote-test-server", mode: Mode::ToolStd, path: "src/tools/remote-test-server", - is_ext_tool: false, + is_optional_tool: false, + source_type: SourceType::InTree, extra_features: Vec::new(), }).expect("expected to build -- essential tool") } @@ -449,12 +477,15 @@ impl Step for Rustdoc { target: builder.config.build, }); - let mut cargo = prepare_tool_cargo(builder, - build_compiler, - Mode::ToolRustc, - target, - "build", - "src/tools/rustdoc"); + let mut cargo = prepare_tool_cargo( + builder, + build_compiler, + Mode::ToolRustc, + target, + "build", + "src/tools/rustdoc", + SourceType::InTree, + ); // Most tools don't get debuginfo, but rustdoc should. cargo.env("RUSTC_DEBUGINFO", builder.config.rust_debuginfo.to_string()) @@ -525,7 +556,8 @@ impl Step for Cargo { tool: "cargo", mode: Mode::ToolRustc, path: "src/tools/cargo", - is_ext_tool: false, + is_optional_tool: false, + source_type: SourceType::Submodule, extra_features: Vec::new(), }).expect("expected to build -- essential tool") } @@ -574,7 +606,8 @@ macro_rules! tool_extended { mode: Mode::ToolRustc, path: $path, extra_features: $sel.extra_features, - is_ext_tool: true, + is_optional_tool: true, + source_type: SourceType::Submodule, }) } } diff --git a/src/build_helper/lib.rs b/src/build_helper/lib.rs index 00e5dee256e..1cbb8e49bfa 100644 --- a/src/build_helper/lib.rs +++ b/src/build_helper/lib.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![deny(bare_trait_objects)] - use std::fs::File; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; diff --git a/src/ci/docker/dist-various-2/Dockerfile b/src/ci/docker/dist-various-2/Dockerfile index e8d6c12de44..7adb32efa1d 100644 --- a/src/ci/docker/dist-various-2/Dockerfile +++ b/src/ci/docker/dist-various-2/Dockerfile @@ -34,12 +34,12 @@ COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh ENV \ - AR_x86_64_unknown_fuchsia=x86_64-unknown-fuchsia-ar \ - CC_x86_64_unknown_fuchsia=x86_64-unknown-fuchsia-clang \ - CXX_x86_64_unknown_fuchsia=x86_64-unknown-fuchsia-clang++ \ - AR_aarch64_unknown_fuchsia=aarch64-unknown-fuchsia-ar \ - CC_aarch64_unknown_fuchsia=aarch64-unknown-fuchsia-clang \ - CXX_aarch64_unknown_fuchsia=aarch64-unknown-fuchsia-clang++ \ + AR_x86_64_fuchsia=x86_64-fuchsia-ar \ + CC_x86_64_fuchsia=x86_64-fuchsia-clang \ + CXX_x86_64_fuchsia=x86_64-fuchsia-clang++ \ + AR_aarch64_fuchsia=aarch64-fuchsia-ar \ + CC_aarch64_fuchsia=aarch64-fuchsia-clang \ + CXX_aarch64_fuchsia=aarch64-fuchsia-clang++ \ AR_sparcv9_sun_solaris=sparcv9-sun-solaris2.10-ar \ CC_sparcv9_sun_solaris=sparcv9-sun-solaris2.10-gcc \ CXX_sparcv9_sun_solaris=sparcv9-sun-solaris2.10-g++ \ @@ -47,8 +47,8 @@ ENV \ CC_x86_64_sun_solaris=x86_64-sun-solaris2.10-gcc \ CXX_x86_64_sun_solaris=x86_64-sun-solaris2.10-g++ -ENV TARGETS=x86_64-unknown-fuchsia -ENV TARGETS=$TARGETS,aarch64-unknown-fuchsia +ENV TARGETS=x86_64-fuchsia +ENV TARGETS=$TARGETS,aarch64-fuchsia ENV TARGETS=$TARGETS,sparcv9-sun-solaris ENV TARGETS=$TARGETS,wasm32-unknown-unknown ENV TARGETS=$TARGETS,x86_64-sun-solaris diff --git a/src/ci/docker/dist-various-2/build-fuchsia-toolchain.sh b/src/ci/docker/dist-various-2/build-fuchsia-toolchain.sh index ef8f0c37f8c..ec19f7c4f45 100755 --- a/src/ci/docker/dist-various-2/build-fuchsia-toolchain.sh +++ b/src/ci/docker/dist-various-2/build-fuchsia-toolchain.sh @@ -39,7 +39,7 @@ build() { esac hide_output make -j$(getconf _NPROCESSORS_ONLN) $tgt - dst=/usr/local/${arch}-unknown-fuchsia + dst=/usr/local/${arch}-fuchsia mkdir -p $dst cp -a build-${tgt}/sysroot/include $dst/ cp -a build-${tgt}/sysroot/lib $dst/ @@ -55,11 +55,11 @@ rm -rf zircon for arch in x86_64 aarch64; do for tool in clang clang++; do - cat >/usr/local/bin/${arch}-unknown-fuchsia-${tool} <<EOF + cat >/usr/local/bin/${arch}-fuchsia-${tool} <<EOF #!/bin/sh -${tool} --target=${arch}-unknown-fuchsia --sysroot=/usr/local/${arch}-unknown-fuchsia "\$@" +${tool} --target=${arch}-fuchsia --sysroot=/usr/local/${arch}-fuchsia "\$@" EOF - chmod +x /usr/local/bin/${arch}-unknown-fuchsia-${tool} + chmod +x /usr/local/bin/${arch}-fuchsia-${tool} done - ln -s /usr/local/bin/llvm-ar /usr/local/bin/${arch}-unknown-fuchsia-ar + ln -s /usr/local/bin/llvm-ar /usr/local/bin/${arch}-fuchsia-ar done diff --git a/src/doc/reference b/src/doc/reference -Subproject 0f63519ea10c028f48b2dbf7d0a2454203b68b0 +Subproject 219e261ddb833a5683627b0a9be87a0f4486abb diff --git a/src/doc/unstable-book/src/language-features/infer-static-outlives-requirements.md b/src/doc/unstable-book/src/language-features/infer-static-outlives-requirements.md new file mode 100644 index 00000000000..f50472fb41e --- /dev/null +++ b/src/doc/unstable-book/src/language-features/infer-static-outlives-requirements.md @@ -0,0 +1,45 @@ +# `infer_static_outlives_requirements` + +The tracking issue for this feature is: [#44493] + +[#44493]: https://github.com/rust-lang/rust/issues/44493 + +------------------------ +The `infer_static_outlives_requirements` feature indicates that certain +`'static` outlives requirements can be infered by the compiler rather than +stating them explicitly. + +Note: It is an accompanying feature to `infer_outlives_requirements`, +which must be enabled to infer outlives requirements. + +For example, currently generic struct definitions that contain +references, require where-clauses of the form T: 'static. By using +this feature the outlives predicates will be infered, although +they may still be written explicitly. + +```rust,ignore (pseudo-Rust) +struct Foo<U> where U: 'static { // <-- currently required + bar: Bar<U> +} +struct Bar<T: 'static> { + x: T, +} +``` + + +## Examples: + +```rust,ignore (pseudo-Rust) +#![feature(infer_outlives_requirements)] +#![feature(infer_static_outlives_requirements)] + +#[rustc_outlives] +// Implicitly infer U: 'static +struct Foo<U> { + bar: Bar<U> +} +struct Bar<T: 'static> { + x: T, +} +``` + diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 63cf01a0fac..ef619527e06 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -72,7 +72,6 @@ test(no_crate_inject, attr(allow(unused_variables), deny(warnings))))] #![no_std] #![needs_allocator] -#![deny(bare_trait_objects)] #![deny(missing_debug_implementations)] #![cfg_attr(test, allow(deprecated))] // rand diff --git a/src/liballoc/tests/arc.rs b/src/liballoc/tests/arc.rs index 753873dd294..d90c22a3b18 100644 --- a/src/liballoc/tests/arc.rs +++ b/src/liballoc/tests/arc.rs @@ -18,7 +18,7 @@ fn uninhabited() { a = a.clone(); assert!(a.upgrade().is_none()); - let mut a: Weak<Any> = a; // Unsizing + let mut a: Weak<dyn Any> = a; // Unsizing a = a.clone(); assert!(a.upgrade().is_none()); } @@ -39,7 +39,7 @@ fn slice() { #[test] fn trait_object() { let a: Arc<u32> = Arc::new(4); - let a: Arc<Any> = a; // Unsizing + let a: Arc<dyn Any> = a; // Unsizing // Exercise is_dangling() with a DST let mut a = Arc::downgrade(&a); @@ -49,7 +49,7 @@ fn trait_object() { let mut b = Weak::<u32>::new(); b = b.clone(); assert!(b.upgrade().is_none()); - let mut b: Weak<Any> = b; // Unsizing + let mut b: Weak<dyn Any> = b; // Unsizing b = b.clone(); assert!(b.upgrade().is_none()); } diff --git a/src/liballoc/tests/btree/set.rs b/src/liballoc/tests/btree/set.rs index 6171b8ba624..0330bda5e32 100644 --- a/src/liballoc/tests/btree/set.rs +++ b/src/liballoc/tests/btree/set.rs @@ -40,7 +40,7 @@ fn test_hash() { } fn check<F>(a: &[i32], b: &[i32], expected: &[i32], f: F) - where F: FnOnce(&BTreeSet<i32>, &BTreeSet<i32>, &mut FnMut(&i32) -> bool) -> bool + where F: FnOnce(&BTreeSet<i32>, &BTreeSet<i32>, &mut dyn FnMut(&i32) -> bool) -> bool { let mut set_a = BTreeSet::new(); let mut set_b = BTreeSet::new(); diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs index 2c361598e89..618aff963f2 100644 --- a/src/liballoc/tests/lib.rs +++ b/src/liballoc/tests/lib.rs @@ -24,6 +24,7 @@ #![feature(try_reserve)] #![feature(unboxed_closures)] #![feature(exact_chunks)] +#![feature(repeat_generic_slice)] extern crate alloc_system; extern crate core; @@ -63,7 +64,7 @@ fn test_boxed_hasher() { 5u32.hash(&mut hasher_1); assert_eq!(ordinary_hash, hasher_1.finish()); - let mut hasher_2 = Box::new(DefaultHasher::new()) as Box<Hasher>; + let mut hasher_2 = Box::new(DefaultHasher::new()) as Box<dyn Hasher>; 5u32.hash(&mut hasher_2); assert_eq!(ordinary_hash, hasher_2.finish()); } diff --git a/src/liballoc/tests/rc.rs b/src/liballoc/tests/rc.rs index baa0406acfc..9ec7c831444 100644 --- a/src/liballoc/tests/rc.rs +++ b/src/liballoc/tests/rc.rs @@ -18,7 +18,7 @@ fn uninhabited() { a = a.clone(); assert!(a.upgrade().is_none()); - let mut a: Weak<Any> = a; // Unsizing + let mut a: Weak<dyn Any> = a; // Unsizing a = a.clone(); assert!(a.upgrade().is_none()); } @@ -39,7 +39,7 @@ fn slice() { #[test] fn trait_object() { let a: Rc<u32> = Rc::new(4); - let a: Rc<Any> = a; // Unsizing + let a: Rc<dyn Any> = a; // Unsizing // Exercise is_dangling() with a DST let mut a = Rc::downgrade(&a); @@ -49,7 +49,7 @@ fn trait_object() { let mut b = Weak::<u32>::new(); b = b.clone(); assert!(b.upgrade().is_none()); - let mut b: Weak<Any> = b; // Unsizing + let mut b: Weak<dyn Any> = b; // Unsizing b = b.clone(); assert!(b.upgrade().is_none()); } diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs index 3b7eec38609..df5e18a9a18 100644 --- a/src/liballoc/tests/slice.rs +++ b/src/liballoc/tests/slice.rs @@ -1529,3 +1529,14 @@ fn panic_safe() { } } } + +#[test] +fn repeat_generic_slice() { + assert_eq!([1, 2].repeat(2), vec![1, 2, 1, 2]); + assert_eq!([1, 2, 3, 4].repeat(0), vec![]); + assert_eq!([1, 2, 3, 4].repeat(1), vec![1, 2, 3, 4]); + assert_eq!( + [1, 2, 3, 4].repeat(3), + vec![1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4] + ); +} diff --git a/src/liballoc_jemalloc/lib.rs b/src/liballoc_jemalloc/lib.rs index 413b212281b..b3b20715511 100644 --- a/src/liballoc_jemalloc/lib.rs +++ b/src/liballoc_jemalloc/lib.rs @@ -10,7 +10,6 @@ #![no_std] #![allow(unused_attributes)] -#![deny(bare_trait_objects)] #![unstable(feature = "alloc_jemalloc", reason = "implementation detail of std, does not provide any public API", issue = "0")] diff --git a/src/liballoc_system/lib.rs b/src/liballoc_system/lib.rs index c6c0abefbab..64348e05de7 100644 --- a/src/liballoc_system/lib.rs +++ b/src/liballoc_system/lib.rs @@ -10,7 +10,6 @@ #![no_std] #![allow(unused_attributes)] -#![deny(bare_trait_objects)] #![unstable(feature = "alloc_system", reason = "this library is unlikely to be stabilized in its current \ form or name", diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index 6f692923c85..0f4a5d16e17 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -30,7 +30,6 @@ #![cfg_attr(test, feature(test))] #![allow(deprecated)] -#![deny(bare_trait_objects)] extern crate alloc; extern crate rustc_data_structures; diff --git a/src/libcore/any.rs b/src/libcore/any.rs index 94f23db1ccc..6b26093439e 100644 --- a/src/libcore/any.rs +++ b/src/libcore/any.rs @@ -120,7 +120,7 @@ impl<T: 'static + ?Sized > Any for T { /////////////////////////////////////////////////////////////////////////////// #[stable(feature = "rust1", since = "1.0.0")] -impl fmt::Debug for Any { +impl fmt::Debug for dyn Any { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.pad("Any") } @@ -130,20 +130,20 @@ impl fmt::Debug for Any { // hence used with `unwrap`. May eventually no longer be needed if // dispatch works with upcasting. #[stable(feature = "rust1", since = "1.0.0")] -impl fmt::Debug for Any + Send { +impl fmt::Debug for dyn Any + Send { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.pad("Any") } } #[stable(feature = "any_send_sync_methods", since = "1.28.0")] -impl fmt::Debug for Any + Send + Sync { +impl fmt::Debug for dyn Any + Send + Sync { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.pad("Any") } } -impl Any { +impl dyn Any { /// Returns `true` if the boxed type is the same as `T`. /// /// # Examples @@ -203,7 +203,7 @@ impl Any { pub fn downcast_ref<T: Any>(&self) -> Option<&T> { if self.is::<T>() { unsafe { - Some(&*(self as *const Any as *const T)) + Some(&*(self as *const dyn Any as *const T)) } } else { None @@ -240,7 +240,7 @@ impl Any { pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> { if self.is::<T>() { unsafe { - Some(&mut *(self as *mut Any as *mut T)) + Some(&mut *(self as *mut dyn Any as *mut T)) } } else { None @@ -248,7 +248,7 @@ impl Any { } } -impl Any+Send { +impl dyn Any+Send { /// Forwards to the method defined on the type `Any`. /// /// # Examples @@ -332,7 +332,7 @@ impl Any+Send { } } -impl Any+Send+Sync { +impl dyn Any+Send+Sync { /// Forwards to the method defined on the type `Any`. /// /// # Examples diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index b6087628ea6..137e9fe2c15 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -1532,7 +1532,7 @@ impl<T: CoerceUnsized<U>, U> CoerceUnsized<UnsafeCell<U>> for UnsafeCell<T> {} #[allow(unused)] fn assert_coerce_unsized(a: UnsafeCell<&i32>, b: Cell<&i32>, c: RefCell<&i32>) { - let _: UnsafeCell<&Send> = a; - let _: Cell<&Send> = b; - let _: RefCell<&Send> = c; + let _: UnsafeCell<&dyn Send> = a; + let _: Cell<&dyn Send> = b; + let _: RefCell<&dyn Send> = c; } diff --git a/src/libcore/fmt/builders.rs b/src/libcore/fmt/builders.rs index e8ea2e743da..3c5f934d4d8 100644 --- a/src/libcore/fmt/builders.rs +++ b/src/libcore/fmt/builders.rs @@ -11,7 +11,7 @@ use fmt; struct PadAdapter<'a> { - buf: &'a mut (fmt::Write + 'a), + buf: &'a mut (dyn fmt::Write + 'a), on_newline: bool, } @@ -107,7 +107,7 @@ pub fn debug_struct_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, impl<'a, 'b: 'a> DebugStruct<'a, 'b> { /// Adds a new field to the generated struct output. #[stable(feature = "debug_builders", since = "1.2.0")] - pub fn field(&mut self, name: &str, value: &fmt::Debug) -> &mut DebugStruct<'a, 'b> { + pub fn field(&mut self, name: &str, value: &dyn fmt::Debug) -> &mut DebugStruct<'a, 'b> { self.result = self.result.and_then(|_| { let prefix = if self.has_fields { "," @@ -204,7 +204,7 @@ pub fn debug_tuple_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str) -> D impl<'a, 'b: 'a> DebugTuple<'a, 'b> { /// Adds a new field to the generated tuple struct output. #[stable(feature = "debug_builders", since = "1.2.0")] - pub fn field(&mut self, value: &fmt::Debug) -> &mut DebugTuple<'a, 'b> { + pub fn field(&mut self, value: &dyn fmt::Debug) -> &mut DebugTuple<'a, 'b> { self.result = self.result.and_then(|_| { let (prefix, space) = if self.fields > 0 { (",", " ") @@ -258,7 +258,7 @@ struct DebugInner<'a, 'b: 'a> { } impl<'a, 'b: 'a> DebugInner<'a, 'b> { - fn entry(&mut self, entry: &fmt::Debug) { + fn entry(&mut self, entry: &dyn fmt::Debug) { self.result = self.result.and_then(|_| { if self.is_pretty() { let mut slot = None; @@ -340,7 +340,7 @@ pub fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b impl<'a, 'b: 'a> DebugSet<'a, 'b> { /// Adds a new entry to the set output. #[stable(feature = "debug_builders", since = "1.2.0")] - pub fn entry(&mut self, entry: &fmt::Debug) -> &mut DebugSet<'a, 'b> { + pub fn entry(&mut self, entry: &dyn fmt::Debug) -> &mut DebugSet<'a, 'b> { self.inner.entry(entry); self } @@ -411,7 +411,7 @@ pub fn debug_list_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a, impl<'a, 'b: 'a> DebugList<'a, 'b> { /// Adds a new entry to the list output. #[stable(feature = "debug_builders", since = "1.2.0")] - pub fn entry(&mut self, entry: &fmt::Debug) -> &mut DebugList<'a, 'b> { + pub fn entry(&mut self, entry: &dyn fmt::Debug) -> &mut DebugList<'a, 'b> { self.inner.entry(entry); self } @@ -482,7 +482,7 @@ pub fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b impl<'a, 'b: 'a> DebugMap<'a, 'b> { /// Adds a new entry to the map output. #[stable(feature = "debug_builders", since = "1.2.0")] - pub fn entry(&mut self, key: &fmt::Debug, value: &fmt::Debug) -> &mut DebugMap<'a, 'b> { + pub fn entry(&mut self, key: &dyn fmt::Debug, value: &dyn fmt::Debug) -> &mut DebugMap<'a, 'b> { self.result = self.result.and_then(|_| { if self.is_pretty() { let mut slot = None; diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index d91bf463383..928f95e3ba2 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -255,7 +255,7 @@ pub struct Formatter<'a> { width: Option<usize>, precision: Option<usize>, - buf: &'a mut (Write+'a), + buf: &'a mut (dyn Write+'a), curarg: slice::Iter<'a, ArgumentV1<'a>>, args: &'a [ArgumentV1<'a>], } @@ -272,7 +272,7 @@ struct Void { /// /// It was added after #45197 showed that one could share a `!Sync` /// object across threads by passing it into `format_args!`. - _oibit_remover: PhantomData<*mut Fn()>, + _oibit_remover: PhantomData<*mut dyn Fn()>, } /// This struct represents the generic "argument" which is taken by the Xprintf @@ -1020,7 +1020,7 @@ pub trait UpperExp { /// /// [`write!`]: ../../std/macro.write.html #[stable(feature = "rust1", since = "1.0.0")] -pub fn write(output: &mut Write, args: Arguments) -> Result { +pub fn write(output: &mut dyn Write, args: Arguments) -> Result { let mut formatter = Formatter { flags: 0, width: None, @@ -1062,7 +1062,7 @@ pub fn write(output: &mut Write, args: Arguments) -> Result { impl<'a> Formatter<'a> { fn wrap_buf<'b, 'c, F>(&'b mut self, wrap: F) -> Formatter<'c> - where 'b: 'c, F: FnOnce(&'b mut (Write+'b)) -> &'c mut (Write+'c) + where 'b: 'c, F: FnOnce(&'b mut (dyn Write+'b)) -> &'c mut (dyn Write+'c) { Formatter { // We want to change this @@ -1342,7 +1342,7 @@ impl<'a> Formatter<'a> { } fn write_formatted_parts(&mut self, formatted: &flt2dec::Formatted) -> Result { - fn write_bytes(buf: &mut Write, s: &[u8]) -> Result { + fn write_bytes(buf: &mut dyn Write, s: &[u8]) -> Result { buf.write_str(unsafe { str::from_utf8_unchecked(s) }) } diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index afc273d265b..48c6eb94144 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -18,7 +18,7 @@ use super::{Inspect, Map, Peekable, Scan, Skip, SkipWhile, StepBy, Take, TakeWhi use super::{Zip, Sum, Product}; use super::{ChainState, FromIterator, ZipImpl}; -fn _assert_is_object_safe(_: &Iterator<Item=()>) {} +fn _assert_is_object_safe(_: &dyn Iterator<Item=()>) {} /// An interface for dealing with iterators. /// diff --git a/src/libcore/manually_drop_stage0.rs b/src/libcore/manually_drop_stage0.rs new file mode 100644 index 00000000000..8643219cb61 --- /dev/null +++ b/src/libcore/manually_drop_stage0.rs @@ -0,0 +1,195 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +/// A wrapper to inhibit compiler from automatically calling `T`’s destructor. +/// +/// This wrapper is 0-cost. +/// +/// # Examples +/// +/// This wrapper helps with explicitly documenting the drop order dependencies between fields of +/// the type: +/// +/// ```rust +/// use std::mem::ManuallyDrop; +/// struct Peach; +/// struct Banana; +/// struct Melon; +/// struct FruitBox { +/// // Immediately clear there’s something non-trivial going on with these fields. +/// peach: ManuallyDrop<Peach>, +/// melon: Melon, // Field that’s independent of the other two. +/// banana: ManuallyDrop<Banana>, +/// } +/// +/// impl Drop for FruitBox { +/// fn drop(&mut self) { +/// unsafe { +/// // Explicit ordering in which field destructors are run specified in the intuitive +/// // location – the destructor of the structure containing the fields. +/// // Moreover, one can now reorder fields within the struct however much they want. +/// ManuallyDrop::drop(&mut self.peach); +/// ManuallyDrop::drop(&mut self.banana); +/// } +/// // After destructor for `FruitBox` runs (this function), the destructor for Melon gets +/// // invoked in the usual manner, as it is not wrapped in `ManuallyDrop`. +/// } +/// } +/// ``` +#[stable(feature = "manually_drop", since = "1.20.0")] +#[allow(unions_with_drop_fields)] +#[derive(Copy)] +pub union ManuallyDrop<T>{ value: T } + +impl<T> ManuallyDrop<T> { + /// Wrap a value to be manually dropped. + /// + /// # Examples + /// + /// ```rust + /// use std::mem::ManuallyDrop; + /// ManuallyDrop::new(Box::new(())); + /// ``` + #[stable(feature = "manually_drop", since = "1.20.0")] + #[rustc_const_unstable(feature = "const_manually_drop_new")] + #[inline] + pub const fn new(value: T) -> ManuallyDrop<T> { + ManuallyDrop { value: value } + } + + /// Extract the value from the ManuallyDrop container. + /// + /// # Examples + /// + /// ```rust + /// use std::mem::ManuallyDrop; + /// let x = ManuallyDrop::new(Box::new(())); + /// let _: Box<()> = ManuallyDrop::into_inner(x); + /// ``` + #[stable(feature = "manually_drop", since = "1.20.0")] + #[inline] + pub fn into_inner(slot: ManuallyDrop<T>) -> T { + unsafe { + slot.value + } + } + + /// Manually drops the contained value. + /// + /// # Safety + /// + /// This function runs the destructor of the contained value and thus the wrapped value + /// now represents uninitialized data. It is up to the user of this method to ensure the + /// uninitialized data is not actually used. + #[stable(feature = "manually_drop", since = "1.20.0")] + #[inline] + pub unsafe fn drop(slot: &mut ManuallyDrop<T>) { + ptr::drop_in_place(&mut slot.value) + } +} + +#[stable(feature = "manually_drop", since = "1.20.0")] +impl<T> Deref for ManuallyDrop<T> { + type Target = T; + #[inline] + fn deref(&self) -> &Self::Target { + unsafe { + &self.value + } + } +} + +#[stable(feature = "manually_drop", since = "1.20.0")] +impl<T> DerefMut for ManuallyDrop<T> { + #[inline] + fn deref_mut(&mut self) -> &mut Self::Target { + unsafe { + &mut self.value + } + } +} + +#[stable(feature = "manually_drop", since = "1.20.0")] +impl<T: ::fmt::Debug> ::fmt::Debug for ManuallyDrop<T> { + fn fmt(&self, fmt: &mut ::fmt::Formatter) -> ::fmt::Result { + unsafe { + fmt.debug_tuple("ManuallyDrop").field(&self.value).finish() + } + } +} + +#[stable(feature = "manually_drop_impls", since = "1.22.0")] +impl<T: Clone> Clone for ManuallyDrop<T> { + fn clone(&self) -> Self { + ManuallyDrop::new(self.deref().clone()) + } + + fn clone_from(&mut self, source: &Self) { + self.deref_mut().clone_from(source); + } +} + +#[stable(feature = "manually_drop_impls", since = "1.22.0")] +impl<T: Default> Default for ManuallyDrop<T> { + fn default() -> Self { + ManuallyDrop::new(Default::default()) + } +} + +#[stable(feature = "manually_drop_impls", since = "1.22.0")] +impl<T: PartialEq> PartialEq for ManuallyDrop<T> { + fn eq(&self, other: &Self) -> bool { + self.deref().eq(other) + } + + fn ne(&self, other: &Self) -> bool { + self.deref().ne(other) + } +} + +#[stable(feature = "manually_drop_impls", since = "1.22.0")] +impl<T: Eq> Eq for ManuallyDrop<T> {} + +#[stable(feature = "manually_drop_impls", since = "1.22.0")] +impl<T: PartialOrd> PartialOrd for ManuallyDrop<T> { + fn partial_cmp(&self, other: &Self) -> Option<::cmp::Ordering> { + self.deref().partial_cmp(other) + } + + fn lt(&self, other: &Self) -> bool { + self.deref().lt(other) + } + + fn le(&self, other: &Self) -> bool { + self.deref().le(other) + } + + fn gt(&self, other: &Self) -> bool { + self.deref().gt(other) + } + + fn ge(&self, other: &Self) -> bool { + self.deref().ge(other) + } +} + +#[stable(feature = "manually_drop_impls", since = "1.22.0")] +impl<T: Ord> Ord for ManuallyDrop<T> { + fn cmp(&self, other: &Self) -> ::cmp::Ordering { + self.deref().cmp(other) + } +} + +#[stable(feature = "manually_drop_impls", since = "1.22.0")] +impl<T: ::hash::Hash> ::hash::Hash for ManuallyDrop<T> { + fn hash<H: ::hash::Hasher>(&self, state: &mut H) { + self.deref().hash(state); + } +} diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index a0fe6e98806..1a54f03bb00 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -918,7 +918,6 @@ pub fn discriminant<T>(v: &T) -> Discriminant<T> { } } - /// A wrapper to inhibit compiler from automatically calling `T`’s destructor. /// /// This wrapper is 0-cost. @@ -954,11 +953,18 @@ pub fn discriminant<T>(v: &T) -> Discriminant<T> { /// } /// } /// ``` +#[cfg(not(stage0))] #[stable(feature = "manually_drop", since = "1.20.0")] -#[allow(unions_with_drop_fields)] -#[derive(Copy)] -pub union ManuallyDrop<T>{ value: T } +#[lang = "manually_drop"] +#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct ManuallyDrop<T> { + value: T, +} + +#[cfg(stage0)] +include!("manually_drop_stage0.rs"); +#[cfg(not(stage0))] impl<T> ManuallyDrop<T> { /// Wrap a value to be manually dropped. /// @@ -972,7 +978,7 @@ impl<T> ManuallyDrop<T> { #[rustc_const_unstable(feature = "const_manually_drop_new")] #[inline] pub const fn new(value: T) -> ManuallyDrop<T> { - ManuallyDrop { value: value } + ManuallyDrop { value } } /// Extract the value from the ManuallyDrop container. @@ -987,9 +993,7 @@ impl<T> ManuallyDrop<T> { #[stable(feature = "manually_drop", since = "1.20.0")] #[inline] pub fn into_inner(slot: ManuallyDrop<T>) -> T { - unsafe { - slot.value - } + slot.value } /// Manually drops the contained value. @@ -1006,102 +1010,22 @@ impl<T> ManuallyDrop<T> { } } +#[cfg(not(stage0))] #[stable(feature = "manually_drop", since = "1.20.0")] impl<T> Deref for ManuallyDrop<T> { type Target = T; #[inline] fn deref(&self) -> &Self::Target { - unsafe { - &self.value - } + &self.value } } +#[cfg(not(stage0))] #[stable(feature = "manually_drop", since = "1.20.0")] impl<T> DerefMut for ManuallyDrop<T> { #[inline] fn deref_mut(&mut self) -> &mut Self::Target { - unsafe { - &mut self.value - } - } -} - -#[stable(feature = "manually_drop", since = "1.20.0")] -impl<T: ::fmt::Debug> ::fmt::Debug for ManuallyDrop<T> { - fn fmt(&self, fmt: &mut ::fmt::Formatter) -> ::fmt::Result { - unsafe { - fmt.debug_tuple("ManuallyDrop").field(&self.value).finish() - } - } -} - -#[stable(feature = "manually_drop_impls", since = "1.22.0")] -impl<T: Clone> Clone for ManuallyDrop<T> { - fn clone(&self) -> Self { - ManuallyDrop::new(self.deref().clone()) - } - - fn clone_from(&mut self, source: &Self) { - self.deref_mut().clone_from(source); - } -} - -#[stable(feature = "manually_drop_impls", since = "1.22.0")] -impl<T: Default> Default for ManuallyDrop<T> { - fn default() -> Self { - ManuallyDrop::new(Default::default()) - } -} - -#[stable(feature = "manually_drop_impls", since = "1.22.0")] -impl<T: PartialEq> PartialEq for ManuallyDrop<T> { - fn eq(&self, other: &Self) -> bool { - self.deref().eq(other) - } - - fn ne(&self, other: &Self) -> bool { - self.deref().ne(other) - } -} - -#[stable(feature = "manually_drop_impls", since = "1.22.0")] -impl<T: Eq> Eq for ManuallyDrop<T> {} - -#[stable(feature = "manually_drop_impls", since = "1.22.0")] -impl<T: PartialOrd> PartialOrd for ManuallyDrop<T> { - fn partial_cmp(&self, other: &Self) -> Option<::cmp::Ordering> { - self.deref().partial_cmp(other) - } - - fn lt(&self, other: &Self) -> bool { - self.deref().lt(other) - } - - fn le(&self, other: &Self) -> bool { - self.deref().le(other) - } - - fn gt(&self, other: &Self) -> bool { - self.deref().gt(other) - } - - fn ge(&self, other: &Self) -> bool { - self.deref().ge(other) - } -} - -#[stable(feature = "manually_drop_impls", since = "1.22.0")] -impl<T: Ord> Ord for ManuallyDrop<T> { - fn cmp(&self, other: &Self) -> ::cmp::Ordering { - self.deref().cmp(other) - } -} - -#[stable(feature = "manually_drop_impls", since = "1.22.0")] -impl<T: ::hash::Hash> ::hash::Hash for ManuallyDrop<T> { - fn hash<H: ::hash::Hasher>(&self, state: &mut H) { - self.deref().hash(state); + &mut self.value } } diff --git a/src/libcore/panic.rs b/src/libcore/panic.rs index 10f02ca2fdc..17cac5aa0a0 100644 --- a/src/libcore/panic.rs +++ b/src/libcore/panic.rs @@ -43,7 +43,7 @@ use fmt; #[stable(feature = "panic_hooks", since = "1.10.0")] #[derive(Debug)] pub struct PanicInfo<'a> { - payload: &'a (Any + Send), + payload: &'a (dyn Any + Send), message: Option<&'a fmt::Arguments<'a>>, location: Location<'a>, } @@ -64,7 +64,7 @@ impl<'a> PanicInfo<'a> { #[doc(hidden)] #[inline] - pub fn set_payload(&mut self, info: &'a (Any + Send)) { + pub fn set_payload(&mut self, info: &'a (dyn Any + Send)) { self.payload = info; } @@ -86,7 +86,7 @@ impl<'a> PanicInfo<'a> { /// panic!("Normal panic"); /// ``` #[stable(feature = "panic_hooks", since = "1.10.0")] - pub fn payload(&self) -> &(Any + Send) { + pub fn payload(&self) -> &(dyn Any + Send) { self.payload } @@ -270,6 +270,6 @@ impl<'a> fmt::Display for Location<'a> { #[unstable(feature = "std_internals", issue = "0")] #[doc(hidden)] pub unsafe trait BoxMeUp { - fn box_me_up(&mut self) -> *mut (Any + Send); - fn get(&mut self) -> &(Any + Send); + fn box_me_up(&mut self) -> *mut (dyn Any + Send); + fn get(&mut self) -> &(dyn Any + Send); } diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index be82ab44cd1..fe5914c72e1 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -1162,8 +1162,8 @@ impl<T: ?Sized> *const T { /// /// Care must be taken with the ownership of `self` and `dest`. /// This method semantically moves the values of `self` into `dest`. - /// However it does not drop the contents of `self`, or prevent the contents - /// of `dest` from being dropped or used. + /// However it does not drop the contents of `dest`, or prevent the contents + /// of `self` from being dropped or used. /// /// # Examples /// diff --git a/src/libcore/slice/memchr.rs b/src/libcore/slice/memchr.rs index 7b62e7b0620..72e7b57a6cb 100644 --- a/src/libcore/slice/memchr.rs +++ b/src/libcore/slice/memchr.rs @@ -102,16 +102,13 @@ pub fn memrchr(x: u8, text: &[u8]) -> Option<usize> { let ptr = text.as_ptr(); let usize_bytes = mem::size_of::<usize>(); - // search to an aligned boundary - let end_align = (ptr as usize + len) & (usize_bytes - 1); - let mut offset; - if end_align > 0 { - offset = if end_align >= len { 0 } else { len - end_align }; - if let Some(index) = text[offset..].iter().rposition(|elt| *elt == x) { - return Some(offset + index); - } - } else { - offset = len; + let mut offset = { + // We call this just to obtain the length of the suffix + let (_, _, suffix) = unsafe { text.align_to::<usize>() }; + len - suffix.len() + }; + if let Some(index) = text[offset..].iter().rposition(|elt| *elt == x) { + return Some(offset + index); } // search the body of the text diff --git a/src/libcore/task/context.rs b/src/libcore/task/context.rs index c69d45248a5..1fc975cb178 100644 --- a/src/libcore/task/context.rs +++ b/src/libcore/task/context.rs @@ -21,7 +21,7 @@ use super::{Executor, Waker, LocalWaker}; /// when performing a single `poll` step on a task. pub struct Context<'a> { local_waker: &'a LocalWaker, - executor: &'a mut Executor, + executor: &'a mut dyn Executor, } impl<'a> fmt::Debug for Context<'a> { @@ -34,7 +34,7 @@ impl<'a> fmt::Debug for Context<'a> { impl<'a> Context<'a> { /// Create a new task `Context` with the provided `local_waker`, `waker`, and `executor`. #[inline] - pub fn new(local_waker: &'a LocalWaker, executor: &'a mut Executor) -> Context<'a> { + pub fn new(local_waker: &'a LocalWaker, executor: &'a mut dyn Executor) -> Context<'a> { Context { local_waker, executor, @@ -58,7 +58,7 @@ impl<'a> Context<'a> { /// This method is useful primarily if you want to explicitly handle /// spawn failures. #[inline] - pub fn executor(&mut self) -> &mut Executor { + pub fn executor(&mut self) -> &mut dyn Executor { self.executor } diff --git a/src/libcore/task/wake.rs b/src/libcore/task/wake.rs index 3b901c9aef0..321b432d3f4 100644 --- a/src/libcore/task/wake.rs +++ b/src/libcore/task/wake.rs @@ -23,7 +23,7 @@ use ptr::NonNull; /// trait, allowing notifications to get routed through it. #[repr(transparent)] pub struct Waker { - inner: NonNull<UnsafeWake>, + inner: NonNull<dyn UnsafeWake>, } impl Unpin for Waker {} @@ -41,7 +41,7 @@ impl Waker { /// use the `Waker::from` function instead which works with the safe /// `Arc` type and the safe `Wake` trait. #[inline] - pub unsafe fn new(inner: NonNull<UnsafeWake>) -> Self { + pub unsafe fn new(inner: NonNull<dyn UnsafeWake>) -> Self { Waker { inner: inner } } @@ -98,7 +98,7 @@ impl Drop for Waker { /// behavior. #[repr(transparent)] pub struct LocalWaker { - inner: NonNull<UnsafeWake>, + inner: NonNull<dyn UnsafeWake>, } impl Unpin for LocalWaker {} @@ -119,7 +119,7 @@ impl LocalWaker { /// For this function to be used safely, it must be sound to call `inner.wake_local()` /// on the current thread. #[inline] - pub unsafe fn new(inner: NonNull<UnsafeWake>) -> Self { + pub unsafe fn new(inner: NonNull<dyn UnsafeWake>) -> Self { LocalWaker { inner: inner } } diff --git a/src/libcore/tests/any.rs b/src/libcore/tests/any.rs index 2d3e81aa131..a80bf939530 100644 --- a/src/libcore/tests/any.rs +++ b/src/libcore/tests/any.rs @@ -17,7 +17,7 @@ static TEST: &'static str = "Test"; #[test] fn any_referenced() { - let (a, b, c) = (&5 as &Any, &TEST as &Any, &Test as &Any); + let (a, b, c) = (&5 as &dyn Any, &TEST as &dyn Any, &Test as &dyn Any); assert!(a.is::<i32>()); assert!(!b.is::<i32>()); @@ -34,7 +34,11 @@ fn any_referenced() { #[test] fn any_owning() { - let (a, b, c) = (box 5_usize as Box<Any>, box TEST as Box<Any>, box Test as Box<Any>); + let (a, b, c) = ( + box 5_usize as Box<dyn Any>, + box TEST as Box<dyn Any>, + box Test as Box<dyn Any>, + ); assert!(a.is::<usize>()); assert!(!b.is::<usize>()); @@ -51,7 +55,7 @@ fn any_owning() { #[test] fn any_downcast_ref() { - let a = &5_usize as &Any; + let a = &5_usize as &dyn Any; match a.downcast_ref::<usize>() { Some(&5) => {} @@ -69,9 +73,9 @@ fn any_downcast_mut() { let mut a = 5_usize; let mut b: Box<_> = box 7_usize; - let a_r = &mut a as &mut Any; + let a_r = &mut a as &mut dyn Any; let tmp: &mut usize = &mut *b; - let b_r = tmp as &mut Any; + let b_r = tmp as &mut dyn Any; match a_r.downcast_mut::<usize>() { Some(x) => { @@ -113,7 +117,7 @@ fn any_downcast_mut() { #[test] fn any_fixed_vec() { let test = [0_usize; 8]; - let test = &test as &Any; + let test = &test as &dyn Any; assert!(test.is::<[usize; 8]>()); assert!(!test.is::<[usize; 10]>()); } diff --git a/src/libcore/tests/hash/mod.rs b/src/libcore/tests/hash/mod.rs index 8716421b424..85c9d41b65b 100644 --- a/src/libcore/tests/hash/mod.rs +++ b/src/libcore/tests/hash/mod.rs @@ -128,7 +128,7 @@ fn test_custom_state() { fn test_indirect_hasher() { let mut hasher = MyHasher { hash: 0 }; { - let mut indirect_hasher: &mut Hasher = &mut hasher; + let mut indirect_hasher: &mut dyn Hasher = &mut hasher; 5u32.hash(&mut indirect_hasher); } assert_eq!(hasher.hash, 5); diff --git a/src/libcore/tests/intrinsics.rs b/src/libcore/tests/intrinsics.rs index 2b380abf63c..9f3cba26a62 100644 --- a/src/libcore/tests/intrinsics.rs +++ b/src/libcore/tests/intrinsics.rs @@ -22,7 +22,7 @@ fn test_typeid_sized_types() { #[test] fn test_typeid_unsized_types() { trait Z {} - struct X(str); struct Y(Z + 'static); + struct X(str); struct Y(dyn Z + 'static); assert_eq!(TypeId::of::<X>(), TypeId::of::<X>()); assert_eq!(TypeId::of::<Y>(), TypeId::of::<Y>()); diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index ca7db6e4639..6fcfaae4535 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -62,6 +62,7 @@ mod fmt; mod hash; mod intrinsics; mod iter; +mod manually_drop; mod mem; mod nonzero; mod num; diff --git a/src/libcore/tests/manually_drop.rs b/src/libcore/tests/manually_drop.rs new file mode 100644 index 00000000000..96bc9247da6 --- /dev/null +++ b/src/libcore/tests/manually_drop.rs @@ -0,0 +1,24 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use core::mem::ManuallyDrop; + +#[test] +fn smoke() { + struct TypeWithDrop; + impl Drop for TypeWithDrop { + fn drop(&mut self) { + unreachable!("Should not get dropped"); + } + } + + let x = ManuallyDrop::new(TypeWithDrop); + drop(x); +} diff --git a/src/libcore/tests/mem.rs b/src/libcore/tests/mem.rs index f55a1c81463..714f2babbdf 100644 --- a/src/libcore/tests/mem.rs +++ b/src/libcore/tests/mem.rs @@ -109,11 +109,11 @@ fn test_transmute() { trait Foo { fn dummy(&self) { } } impl Foo for isize {} - let a = box 100isize as Box<Foo>; + let a = box 100isize as Box<dyn Foo>; unsafe { let x: ::core::raw::TraitObject = transmute(a); assert!(*(x.data as *const isize) == 100); - let _x: Box<Foo> = transmute(x); + let _x: Box<dyn Foo> = transmute(x); } unsafe { diff --git a/src/libcore/tests/option.rs b/src/libcore/tests/option.rs index bc3e61a4f54..324ebf43565 100644 --- a/src/libcore/tests/option.rs +++ b/src/libcore/tests/option.rs @@ -240,7 +240,7 @@ fn test_collect() { assert!(v == None); // test that it does not take more elements than it needs - let mut functions: [Box<Fn() -> Option<()>>; 3] = + let mut functions: [Box<dyn Fn() -> Option<()>>; 3] = [box || Some(()), box || None, box || panic!()]; let v: Option<Vec<()>> = functions.iter_mut().map(|f| (*f)()).collect(); diff --git a/src/libcore/tests/ptr.rs b/src/libcore/tests/ptr.rs index 31bc1d67768..92160910d8f 100644 --- a/src/libcore/tests/ptr.rs +++ b/src/libcore/tests/ptr.rs @@ -84,16 +84,16 @@ fn test_is_null() { assert!(nms.is_null()); // Pointers to unsized types -- trait objects - let ci: *const ToString = &3; + let ci: *const dyn ToString = &3; assert!(!ci.is_null()); - let mi: *mut ToString = &mut 3; + let mi: *mut dyn ToString = &mut 3; assert!(!mi.is_null()); - let nci: *const ToString = null::<isize>(); + let nci: *const dyn ToString = null::<isize>(); assert!(nci.is_null()); - let nmi: *mut ToString = null_mut::<isize>(); + let nmi: *mut dyn ToString = null_mut::<isize>(); assert!(nmi.is_null()); } @@ -140,16 +140,16 @@ fn test_as_ref() { assert_eq!(nms.as_ref(), None); // Pointers to unsized types -- trait objects - let ci: *const ToString = &3; + let ci: *const dyn ToString = &3; assert!(ci.as_ref().is_some()); - let mi: *mut ToString = &mut 3; + let mi: *mut dyn ToString = &mut 3; assert!(mi.as_ref().is_some()); - let nci: *const ToString = null::<isize>(); + let nci: *const dyn ToString = null::<isize>(); assert!(nci.as_ref().is_none()); - let nmi: *mut ToString = null_mut::<isize>(); + let nmi: *mut dyn ToString = null_mut::<isize>(); assert!(nmi.as_ref().is_none()); } } @@ -182,10 +182,10 @@ fn test_as_mut() { assert_eq!(nms.as_mut(), None); // Pointers to unsized types -- trait objects - let mi: *mut ToString = &mut 3; + let mi: *mut dyn ToString = &mut 3; assert!(mi.as_mut().is_some()); - let nmi: *mut ToString = null_mut::<isize>(); + let nmi: *mut dyn ToString = null_mut::<isize>(); assert!(nmi.as_mut().is_none()); } } diff --git a/src/libcore/tests/result.rs b/src/libcore/tests/result.rs index d9927ce4487..0616252c82c 100644 --- a/src/libcore/tests/result.rs +++ b/src/libcore/tests/result.rs @@ -81,7 +81,7 @@ fn test_collect() { assert!(v == Err(2)); // test that it does not take more elements than it needs - let mut functions: [Box<Fn() -> Result<(), isize>>; 3] = + let mut functions: [Box<dyn Fn() -> Result<(), isize>>; 3] = [box || Ok(()), box || Err(1), box || panic!()]; let v: Result<Vec<()>, isize> = functions.iter_mut().map(|f| (*f)()).collect(); diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs index 30a3bbdc58e..3aa09a91e07 100644 --- a/src/libfmt_macros/lib.rs +++ b/src/libfmt_macros/lib.rs @@ -14,8 +14,6 @@ //! Parsing does not happen at runtime: structures of `std::fmt::rt` are //! generated instead. -#![deny(bare_trait_objects)] - # -#![deny(bare_trait_objects)] - #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/", diff --git a/src/libpanic_abort/lib.rs b/src/libpanic_abort/lib.rs index 02ab28507d7..392bf17968f 100644 --- a/src/libpanic_abort/lib.rs +++ b/src/libpanic_abort/lib.rs @@ -21,7 +21,6 @@ issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/")] #![panic_runtime] #![allow(unused_features)] -#![deny(bare_trait_objects)] #![feature(core_intrinsics)] #![feature(libc)] diff --git a/src/libpanic_unwind/lib.rs b/src/libpanic_unwind/lib.rs index f8cd29fc086..5c320bb369e 100644 --- a/src/libpanic_unwind/lib.rs +++ b/src/libpanic_unwind/lib.rs @@ -22,7 +22,6 @@ //! More documentation about each implementation can be found in the respective //! module. -#![deny(bare_trait_objects)] #![no_std] #![unstable(feature = "panic_unwind", issue = "32837")] # for more. #![stable(feature = "proc_macro_lib", since = "1.15.0")] -#![deny(bare_trait_objects)] #![deny(missing_docs)] #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", diff --git a/src/libprofiler_builtins/lib.rs b/src/libprofiler_builtins/lib.rs index 3d91505cd77..6d0d6d115b7 100644 --- a/src/libprofiler_builtins/lib.rs +++ b/src/libprofiler_builtins/lib.rs @@ -15,5 +15,4 @@ reason = "internal implementation detail of rustc right now", issue = "0")] #![allow(unused_features)] -#![deny(bare_trait_objects)] #![feature(staged_api)] diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 3b030fc098f..7e2c5d03d6b 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -746,7 +746,7 @@ impl<'a> LoweringContext<'a> { // This is used to track which lifetimes have already been defined, and // which are new in-band lifetimes that need to have a definition created // for them. - fn with_in_scope_lifetime_defs<T, F>(&mut self, params: &Vec<GenericParam>, f: F) -> T + fn with_in_scope_lifetime_defs<T, F>(&mut self, params: &[GenericParam], f: F) -> T where F: FnOnce(&mut LoweringContext) -> T, { @@ -2237,7 +2237,7 @@ impl<'a> LoweringContext<'a> { fn lower_generic_params( &mut self, - params: &Vec<GenericParam>, + params: &[GenericParam], add_bounds: &NodeMap<Vec<GenericBound>>, mut itctx: ImplTraitContext, ) -> hir::HirVec<hir::GenericParam> { diff --git a/src/librustc/hir/map/hir_id_validator.rs b/src/librustc/hir/map/hir_id_validator.rs index 656f325b4dd..a17c160c4d0 100644 --- a/src/librustc/hir/map/hir_id_validator.rs +++ b/src/librustc/hir/map/hir_id_validator.rs @@ -105,7 +105,7 @@ impl<'a, 'hir: 'a> HirIdValidator<'a, 'hir> { .collect(); // Try to map those to something more useful - let mut missing_items = vec![]; + let mut missing_items = Vec::with_capacity(missing.len()); for local_id in missing { let hir_id = HirId { diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs index 04b725957b6..05361b65641 100644 --- a/src/librustc/ich/hcx.rs +++ b/src/librustc/ich/hcx.rs @@ -396,7 +396,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for Span { pub fn hash_stable_trait_impls<'a, 'gcx, W, R>( hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher<W>, - blanket_impls: &Vec<DefId>, + blanket_impls: &[DefId], non_blanket_impls: &HashMap<fast_reject::SimplifiedType, Vec<DefId>, R>) where W: StableHasherResult, R: std_hash::BuildHasher, diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index c9ac6cdedbb..c106966fb70 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -423,6 +423,7 @@ impl_stable_hash_for!(enum ::syntax_pos::FileName { Anon, MacroExpansion, ProcMacroSourceCode, + CliCrateAttr, CfgSpec, Custom(s) }); diff --git a/src/librustc/infer/anon_types/mod.rs b/src/librustc/infer/anon_types/mod.rs index ae4d88704a0..205f8c5ad06 100644 --- a/src/librustc/infer/anon_types/mod.rs +++ b/src/librustc/infer/anon_types/mod.rs @@ -691,25 +691,41 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> { // } // ``` if let Some(anon_node_id) = tcx.hir.as_local_node_id(def_id) { - let in_definition_scope = match tcx.hir.expect_item(anon_node_id).node { - // impl trait - hir::ItemKind::Existential(hir::ExistTy { - impl_trait_fn: Some(parent), - .. - }) => parent == self.parent_def_id, - // named existential types - hir::ItemKind::Existential(hir::ExistTy { - impl_trait_fn: None, - .. - }) => may_define_existential_type( - tcx, - self.parent_def_id, - anon_node_id, - ), - _ => { - let anon_parent_node_id = tcx.hir.get_parent(anon_node_id); - self.parent_def_id == tcx.hir.local_def_id(anon_parent_node_id) + let parent_def_id = self.parent_def_id; + let def_scope_default = || { + let anon_parent_node_id = tcx.hir.get_parent(anon_node_id); + parent_def_id == tcx.hir.local_def_id(anon_parent_node_id) + }; + let in_definition_scope = match tcx.hir.find(anon_node_id) { + Some(hir::map::NodeItem(item)) => match item.node { + // impl trait + hir::ItemKind::Existential(hir::ExistTy { + impl_trait_fn: Some(parent), + .. + }) => parent == self.parent_def_id, + // named existential types + hir::ItemKind::Existential(hir::ExistTy { + impl_trait_fn: None, + .. + }) => may_define_existential_type( + tcx, + self.parent_def_id, + anon_node_id, + ), + _ => def_scope_default(), }, + Some(hir::map::NodeImplItem(item)) => match item.node { + hir::ImplItemKind::Existential(_) => may_define_existential_type( + tcx, + self.parent_def_id, + anon_node_id, + ), + _ => def_scope_default(), + }, + _ => bug!( + "expected (impl) item, found {}", + tcx.hir.node_to_string(anon_node_id), + ), }; if in_definition_scope { return self.fold_anon_ty(ty, def_id, substs); diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs index dbcb63addb8..693219ec4b0 100644 --- a/src/librustc/infer/error_reporting/need_type_info.rs +++ b/src/librustc/infer/error_reporting/need_type_info.rs @@ -74,7 +74,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindLocalByTypeVisitor<'a, 'gcx, 'tcx> { impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { - fn extract_type_name(&self, ty: &'a Ty<'tcx>) -> String { + pub fn extract_type_name(&self, ty: &'a Ty<'tcx>) -> String { if let ty::TyInfer(ty::TyVar(ty_vid)) = (*ty).sty { let ty_vars = self.type_variables.borrow(); if let TypeVariableOrigin::TypeParameterDefinition(_, name) = diff --git a/src/librustc/infer/outlives/obligations.rs b/src/librustc/infer/outlives/obligations.rs index 07286f1250c..b8991a0366a 100644 --- a/src/librustc/infer/outlives/obligations.rs +++ b/src/librustc/infer/outlives/obligations.rs @@ -505,11 +505,7 @@ where } fn recursive_type_bound(&self, ty: Ty<'tcx>) -> VerifyBound<'tcx> { - let mut bounds = vec![]; - - for subty in ty.walk_shallow() { - bounds.push(self.type_bound(subty)); - } + let mut bounds = ty.walk_shallow().map(|subty| self.type_bound(subty)).collect::<Vec<_>>(); let mut regions = ty.regions(); regions.retain(|r| !r.is_late_bound()); // ignore late-bound regions diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index d709a4debd1..b6cb336648b 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -36,8 +36,6 @@ //! //! This API is completely unstable and subject to change. -#![deny(bare_trait_objects)] - #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 5c1009fb31f..14cfaa81533 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -219,7 +219,7 @@ impl LintStore { } } - let mut future_incompatible = vec![]; + let mut future_incompatible = Vec::with_capacity(lints.len()); for lint in lints { future_incompatible.push(lint.id); self.future_incompatible.insert(lint.id, lint); diff --git a/src/librustc/middle/borrowck.rs b/src/librustc/middle/borrowck.rs index 6f5791ed5d7..c8d513a59f0 100644 --- a/src/librustc/middle/borrowck.rs +++ b/src/librustc/middle/borrowck.rs @@ -15,9 +15,15 @@ use util::nodemap::FxHashSet; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult}; +#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)] +pub enum SignalledError { SawSomeError, NoErrorsSeen } + +impl_stable_hash_for!(enum self::SignalledError { SawSomeError, NoErrorsSeen }); + #[derive(Debug, RustcEncodable, RustcDecodable)] pub struct BorrowCheckResult { pub used_mut_nodes: FxHashSet<HirId>, + pub signalled_any_error: SignalledError, } impl<'a> HashStable<StableHashingContext<'a>> for BorrowCheckResult { @@ -26,7 +32,9 @@ impl<'a> HashStable<StableHashingContext<'a>> for BorrowCheckResult { hasher: &mut StableHasher<W>) { let BorrowCheckResult { ref used_mut_nodes, + ref signalled_any_error, } = *self; used_mut_nodes.hash_stable(hcx, hasher); + signalled_any_error.hash_stable(hcx, hasher); } } diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 6c1ef851cbe..cf94a0fb4b4 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -324,6 +324,8 @@ language_item_table! { NonZeroItem, "non_zero", non_zero; + ManuallyDropItem, "manually_drop", manually_drop; + DebugTraitLangItem, "debug_trait", debug_trait; // A lang item for each of the 128-bit operators we can optionally lower. diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 54d9e24bbc0..8f3ed3106d5 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -455,15 +455,28 @@ pub enum BorrowckMode { Ast, Mir, Compare, + Migrate, } impl BorrowckMode { + /// Should we run the MIR-based borrow check, but also fall back + /// on the AST borrow check if the MIR-based one errors. + pub fn migrate(self) -> bool { + match self { + BorrowckMode::Ast => false, + BorrowckMode::Compare => false, + BorrowckMode::Mir => false, + BorrowckMode::Migrate => true, + } + } + /// Should we emit the AST-based borrow checker errors? pub fn use_ast(self) -> bool { match self { BorrowckMode::Ast => true, BorrowckMode::Compare => true, BorrowckMode::Mir => false, + BorrowckMode::Migrate => false, } } /// Should we emit the MIR-based borrow checker errors? @@ -472,6 +485,7 @@ impl BorrowckMode { BorrowckMode::Ast => false, BorrowckMode::Compare => true, BorrowckMode::Mir => true, + BorrowckMode::Migrate => true, } } } @@ -1127,7 +1141,7 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, emit_end_regions: bool = (false, parse_bool, [UNTRACKED], "emit EndRegion as part of MIR; enable transforms that solely process EndRegion"), borrowck: Option<String> = (None, parse_opt_string, [UNTRACKED], - "select which borrowck is used (`ast`, `mir`, or `compare`)"), + "select which borrowck is used (`ast`, `mir`, `migrate`, or `compare`)"), two_phase_borrows: bool = (false, parse_bool, [UNTRACKED], "use two-phase reserved/active distinction for `&mut` borrows in MIR borrowck"), two_phase_beyond_autoref: bool = (false, parse_bool, [UNTRACKED], @@ -1233,8 +1247,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "for every macro invocation, print its name and arguments"), debug_macros: bool = (false, parse_bool, [TRACKED], "emit line numbers debug info inside macros"), - enable_nonzeroing_move_hints: bool = (false, parse_bool, [TRACKED], - "force nonzeroing move optimization on"), keep_hygiene_data: bool = (false, parse_bool, [UNTRACKED], "don't clear the hygiene data after analysis"), keep_ast: bool = (false, parse_bool, [UNTRACKED], @@ -1355,6 +1367,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "don't run LLVM in parallel (while keeping codegen-units and ThinLTO)"), no_leak_check: bool = (false, parse_bool, [UNTRACKED], "disables the 'leak check' for subtyping; unsound, but useful for tests"), + crate_attr: Vec<String> = (Vec::new(), parse_string_push, [TRACKED], + "inject the given attribute in the crate"), } pub fn default_lib_output() -> CrateType { @@ -2168,6 +2182,7 @@ pub fn build_session_options_and_crate_config( None | Some("ast") => BorrowckMode::Ast, Some("mir") => BorrowckMode::Mir, Some("compare") => BorrowckMode::Compare, + Some("migrate") => BorrowckMode::Migrate, Some(m) => early_error(error_format, &format!("unknown borrowck mode `{}`", m)), }; @@ -3154,10 +3169,6 @@ mod tests { assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); opts = reference.clone(); - opts.debugging_opts.enable_nonzeroing_move_hints = true; - assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); - - opts = reference.clone(); opts.debugging_opts.show_span = Some(String::from("abc")); assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 77a1129f66d..7b8bbbf4a10 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -624,9 +624,6 @@ impl Session { pub fn unstable_options(&self) -> bool { self.opts.debugging_opts.unstable_options } - pub fn nonzeroing_move_hints(&self) -> bool { - self.opts.debugging_opts.enable_nonzeroing_move_hints - } pub fn overflow_checks(&self) -> bool { self.opts .cg diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs index 6a6bebdbd86..02bfab033ef 100644 --- a/src/librustc/traits/coherence.rs +++ b/src/librustc/traits/coherence.rs @@ -59,7 +59,7 @@ where F1: FnOnce(OverlapResult<'_>) -> R, F2: FnOnce() -> R, { - debug!("impl_can_satisfy(\ + debug!("overlapping_impls(\ impl1_def_id={:?}, \ impl2_def_id={:?}, intercrate_mode={:?})", diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 8300f98fb1c..5f8a2208bb0 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -48,7 +48,7 @@ use syntax_pos::{DUMMY_SP, Span}; impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { pub fn report_fulfillment_errors(&self, - errors: &Vec<FulfillmentError<'tcx>>, + errors: &[FulfillmentError<'tcx>], body_id: Option<hir::BodyId>, fallback_has_occurred: bool) { #[derive(Debug)] @@ -1015,7 +1015,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { ) -> DiagnosticBuilder<'tcx> { let kind = if is_closure { "closure" } else { "function" }; - let args_str = |arguments: &Vec<ArgKind>, other: &Vec<ArgKind>| { + let args_str = |arguments: &[ArgKind], other: &[ArgKind]| { let arg_length = arguments.len(); let distinct = match &other[..] { &[ArgKind::Tuple(..)] => true, diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index 83128ba75d5..aa4f63675d7 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -98,13 +98,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn astconv_object_safety_violations(self, trait_def_id: DefId) -> Vec<ObjectSafetyViolation> { - let mut violations = vec![]; - - for def_id in traits::supertrait_def_ids(self, trait_def_id) { - if self.predicates_reference_self(def_id, true) { - violations.push(ObjectSafetyViolation::SupertraitSelf); - } - } + let violations = traits::supertrait_def_ids(self, trait_def_id) + .filter(|&def_id| self.predicates_reference_self(def_id, true)) + .map(|_| ObjectSafetyViolation::SupertraitSelf) + .collect(); debug!("astconv_object_safety_violations(trait_def_id={:?}) = {:?}", trait_def_id, diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index 1052d029e0d..1ce60d8f055 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -1502,7 +1502,7 @@ fn confirm_impl_candidate<'cx, 'gcx, 'tcx>( let param_env = obligation.param_env; let assoc_ty = assoc_ty_def(selcx, impl_def_id, obligation.predicate.item_def_id); - let ty = if !assoc_ty.item.defaultness.has_value() { + if !assoc_ty.item.defaultness.has_value() { // This means that the impl is missing a definition for the // associated type. This error will be reported by the type // checker method `check_impl_items_against_trait`, so here we @@ -1510,11 +1510,18 @@ fn confirm_impl_candidate<'cx, 'gcx, 'tcx>( debug!("confirm_impl_candidate: no associated type {:?} for {:?}", assoc_ty.item.ident, obligation.predicate); - tcx.types.err + return Progress { + ty: tcx.types.err, + obligations: nested, + }; + } + let substs = translate_substs(selcx.infcx(), param_env, impl_def_id, substs, assoc_ty.node); + let ty = if let ty::AssociatedKind::Existential = assoc_ty.item.kind { + let item_substs = Substs::identity_for_item(tcx, assoc_ty.item.def_id); + tcx.mk_anon(assoc_ty.item.def_id, item_substs) } else { tcx.type_of(assoc_ty.item.def_id) }; - let substs = translate_substs(selcx.infcx(), param_env, impl_def_id, substs, assoc_ty.node); Progress { ty: ty.subst(tcx, substs), obligations: nested, diff --git a/src/librustc/traits/query/dropck_outlives.rs b/src/librustc/traits/query/dropck_outlives.rs index 73a9ff4e483..a48d24bb97a 100644 --- a/src/librustc/traits/query/dropck_outlives.rs +++ b/src/librustc/traits/query/dropck_outlives.rs @@ -243,7 +243,10 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'_, '_, 'tcx>, ty: Ty<'tcx>) -> ty::TyAdt(def, _) => { if def.is_union() { - // Unions never run have a dtor. + // Unions never have a dtor. + true + } else if Some(def.did) == tcx.lang_items().manually_drop() { + // `ManuallyDrop` never has a dtor. true } else { // Other types might. Moreover, PhantomData doesn't diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs index b64e4228be9..f9c0581d3ca 100644 --- a/src/librustc/traits/specialize/specialization_graph.rs +++ b/src/librustc/traits/specialize/specialization_graph.rs @@ -73,8 +73,8 @@ enum Inserted { /// The impl was inserted as a new child in this group of children. BecameNewSibling(Option<OverlapError>), - /// The impl replaced an existing impl that specializes it. - Replaced(DefId), + /// The impl should replace an existing impl X, because the impl specializes X. + ReplaceChild(DefId), /// The impl is a specialization of an existing child. ShouldRecurseOn(DefId), @@ -94,12 +94,34 @@ impl<'a, 'gcx, 'tcx> Children { impl_def_id: DefId) { let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap(); if let Some(sty) = fast_reject::simplify_type(tcx, trait_ref.self_ty(), false) { + debug!("insert_blindly: impl_def_id={:?} sty={:?}", impl_def_id, sty); self.nonblanket_impls.entry(sty).or_insert(vec![]).push(impl_def_id) } else { + debug!("insert_blindly: impl_def_id={:?} sty=None", impl_def_id); self.blanket_impls.push(impl_def_id) } } + /// Remove an impl from this set of children. Used when replacing + /// an impl with a parent. The impl must be present in the list of + /// children already. + fn remove_existing(&mut self, + tcx: TyCtxt<'a, 'gcx, 'tcx>, + impl_def_id: DefId) { + let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap(); + let vec: &mut Vec<DefId>; + if let Some(sty) = fast_reject::simplify_type(tcx, trait_ref.self_ty(), false) { + debug!("remove_existing: impl_def_id={:?} sty={:?}", impl_def_id, sty); + vec = self.nonblanket_impls.get_mut(&sty).unwrap(); + } else { + debug!("remove_existing: impl_def_id={:?} sty=None", impl_def_id); + vec = &mut self.blanket_impls; + } + + let index = vec.iter().position(|d| *d == impl_def_id).unwrap(); + vec.remove(index); + } + /// Attempt to insert an impl into this set of children, while comparing for /// specialization relationships. fn insert(&mut self, @@ -110,11 +132,22 @@ impl<'a, 'gcx, 'tcx> Children { { let mut last_lint = None; - for slot in match simplified_self { - Some(sty) => self.filtered_mut(sty), - None => self.iter_mut(), + debug!( + "insert(impl_def_id={:?}, simplified_self={:?})", + impl_def_id, + simplified_self, + ); + + for possible_sibling in match simplified_self { + Some(sty) => self.filtered(sty), + None => self.iter(), } { - let possible_sibling = *slot; + debug!( + "insert: impl_def_id={:?}, simplified_self={:?}, possible_sibling={:?}", + impl_def_id, + simplified_self, + possible_sibling, + ); let overlap_error = |overlap: traits::coherence::OverlapResult| { // overlap, but no specialization; error out @@ -168,9 +201,7 @@ impl<'a, 'gcx, 'tcx> Children { debug!("placing as parent of TraitRef {:?}", tcx.impl_trait_ref(possible_sibling).unwrap()); - // possible_sibling specializes the impl - *slot = impl_def_id; - return Ok(Inserted::Replaced(possible_sibling)); + return Ok(Inserted::ReplaceChild(possible_sibling)); } else { if !tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling) { traits::overlapping_impls( @@ -193,15 +224,14 @@ impl<'a, 'gcx, 'tcx> Children { Ok(Inserted::BecameNewSibling(last_lint)) } - fn iter_mut(&'a mut self) -> Box<dyn Iterator<Item = &'a mut DefId> + 'a> { - let nonblanket = self.nonblanket_impls.iter_mut().flat_map(|(_, v)| v.iter_mut()); - Box::new(self.blanket_impls.iter_mut().chain(nonblanket)) + fn iter(&mut self) -> Box<dyn Iterator<Item = DefId> + '_> { + let nonblanket = self.nonblanket_impls.iter_mut().flat_map(|(_, v)| v.iter()); + Box::new(self.blanket_impls.iter().chain(nonblanket).cloned()) } - fn filtered_mut(&'a mut self, sty: SimplifiedType) - -> Box<dyn Iterator<Item = &'a mut DefId> + 'a> { - let nonblanket = self.nonblanket_impls.entry(sty).or_insert(vec![]).iter_mut(); - Box::new(self.blanket_impls.iter_mut().chain(nonblanket)) + fn filtered(&mut self, sty: SimplifiedType) -> Box<dyn Iterator<Item = DefId> + '_> { + let nonblanket = self.nonblanket_impls.entry(sty).or_insert(vec![]).iter(); + Box::new(self.blanket_impls.iter().chain(nonblanket).cloned()) } } @@ -259,11 +289,38 @@ impl<'a, 'gcx, 'tcx> Graph { last_lint = opt_lint; break; } - Replaced(new_child) => { - self.parent.insert(new_child, impl_def_id); - let mut new_children = Children::new(); - new_children.insert_blindly(tcx, new_child); - self.children.insert(impl_def_id, new_children); + ReplaceChild(grand_child_to_be) => { + // We currently have + // + // P + // | + // G + // + // and we are inserting the impl N. We want to make it: + // + // P + // | + // N + // | + // G + + // Adjust P's list of children: remove G and then add N. + { + let siblings = self.children + .get_mut(&parent) + .unwrap(); + siblings.remove_existing(tcx, grand_child_to_be); + siblings.insert_blindly(tcx, impl_def_id); + } + + // Set G's parent to N and N's parent to P + self.parent.insert(grand_child_to_be, impl_def_id); + self.parent.insert(impl_def_id, parent); + + // Add G as N's child. + let mut grand_children = Children::new(); + grand_children.insert_blindly(tcx, grand_child_to_be); + self.children.insert(impl_def_id, grand_children); break; } ShouldRecurseOn(new_parent) => { @@ -377,9 +434,19 @@ impl<'a, 'gcx, 'tcx> Ancestors { trait_def_id: DefId, ) -> impl Iterator<Item = NodeItem<ty::AssociatedItem>> + Captures<'gcx> + Captures<'tcx> + 'a { self.flat_map(move |node| { - node.items(tcx).filter(move |impl_item| { - impl_item.kind == trait_item_kind && - tcx.hygienic_eq(impl_item.ident, trait_item_name, trait_def_id) + use ty::AssociatedKind::*; + node.items(tcx).filter(move |impl_item| match (trait_item_kind, impl_item.kind) { + | (Const, Const) + | (Method, Method) + | (Type, Type) + | (Type, Existential) + => tcx.hygienic_eq(impl_item.ident, trait_item_name, trait_def_id), + + | (Const, _) + | (Method, _) + | (Type, _) + | (Existential, _) + => false, }).map(move |item| NodeItem { node: node, item: item }) }) } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 41007508c50..98568f860a4 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -74,6 +74,7 @@ use rustc_target::spec::abi; use syntax::ast::{self, NodeId}; use syntax::attr; use syntax::codemap::MultiSpan; +use syntax::edition::Edition; use syntax::feature_gate; use syntax::symbol::{Symbol, keywords, InternedString}; use syntax_pos::Span; @@ -1366,6 +1367,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.borrowck_mode().use_mir() } + /// If true, we should use the MIR-based borrow check, but also + /// fall back on the AST borrow check if the MIR-based one errors. + pub fn migrate_borrowck(self) -> bool { + self.borrowck_mode().migrate() + } + /// If true, make MIR codegen for `match` emit a temp that holds a /// borrow of the input to the match expression. pub fn generate_borrow_of_any_match_input(&self) -> bool { @@ -1397,18 +1404,51 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// What mode(s) of borrowck should we run? AST? MIR? both? /// (Also considers the `#![feature(nll)]` setting.) pub fn borrowck_mode(&self) -> BorrowckMode { - match self.sess.opts.borrowck_mode { - mode @ BorrowckMode::Mir | - mode @ BorrowckMode::Compare => mode, + // Here are the main constraints we need to deal with: + // + // 1. An opts.borrowck_mode of `BorrowckMode::Ast` is + // synonymous with no `-Z borrowck=...` flag at all. + // (This is arguably a historical accident.) + // + // 2. `BorrowckMode::Migrate` is the limited migration to + // NLL that we are deploying with the 2018 edition. + // + // 3. We want to allow developers on the Nightly channel + // to opt back into the "hard error" mode for NLL, + // (which they can do via specifying `#![feature(nll)]` + // explicitly in their crate). + // + // So, this precedence list is how pnkfelix chose to work with + // the above constraints: + // + // * `#![feature(nll)]` *always* means use NLL with hard + // errors. (To simplify the code here, it now even overrides + // a user's attempt to specify `-Z borrowck=compare`, which + // we arguably do not need anymore and should remove.) + // + // * Otherwise, if no `-Z borrowck=...` flag was given (or + // if `borrowck=ast` was specified), then use the default + // as required by the edition. + // + // * Otherwise, use the behavior requested via `-Z borrowck=...` - mode @ BorrowckMode::Ast => { - if self.features().nll { - BorrowckMode::Mir - } else { - mode - } - } + if self.features().nll { return BorrowckMode::Mir; } + match self.sess.opts.borrowck_mode { + mode @ BorrowckMode::Mir | + mode @ BorrowckMode::Compare | + mode @ BorrowckMode::Migrate => mode, + + BorrowckMode::Ast => match self.sess.edition() { + Edition::Edition2015 => BorrowckMode::Ast, + Edition::Edition2018 => BorrowckMode::Migrate, + + // For now, future editions mean Migrate. (But it + // would make a lot of sense for it to be changed to + // `BorrowckMode::Mir`, depending on how we plan to + // time the forcing of full migration to NLL.) + _ => BorrowckMode::Migrate, + }, } } diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index d5425aff6ba..95caa0c185b 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -932,6 +932,9 @@ fn needs_drop_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Foreign types can never have destructors ty::TyForeign(..) => false, + // `ManuallyDrop` doesn't have a destructor regardless of field types. + ty::TyAdt(def, _) if Some(def.did) == tcx.lang_items().manually_drop() => false, + // Issue #22536: We first query type_moves_by_default. It sees a // normalized version of the type, and therefore will definitely // know whether the type implements Copy (and thus needs no @@ -967,7 +970,8 @@ fn needs_drop_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty::TyTuple(ref tys) => tys.iter().cloned().any(needs_drop), - // unions don't have destructors regardless of the child types + // unions don't have destructors because of the child types, + // only if they manually implement `Drop` (handled above). ty::TyAdt(def, _) if def.is_union() => false, ty::TyAdt(def, substs) => diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index c67453d2b20..15b5edaa3d5 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -19,7 +19,7 @@ use ty::{TyError, TyStr, TyArray, TySlice, TyFloat, TyFnDef, TyFnPtr}; use ty::{TyParam, TyRawPtr, TyRef, TyNever, TyTuple}; use ty::{TyClosure, TyGenerator, TyGeneratorWitness, TyForeign, TyProjection, TyAnon}; use ty::{TyDynamic, TyInt, TyUint, TyInfer}; -use ty::{self, Ty, TyCtxt, TypeFoldable, GenericParamCount, GenericParamDefKind}; +use ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable, GenericParamCount, GenericParamDefKind}; use util::nodemap::FxHashSet; use std::cell::Cell; @@ -32,6 +32,12 @@ use syntax::ast::CRATE_NODE_ID; use syntax::symbol::{Symbol, InternedString}; use hir; +thread_local! { + /// Mechanism for highlighting of specific regions for display in NLL region inference errors. + /// Contains region to highlight and counter for number to use when highlighting. + static HIGHLIGHT_REGION: Cell<Option<(RegionVid, usize)>> = Cell::new(None) +} + macro_rules! gen_display_debug_body { ( $with:path ) => { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -562,6 +568,19 @@ pub fn parameterized<F: fmt::Write>(f: &mut F, PrintContext::new().parameterized(f, substs, did, projections) } +fn get_highlight_region() -> Option<(RegionVid, usize)> { + HIGHLIGHT_REGION.with(|hr| hr.get()) +} + +pub fn with_highlight_region<R>(r: RegionVid, counter: usize, op: impl FnOnce() -> R) -> R { + HIGHLIGHT_REGION.with(|hr| { + assert_eq!(hr.get(), None); + hr.set(Some((r, counter))); + let r = op(); + hr.set(None); + r + }) +} impl<'a, T: Print> Print for &'a T { fn print<F: fmt::Write>(&self, f: &mut F, cx: &mut PrintContext) -> fmt::Result { @@ -733,7 +752,7 @@ define_print! { define_print! { () ty::RegionKind, (self, f, cx) { display { - if cx.is_verbose { + if cx.is_verbose || get_highlight_region().is_some() { return self.print_debug(f, cx); } @@ -905,6 +924,15 @@ impl fmt::Debug for ty::FloatVid { impl fmt::Debug for ty::RegionVid { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if let Some((region, counter)) = get_highlight_region() { + debug!("RegionVid.fmt: region={:?} self={:?} counter={:?}", region, self, counter); + return if *self == region { + write!(f, "'{:?}", counter) + } else { + write!(f, "'_") + } + } + write!(f, "'_#{}r", self.index()) } } @@ -1022,9 +1050,11 @@ define_print! { TyRef(r, ty, mutbl) => { write!(f, "&")?; let s = r.print_to_string(cx); - write!(f, "{}", s)?; - if !s.is_empty() { - write!(f, " ")?; + if s != "'_" { + write!(f, "{}", s)?; + if !s.is_empty() { + write!(f, " ")?; + } } ty::TypeAndMut { ty, mutbl }.print(f, cx) } diff --git a/src/librustc_allocator/lib.rs b/src/librustc_allocator/lib.rs index 1227936ce96..b217d3665a2 100644 --- a/src/librustc_allocator/lib.rs +++ b/src/librustc_allocator/lib.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![deny(bare_trait_objects)] #![feature(rustc_private)] #[macro_use] extern crate log; diff --git a/src/librustc_apfloat/lib.rs b/src/librustc_apfloat/lib.rs index c7cd958016d..08438805a70 100644 --- a/src/librustc_apfloat/lib.rs +++ b/src/librustc_apfloat/lib.rs @@ -40,8 +40,6 @@ //! //! This API is completely unstable and subject to change. -#![deny(bare_trait_objects)] - #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] diff --git a/src/librustc_asan/lib.rs b/src/librustc_asan/lib.rs index 7bd1e98f85d..0c78fd74a23 100644 --- a/src/librustc_asan/lib.rs +++ b/src/librustc_asan/lib.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![deny(bare_trait_objects)] - #![sanitizer_runtime] #![feature(alloc_system)] #![feature(sanitizer_runtime)] diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index 002e8697588..49bd69f8262 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -447,10 +447,12 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { .region_scope_tree .yield_in_scope_for_expr(scope, cmt.hir_id, - self.bccx.body) { + self.bccx.body) + { self.bccx.cannot_borrow_across_generator_yield(borrow_span, yield_span, Origin::Ast).emit(); + self.bccx.signal_error(); } } @@ -507,9 +509,13 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { new_loan, old_loan, old_loan, new_loan).err(); match (err_old_new, err_new_old) { - (Some(mut err), None) | (None, Some(mut err)) => err.emit(), + (Some(mut err), None) | (None, Some(mut err)) => { + err.emit(); + self.bccx.signal_error(); + } (Some(mut err_old), Some(mut err_new)) => { err_old.emit(); + self.bccx.signal_error(); err_new.cancel(); } (None, None) => return true, @@ -695,6 +701,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { loan_span, &self.bccx.loan_path_to_string(&loan_path), Origin::Ast) .emit(); + self.bccx.signal_error(); } } } @@ -745,6 +752,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { }; err.emit(); + self.bccx.signal_error(); } } } @@ -914,5 +922,6 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { self.bccx.cannot_assign_to_borrowed( span, loan.span, &self.bccx.loan_path_to_string(loan_path), Origin::Ast) .emit(); + self.bccx.signal_error(); } } diff --git a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs index f221565c7f3..b217e6a8564 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs @@ -68,7 +68,7 @@ pub struct GroupedMoveErrors<'tcx> { move_to_places: Vec<MovePlace<'tcx>> } -fn report_move_errors<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, errors: &Vec<MoveError<'tcx>>) { +fn report_move_errors<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, errors: &[MoveError<'tcx>]) { let grouped_errors = group_errors_with_same_origin(errors); for error in &grouped_errors { let mut err = report_cannot_move_out_of(bccx, error.move_from.clone()); @@ -99,10 +99,11 @@ fn report_move_errors<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, errors: &Vec<Move "captured outer variable"); } err.emit(); + bccx.signal_error(); } } -fn group_errors_with_same_origin<'tcx>(errors: &Vec<MoveError<'tcx>>) +fn group_errors_with_same_origin<'tcx>(errors: &[MoveError<'tcx>]) -> Vec<GroupedMoveErrors<'tcx>> { let mut grouped_errors = Vec::new(); for error in errors { diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 3ae1e5aac50..0cb4a766e80 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -28,7 +28,7 @@ use rustc::middle::dataflow::DataFlowContext; use rustc::middle::dataflow::BitwiseOperator; use rustc::middle::dataflow::DataFlowOperator; use rustc::middle::dataflow::KillFrom; -use rustc::middle::borrowck::BorrowCheckResult; +use rustc::middle::borrowck::{BorrowCheckResult, SignalledError}; use rustc::hir::def_id::{DefId, LocalDefId}; use rustc::middle::expr_use_visitor as euv; use rustc::middle::mem_categorization as mc; @@ -42,7 +42,7 @@ use rustc_mir::util::borrowck_errors::{BorrowckErrors, Origin}; use rustc_mir::util::suggest_ref_mut; use rustc::util::nodemap::FxHashSet; -use std::cell::RefCell; +use std::cell::{Cell, RefCell}; use std::fmt; use std::rc::Rc; use rustc_data_structures::sync::Lrc; @@ -90,7 +90,7 @@ pub struct AnalysisData<'a, 'tcx: 'a> { fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId) -> Lrc<BorrowCheckResult> { - assert!(tcx.use_ast_borrowck()); + assert!(tcx.use_ast_borrowck() || tcx.migrate_borrowck()); debug!("borrowck(body_owner_def_id={:?})", owner_def_id); @@ -105,6 +105,7 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId) // and do not need borrowchecking. return Lrc::new(BorrowCheckResult { used_mut_nodes: FxHashSet(), + signalled_any_error: SignalledError::NoErrorsSeen, }) } _ => { } @@ -121,6 +122,7 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId) owner_def_id, body, used_mut_nodes: RefCell::new(FxHashSet()), + signalled_any_error: Cell::new(SignalledError::NoErrorsSeen), }; // Eventually, borrowck will always read the MIR, but at the @@ -154,6 +156,7 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId) Lrc::new(BorrowCheckResult { used_mut_nodes: bccx.used_mut_nodes.into_inner(), + signalled_any_error: bccx.signalled_any_error.into_inner(), }) } @@ -234,6 +237,7 @@ pub fn build_borrowck_dataflow_data_for_fn<'a, 'tcx>( owner_def_id, body, used_mut_nodes: RefCell::new(FxHashSet()), + signalled_any_error: Cell::new(SignalledError::NoErrorsSeen), }; let dataflow_data = build_borrowck_dataflow_data(&mut bccx, true, body_id, |_| cfg); @@ -257,6 +261,15 @@ pub struct BorrowckCtxt<'a, 'tcx: 'a> { body: &'tcx hir::Body, used_mut_nodes: RefCell<FxHashSet<HirId>>, + + signalled_any_error: Cell<SignalledError>, +} + + +impl<'a, 'tcx: 'a> BorrowckCtxt<'a, 'tcx> { + fn signal_error(&self) { + self.signalled_any_error.set(SignalledError::SawSomeError); + } } impl<'a, 'b, 'tcx: 'b> BorrowckErrors<'a> for &'a BorrowckCtxt<'b, 'tcx> { @@ -645,6 +658,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { .span_label(use_span, format!("use of possibly uninitialized `{}`", self.loan_path_to_string(lp))) .emit(); + self.signal_error(); return; } _ => { @@ -760,6 +774,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { // not considered particularly helpful. err.emit(); + self.signal_error(); } pub fn report_partial_reinitialization_of_uninitialized_structure( @@ -770,6 +785,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { &self.loan_path_to_string(lp), Origin::Ast) .emit(); + self.signal_error(); } pub fn report_reassigned_immutable_variable(&self, @@ -787,6 +803,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { self.loan_path_to_string(lp))); } err.emit(); + self.signal_error(); } pub fn struct_span_err_with_code<S: Into<MultiSpan>>(&self, @@ -908,6 +925,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { self.tcx.hir.hir_to_node_id(err.cmt.hir_id) ); db.emit(); + self.signal_error(); } err_out_of_scope(super_scope, sub_scope, cause) => { let msg = match opt_loan_path(&err.cmt) { @@ -1022,6 +1040,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { } db.emit(); + self.signal_error(); } err_borrowed_pointer_too_short(loan_scope, ptr_scope) => { let descr = self.cmt_to_path_or_string(err.cmt); @@ -1047,6 +1066,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { ""); db.emit(); + self.signal_error(); } } } @@ -1125,6 +1145,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { err.help("closures behind references must be called via `&mut`"); } err.emit(); + self.signal_error(); } /// Given a type, if it is an immutable reference, return a suggestion to make it mutable @@ -1307,6 +1328,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { cmt_path_or_string), suggestion) .emit(); + self.signal_error(); } fn region_end_span(&self, region: ty::Region<'tcx>) -> Option<Span> { diff --git a/src/librustc_borrowck/lib.rs b/src/librustc_borrowck/lib.rs index d583a32c431..a5a20af0e4e 100644 --- a/src/librustc_borrowck/lib.rs +++ b/src/librustc_borrowck/lib.rs @@ -13,7 +13,6 @@ html_root_url = "https://doc.rust-lang.org/nightly/")] #![allow(non_camel_case_types)] -#![deny(bare_trait_objects)] #![feature(from_ref)] #![feature(quote)] diff --git a/src/librustc_codegen_llvm/back/link.rs b/src/librustc_codegen_llvm/back/link.rs index f2b17584adc..13f0c90e885 100644 --- a/src/librustc_codegen_llvm/back/link.rs +++ b/src/librustc_codegen_llvm/back/link.rs @@ -40,6 +40,7 @@ use std::env; use std::fmt; use std::fs; use std::io; +use std::iter; use std::path::{Path, PathBuf}; use std::process::{Output, Stdio}; use std::str; @@ -885,9 +886,9 @@ fn exec_linker(sess: &Session, cmd: &mut Command, out_filename: &Path, tmpdir: & } let file = tmpdir.join("linker-arguments"); let bytes = if sess.target.target.options.is_like_msvc { - let mut out = vec![]; + let mut out = Vec::with_capacity((1 + args.len()) * 2); // start the stream with a UTF-16 BOM - for c in vec![0xFEFF].into_iter().chain(args.encode_utf16()) { + for c in iter::once(0xFEFF).chain(args.encode_utf16()) { // encode in little endian out.push(c as u8); out.push((c >> 8) as u8); diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 8aa7902021f..90f96c9687b 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -23,7 +23,6 @@ #![feature(custom_attribute)] #![feature(fs_read_write)] #![allow(unused_attributes)] -#![deny(bare_trait_objects)] #![feature(libc)] #![feature(quote)] #![feature(range_contains)] diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs index e9031007a4e..f59cf5832fc 100644 --- a/src/librustc_codegen_utils/lib.rs +++ b/src/librustc_codegen_utils/lib.rs @@ -20,7 +20,6 @@ #![feature(box_syntax)] #![feature(custom_attribute)] #![allow(unused_attributes)] -#![deny(bare_trait_objects)] #![feature(quote)] #![feature(rustc_diagnostic_macros)] diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index ef0d57c7b7c..a9e582e510e 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -16,8 +16,6 @@ //! //! This API is completely unstable and subject to change. -#![deny(bare_trait_objects)] - #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://www.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 91392ab013d..24a2354775c 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -798,7 +798,7 @@ where pub fn phase_2_configure_and_expand_inner<'a, F>( sess: &'a Session, cstore: &'a CStore, - krate: ast::Crate, + mut krate: ast::Crate, registry: Option<Registry>, crate_name: &str, addl_plugins: Option<Vec<String>>, @@ -810,6 +810,10 @@ pub fn phase_2_configure_and_expand_inner<'a, F>( where F: FnOnce(&ast::Crate) -> CompileResult, { + krate = time(sess, "attributes injection", || { + syntax::attr::inject(krate, &sess.parse_sess, &sess.opts.debugging_opts.crate_attr) + }); + let (mut krate, features) = syntax::config::features( krate, &sess.parse_sess, @@ -1395,7 +1399,7 @@ fn generated_output_paths( // Runs `f` on every output file path and returns the first non-None result, or None if `f` // returns None for every file path. -fn check_output<F, T>(output_paths: &Vec<PathBuf>, f: F) -> Option<T> +fn check_output<F, T>(output_paths: &[PathBuf], f: F) -> Option<T> where F: Fn(&PathBuf) -> Option<T>, { @@ -1407,7 +1411,7 @@ where None } -pub fn output_contains_path(output_paths: &Vec<PathBuf>, input_path: &PathBuf) -> bool { +pub fn output_contains_path(output_paths: &[PathBuf], input_path: &PathBuf) -> bool { let input_path = input_path.canonicalize().ok(); if input_path.is_none() { return false; @@ -1422,7 +1426,7 @@ pub fn output_contains_path(output_paths: &Vec<PathBuf>, input_path: &PathBuf) - check_output(output_paths, check).is_some() } -pub fn output_conflicts_with_dir(output_paths: &Vec<PathBuf>) -> Option<PathBuf> { +pub fn output_conflicts_with_dir(output_paths: &[PathBuf]) -> Option<PathBuf> { let check = |output_path: &PathBuf| { if output_path.is_dir() { Some(output_path.clone()) @@ -1433,7 +1437,7 @@ pub fn output_conflicts_with_dir(output_paths: &Vec<PathBuf>) -> Option<PathBuf> check_output(output_paths, check) } -fn write_out_deps(sess: &Session, outputs: &OutputFilenames, out_filenames: &Vec<PathBuf>) { +fn write_out_deps(sess: &Session, outputs: &OutputFilenames, out_filenames: &[PathBuf]) { // Write out dependency rules to the dep-info file if requested if !sess.opts.output_types.contains_key(&OutputType::DepInfo) { return; diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 3ec73059721..29b9990de34 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -14,8 +14,6 @@ //! //! This API is completely unstable and subject to change. -#![deny(bare_trait_objects)] - #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] diff --git a/src/librustc_driver/profile/mod.rs b/src/librustc_driver/profile/mod.rs index a362556717b..2ec85e1c27f 100644 --- a/src/librustc_driver/profile/mod.rs +++ b/src/librustc_driver/profile/mod.rs @@ -62,7 +62,7 @@ struct StackFrame { pub traces: Vec<trace::Rec>, } -fn total_duration(traces: &Vec<trace::Rec>) -> Duration { +fn total_duration(traces: &[trace::Rec]) -> Duration { let mut sum : Duration = Duration::new(0,0); for t in traces.iter() { sum += t.dur_total; } return sum diff --git a/src/librustc_driver/profile/trace.rs b/src/librustc_driver/profile/trace.rs index 970a860fdff..797ed4505b4 100644 --- a/src/librustc_driver/profile/trace.rs +++ b/src/librustc_driver/profile/trace.rs @@ -107,7 +107,7 @@ fn html_of_fraction(frac: f64) -> (String, String) { else { (format!("< 0.1%", ), css) } } -fn total_duration(traces: &Vec<Rec>) -> Duration { +fn total_duration(traces: &[Rec]) -> Duration { let mut sum : Duration = Duration::new(0,0); for t in traces.iter() { sum += t.dur_total; @@ -123,7 +123,7 @@ fn duration_div(nom: Duration, den: Duration) -> f64 { to_nanos(nom) as f64 / to_nanos(den) as f64 } -fn write_traces_rec(file: &mut File, traces: &Vec<Rec>, total: Duration, depth: usize) { +fn write_traces_rec(file: &mut File, traces: &[Rec], total: Duration, depth: usize) { for t in traces { let (eff_text, eff_css_classes) = html_of_effect(&t.effect); let (dur_text, dur_css_classes) = html_of_duration(&t.start, &t.dur_total); @@ -149,7 +149,7 @@ fn write_traces_rec(file: &mut File, traces: &Vec<Rec>, total: Duration, depth: } } -fn compute_counts_rec(counts: &mut HashMap<String,QueryMetric>, traces: &Vec<Rec>) { +fn compute_counts_rec(counts: &mut HashMap<String,QueryMetric>, traces: &[Rec]) { for t in traces.iter() { match t.effect { Effect::TimeBegin(ref msg) => { @@ -218,7 +218,7 @@ pub fn write_counts(count_file: &mut File, counts: &mut HashMap<String,QueryMetr } } -pub fn write_traces(html_file: &mut File, counts_file: &mut File, traces: &Vec<Rec>) { +pub fn write_traces(html_file: &mut File, counts_file: &mut File, traces: &[Rec]) { let capacity = traces.iter().fold(0, |acc, t| acc + 1 + t.extent.len()); let mut counts : HashMap<String, QueryMetric> = HashMap::with_capacity(capacity); compute_counts_rec(&mut counts, traces); diff --git a/src/librustc_errors/diagnostic.rs b/src/librustc_errors/diagnostic.rs index b1578b697bb..825e31539c8 100644 --- a/src/librustc_errors/diagnostic.rs +++ b/src/librustc_errors/diagnostic.rs @@ -99,6 +99,25 @@ impl Diagnostic { } } + pub fn is_error(&self) -> bool { + match self.level { + Level::Bug | + Level::Fatal | + Level::PhaseFatal | + Level::Error | + Level::FailureNote => { + true + } + + Level::Warning | + Level::Note | + Level::Help | + Level::Cancelled => { + false + } + } + } + /// Cancel the diagnostic (a structured diagnostic must either be emitted or /// canceled or it will panic when dropped). pub fn cancel(&mut self) { diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs index 8f99ad87cb8..a0f3abda077 100644 --- a/src/librustc_errors/diagnostic_builder.rs +++ b/src/librustc_errors/diagnostic_builder.rs @@ -100,25 +100,6 @@ impl<'a> DiagnosticBuilder<'a> { buffered_diagnostics.push(diagnostic); } - pub fn is_error(&self) -> bool { - match self.level { - Level::Bug | - Level::Fatal | - Level::PhaseFatal | - Level::Error | - Level::FailureNote => { - true - } - - Level::Warning | - Level::Note | - Level::Help | - Level::Cancelled => { - false - } - } - } - /// Convenience function for internal use, clients should use one of the /// span_* methods instead. pub fn sub<S: Into<MultiSpan>>( diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index e0ed89a6416..09295e2c7ff 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -747,7 +747,7 @@ impl EmitterWriter { max } - fn get_max_line_num(&mut self, span: &MultiSpan, children: &Vec<SubDiagnostic>) -> usize { + fn get_max_line_num(&mut self, span: &MultiSpan, children: &[SubDiagnostic]) -> usize { let mut max = 0; let primary = self.get_multispan_max_line_num(span); @@ -950,7 +950,7 @@ impl EmitterWriter { fn emit_message_default(&mut self, msp: &MultiSpan, - msg: &Vec<(String, Style)>, + msg: &[(String, Style)], code: &Option<DiagnosticId>, level: &Level, max_line_num_len: usize, @@ -1313,10 +1313,10 @@ impl EmitterWriter { fn emit_messages_default(&mut self, level: &Level, - message: &Vec<(String, Style)>, + message: &[(String, Style)], code: &Option<DiagnosticId>, span: &MultiSpan, - children: &Vec<SubDiagnostic>, + children: &[SubDiagnostic], suggestions: &[CodeSuggestion]) { let max_line_num_len = if self.ui_testing { ANONYMIZED_LINE_NUM.len() @@ -1429,7 +1429,7 @@ fn overlaps(a1: &Annotation, a2: &Annotation, padding: usize) -> bool { num_overlap(a1.start_col, a1.end_col + padding, a2.start_col, a2.end_col, false) } -fn emit_to_destination(rendered_buffer: &Vec<Vec<StyledString>>, +fn emit_to_destination(rendered_buffer: &[Vec<StyledString>], lvl: &Level, dst: &mut Destination, short_message: bool) diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 400e5829d33..82546747755 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![deny(bare_trait_objects)] - #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] diff --git a/src/librustc_incremental/lib.rs b/src/librustc_incremental/lib.rs index 2ef88041d33..3839c133a6e 100644 --- a/src/librustc_incremental/lib.rs +++ b/src/librustc_incremental/lib.rs @@ -10,8 +10,6 @@ //! Support for serializing the dep-graph and reloading it. -#![deny(bare_trait_objects)] - #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 798c289ac2f..78a8c494f48 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -19,8 +19,6 @@ //! //! This API is completely unstable and subject to change. -#![deny(bare_trait_objects)] - #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index c60016cde0d..741758cb954 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -12,7 +12,6 @@ #![allow(non_camel_case_types)] #![allow(non_snake_case)] #![allow(dead_code)] -#![deny(bare_trait_objects)] #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", diff --git a/src/librustc_lsan/lib.rs b/src/librustc_lsan/lib.rs index 7bd1e98f85d..0c78fd74a23 100644 --- a/src/librustc_lsan/lib.rs +++ b/src/librustc_lsan/lib.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![deny(bare_trait_objects)] - #![sanitizer_runtime] #![feature(alloc_system)] #![feature(sanitizer_runtime)] diff --git a/src/librustc_metadata/dynamic_lib.rs b/src/librustc_metadata/dynamic_lib.rs index d7da0d00012..182a071277e 100644 --- a/src/librustc_metadata/dynamic_lib.rs +++ b/src/librustc_metadata/dynamic_lib.rs @@ -90,30 +90,29 @@ mod tests { use std::mem; #[test] - fn test_loading_cosine() { + fn test_loading_atoi() { if cfg!(windows) { return } - // The math library does not need to be loaded since it is already - // statically linked in - let libm = match DynamicLibrary::open(None) { + // The C library does not need to be loaded since it is already linked in + let lib = match DynamicLibrary::open(None) { Err(error) => panic!("Could not load self as module: {}", error), - Ok(libm) => libm + Ok(lib) => lib }; - let cosine: extern fn(libc::c_double) -> libc::c_double = unsafe { - match libm.symbol("cos") { - Err(error) => panic!("Could not load function cos: {}", error), - Ok(cosine) => mem::transmute::<*mut u8, _>(cosine) + let atoi: extern fn(*const libc::c_char) -> libc::c_int = unsafe { + match lib.symbol("atoi") { + Err(error) => panic!("Could not load function atoi: {}", error), + Ok(atoi) => mem::transmute::<*mut u8, _>(atoi) } }; - let argument = 0.0; - let expected_result = 1.0; - let result = cosine(argument); + let argument = CString::new("1383428980").unwrap(); + let expected_result = 0x52757374; + let result = atoi(argument.as_ptr()); if result != expected_result { - panic!("cos({}) != {} but equaled {} instead", argument, + panic!("atoi({:?}) != {} but equaled {} instead", argument, expected_result, result) } } diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index d535c1ef903..5cba0387d17 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![deny(bare_trait_objects)] - #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] diff --git a/src/librustc_mir/borrow_check/borrow_set.rs b/src/librustc_mir/borrow_check/borrow_set.rs index e9e0c5c3613..347bf61480e 100644 --- a/src/librustc_mir/borrow_check/borrow_set.rs +++ b/src/librustc_mir/borrow_check/borrow_set.rs @@ -333,14 +333,21 @@ impl<'a, 'gcx, 'tcx> GatherBorrows<'a, 'gcx, 'tcx> { // Consider the borrow not activated to start. When we find an activation, we'll update // this field. - let borrow_data = &mut self.idx_vec[borrow_index]; - borrow_data.activation_location = TwoPhaseActivation::NotActivated; + { + let borrow_data = &mut self.idx_vec[borrow_index]; + borrow_data.activation_location = TwoPhaseActivation::NotActivated; + } // Insert `temp` into the list of pending activations. From // now on, we'll be on the lookout for a use of it. Note that // we are guaranteed that this use will come after the // assignment. let old_value = self.pending_activations.insert(temp, borrow_index); - assert!(old_value.is_none()); + if let Some(old_index) = old_value { + span_bug!(self.mir.source_info(start_location).span, + "found already pending activation for temp: {:?} \ + at borrow_index: {:?} with associated data {:?}", + temp, old_index, self.idx_vec[old_index]); + } } } diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 84e3ecd5096..4ba96f643b0 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -16,6 +16,7 @@ use rustc::hir::def_id::DefId; use rustc::hir::map::definitions::DefPathData; use rustc::infer::InferCtxt; use rustc::lint::builtin::UNUSED_MUT; +use rustc::middle::borrowck::SignalledError; use rustc::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind}; use rustc::mir::{ClearCrossCrate, Local, Location, Mir, Mutability, Operand, Place}; use rustc::mir::{Field, Projection, ProjectionElem, Rvalue, Statement, StatementKind}; @@ -23,7 +24,7 @@ use rustc::mir::{Terminator, TerminatorKind}; use rustc::ty::query::Providers; use rustc::ty::{self, ParamEnv, TyCtxt}; -use rustc_errors::{Diagnostic, DiagnosticBuilder}; +use rustc_errors::{Diagnostic, DiagnosticBuilder, Level}; use rustc_data_structures::graph::dominators::Dominators; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::indexed_set::IdxSetBuf; @@ -329,8 +330,34 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>( } } - for diag in mbcx.errors_buffer.drain(..) { - DiagnosticBuilder::new_diagnostic(mbcx.tcx.sess.diagnostic(), diag).emit(); + if mbcx.errors_buffer.len() > 0 { + if tcx.migrate_borrowck() { + match tcx.borrowck(def_id).signalled_any_error { + SignalledError::NoErrorsSeen => { + // if AST-borrowck signalled no errors, then + // downgrade all the buffered MIR-borrowck errors + // to warnings. + for err in &mut mbcx.errors_buffer { + if err.is_error() { + err.level = Level::Warning; + err.warn("This error has been downgraded to a warning \ + for backwards compatibility with previous releases.\n\ + It represents potential unsoundness in your code.\n\ + This warning will become a hard error in the future."); + } + } + } + SignalledError::SawSomeError => { + // if AST-borrowck signalled a (cancelled) error, + // then we will just emit the buffered + // MIR-borrowck errors as normal. + } + } + } + + for diag in mbcx.errors_buffer.drain(..) { + DiagnosticBuilder::new_diagnostic(mbcx.tcx.sess.diagnostic(), diag).emit(); + } } let result = BorrowCheckResult { @@ -1747,20 +1774,44 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { } } - Reservation(WriteKind::Move) - | Write(WriteKind::Move) - | Reservation(WriteKind::StorageDeadOrDrop) - | Reservation(WriteKind::MutableBorrow(BorrowKind::Shared)) - | Write(WriteKind::StorageDeadOrDrop) - | Write(WriteKind::MutableBorrow(BorrowKind::Shared)) => { + Reservation(wk @ WriteKind::Move) + | Write(wk @ WriteKind::Move) + | Reservation(wk @ WriteKind::StorageDeadOrDrop) + | Reservation(wk @ WriteKind::MutableBorrow(BorrowKind::Shared)) + | Write(wk @ WriteKind::StorageDeadOrDrop) + | Write(wk @ WriteKind::MutableBorrow(BorrowKind::Shared)) => { if let Err(_place_err) = self.is_mutable(place, is_local_mutation_allowed) { - self.tcx.sess.delay_span_bug( - span, - &format!( - "Accessing `{:?}` with the kind `{:?}` shouldn't be possible", - place, kind - ), - ); + if self.tcx.migrate_borrowck() { + // rust-lang/rust#46908: In pure NLL mode this + // code path should be unreachable (and thus + // we signal an ICE in the else branch + // here). But we can legitimately get here + // under borrowck=migrate mode, so instead of + // ICE'ing we instead report a legitimate + // error (which will then be downgraded to a + // warning by the migrate machinery). + error_access = match wk { + WriteKind::MutableBorrow(_) => AccessKind::MutableBorrow, + WriteKind::Move => AccessKind::Move, + WriteKind::StorageDeadOrDrop | + WriteKind::Mutate => AccessKind::Mutate, + }; + self.report_mutability_error( + place, + span, + _place_err, + error_access, + location, + ); + } else { + self.tcx.sess.delay_span_bug( + span, + &format!( + "Accessing `{:?}` with the kind `{:?}` shouldn't be possible", + place, kind + ), + ); + } } return false; } diff --git a/src/librustc_mir/borrow_check/move_errors.rs b/src/librustc_mir/borrow_check/move_errors.rs index 4aa38fb5f37..215ade5bd4d 100644 --- a/src/librustc_mir/borrow_check/move_errors.rs +++ b/src/librustc_mir/borrow_check/move_errors.rs @@ -87,6 +87,10 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> { cannot_move_out_of: IllegalMoveOrigin { location, kind }, } => { let stmt_source_info = self.mir.source_info(location); + // Note: that the only time we assign a place isn't a temporary + // to a user variable is when initializing it. + // If that ever stops being the case, then the ever initialized + // flow could be used. if let Some(StatementKind::Assign( Place::Local(local), Rvalue::Use(Operand::Move(move_from)), @@ -109,26 +113,16 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> { opt_ty_info: _, }))) = local_decl.is_user_variable { - // HACK use scopes to determine if this assignment is - // the initialization of a variable. - // FIXME(matthewjasper) This would probably be more - // reliable if it used the ever initialized dataflow - // but move errors are currently reported before the - // rest of borrowck has run. - if self - .mir - .is_sub_scope(local_decl.source_info.scope, stmt_source_info.scope) - { - self.append_binding_error( - grouped_errors, - kind, - move_from, - *local, - opt_match_place, - match_span, - ); - return; - } + self.append_binding_error( + grouped_errors, + kind, + move_from, + *local, + opt_match_place, + match_span, + stmt_source_info.span, + ); + return; } } grouped_errors.push(GroupedMoveError::OtherIllegalMove { @@ -147,6 +141,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> { bind_to: Local, match_place: &Option<Place<'tcx>>, match_span: Span, + statement_span: Span, ) { debug!( "append_to_grouped_errors(match_place={:?}, match_span={:?})", @@ -173,13 +168,13 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> { debug!("found a new move error location"); // Don't need to point to x in let x = ... . - let binds_to = if from_simple_let { - vec![] + let (binds_to, span) = if from_simple_let { + (vec![], statement_span) } else { - vec![bind_to] + (vec![bind_to], match_span) }; grouped_errors.push(GroupedMoveError::MovesFromMatchPlace { - span: match_span, + span, move_from: match_place.clone(), kind, binds_to, diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs index ab1ff1fa347..571a1188d49 100644 --- a/src/librustc_mir/borrow_check/mutability_errors.rs +++ b/src/librustc_mir/borrow_check/mutability_errors.rs @@ -24,6 +24,7 @@ use util::suggest_ref_mut; pub(super) enum AccessKind { MutableBorrow, Mutate, + Move, } impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> { @@ -110,6 +111,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> { if let Some(desc) = access_place_desc { item_msg = format!("`{}`", desc); reason = match error_access { + AccessKind::Move | AccessKind::Mutate => format!(" which is behind a {}", pointer_type), AccessKind::MutableBorrow => { format!(", as it is behind a {}", pointer_type) @@ -160,6 +162,13 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> { let span = match error_access { + AccessKind::Move => { + err = self.tcx + .cannot_move_out_of(span, &(item_msg + &reason), Origin::Mir); + act = "move"; + acted_on = "moved"; + span + } AccessKind::Mutate => { err = self.tcx .cannot_assign(span, &(item_msg + &reason), Origin::Mir); diff --git a/src/librustc_mir/borrow_check/nll/facts.rs b/src/librustc_mir/borrow_check/nll/facts.rs index 2523711f936..8eb052f88e1 100644 --- a/src/librustc_mir/borrow_check/nll/facts.rs +++ b/src/librustc_mir/borrow_check/nll/facts.rs @@ -120,7 +120,7 @@ struct FactWriter<'w> { impl<'w> FactWriter<'w> { fn write_facts_to_path<T>( &self, - rows: &Vec<T>, + rows: &[T], file_name: &str, ) -> Result<(), Box<dyn Error>> where diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs index 1b540ef74be..c2c5c6771b0 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs @@ -31,9 +31,7 @@ mod var_name; enum ConstraintCategory { Cast, Assignment, - AssignmentToUpvar, Return, - CallArgumentToUpvar, CallArgument, Other, Boring, @@ -41,16 +39,13 @@ enum ConstraintCategory { impl fmt::Display for ConstraintCategory { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // Must end with a space. Allows for empty names to be provided. match self { - ConstraintCategory::Assignment | ConstraintCategory::AssignmentToUpvar => { - write!(f, "assignment") - } - ConstraintCategory::Return => write!(f, "return"), - ConstraintCategory::Cast => write!(f, "cast"), - ConstraintCategory::CallArgument | ConstraintCategory::CallArgumentToUpvar => { - write!(f, "argument") - } - _ => write!(f, "free region"), + ConstraintCategory::Assignment => write!(f, "assignment "), + ConstraintCategory::Return => write!(f, "return "), + ConstraintCategory::Cast => write!(f, "cast "), + ConstraintCategory::CallArgument => write!(f, "argument "), + _ => write!(f, ""), } } } @@ -224,10 +219,10 @@ impl<'tcx> RegionInferenceContext<'tcx> { "constraint_is_interesting: locations={:?} constraint={:?}", constraint.locations, constraint ); - if let Locations::Interesting(_) = constraint.locations { - true - } else { - false + + match constraint.locations { + Locations::Interesting(_) | Locations::All => true, + _ => false, } } @@ -320,45 +315,26 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } - let category = match ( - category, + let (fr_is_local, outlived_fr_is_local): (bool, bool) = ( self.universal_regions.is_local_free_region(fr), self.universal_regions.is_local_free_region(outlived_fr), - ) { - (ConstraintCategory::Assignment, true, false) => ConstraintCategory::AssignmentToUpvar, - (ConstraintCategory::CallArgument, true, false) => { - ConstraintCategory::CallArgumentToUpvar - } - (category, _, _) => category, + ); + debug!("report_error: fr_is_local={:?} outlived_fr_is_local={:?} category={:?}", + fr_is_local, outlived_fr_is_local, category); + + match (category, fr_is_local, outlived_fr_is_local) { + (ConstraintCategory::Assignment, true, false) | + (ConstraintCategory::CallArgument, true, false) => + self.report_escaping_data_error(mir, infcx, mir_def_id, fr, outlived_fr, + category, span, errors_buffer), + _ => + self.report_general_error(mir, infcx, mir_def_id, fr, fr_is_local, + outlived_fr, outlived_fr_is_local, + category, span, errors_buffer), }; - - debug!("report_error: category={:?}", category); - match category { - ConstraintCategory::AssignmentToUpvar | ConstraintCategory::CallArgumentToUpvar => self - .report_closure_error( - mir, - infcx, - mir_def_id, - fr, - outlived_fr, - category, - span, - errors_buffer, - ), - _ => self.report_general_error( - mir, - infcx, - mir_def_id, - fr, - outlived_fr, - category, - span, - errors_buffer, - ), - } } - fn report_closure_error( + fn report_escaping_data_error( &self, mir: &Mir<'tcx>, infcx: &InferCtxt<'_, '_, 'tcx>, @@ -373,29 +349,23 @@ impl<'tcx> RegionInferenceContext<'tcx> { let outlived_fr_name_and_span = self.get_var_name_and_span_for_region(infcx.tcx, mir, outlived_fr); + let escapes_from = if infcx.tcx.is_closure(mir_def_id) { "closure" } else { "function" }; + if fr_name_and_span.is_none() && outlived_fr_name_and_span.is_none() { - return self.report_general_error( - mir, - infcx, - mir_def_id, - fr, - outlived_fr, - category, - span, - errors_buffer, - ); + return self.report_general_error(mir, infcx, mir_def_id, + fr, true, outlived_fr, false, + category, span, errors_buffer); } - let mut diag = infcx - .tcx - .sess - .struct_span_err(span, &format!("borrowed data escapes outside of closure")); + let mut diag = infcx.tcx.sess.struct_span_err( + span, &format!("borrowed data escapes outside of {}", escapes_from), + ); if let Some((outlived_fr_name, outlived_fr_span)) = outlived_fr_name_and_span { if let Some(name) = outlived_fr_name { diag.span_label( outlived_fr_span, - format!("`{}` is declared here, outside of the closure body", name), + format!("`{}` is declared here, outside of the {} body", name, escapes_from), ); } } @@ -404,13 +374,12 @@ impl<'tcx> RegionInferenceContext<'tcx> { if let Some(name) = fr_name { diag.span_label( fr_span, - format!( - "`{}` is a reference that is only valid in the closure body", - name - ), + format!("`{}` is a reference that is only valid in the {} body", + name, escapes_from), ); - diag.span_label(span, format!("`{}` escapes the closure body here", name)); + diag.span_label(span, format!("`{}` escapes the {} body here", + name, escapes_from)); } } @@ -423,7 +392,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { infcx: &InferCtxt<'_, '_, 'tcx>, mir_def_id: DefId, fr: RegionVid, + fr_is_local: bool, outlived_fr: RegionVid, + outlived_fr_is_local: bool, category: ConstraintCategory, span: Span, errors_buffer: &mut Vec<Diagnostic>, @@ -434,17 +405,28 @@ impl<'tcx> RegionInferenceContext<'tcx> { ); let counter = &mut 1; - let fr_name = self.give_region_a_name(infcx.tcx, mir, mir_def_id, fr, counter, &mut diag); - let outlived_fr_name = - self.give_region_a_name(infcx.tcx, mir, mir_def_id, outlived_fr, counter, &mut diag); - - diag.span_label( - span, - format!( - "{} requires that `{}` must outlive `{}`", - category, fr_name, outlived_fr_name, - ), - ); + let fr_name = self.give_region_a_name( + infcx, mir, mir_def_id, fr, counter, &mut diag); + let outlived_fr_name = self.give_region_a_name( + infcx, mir, mir_def_id, outlived_fr, counter, &mut diag); + + let mir_def_name = if infcx.tcx.is_closure(mir_def_id) { "closure" } else { "function" }; + + match (category, outlived_fr_is_local, fr_is_local) { + (ConstraintCategory::Return, true, _) => { + diag.span_label(span, format!( + "{} was supposed to return data with lifetime `{}` but it is returning \ + data with lifetime `{}`", + mir_def_name, fr_name, outlived_fr_name, + )); + }, + _ => { + diag.span_label(span, format!( + "{}requires that `{}` must outlive `{}`", + category, fr_name, outlived_fr_name, + )); + }, + } diag.buffer(errors_buffer); } diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs index c0eca026331..8505d8e1ef3 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs @@ -12,9 +12,11 @@ use borrow_check::nll::region_infer::RegionInferenceContext; use borrow_check::nll::ToRegionVid; use rustc::hir; use rustc::hir::def_id::DefId; +use rustc::infer::InferCtxt; use rustc::mir::Mir; use rustc::ty::subst::{Substs, UnpackedKind}; use rustc::ty::{self, RegionVid, Ty, TyCtxt}; +use rustc::util::ppaux::with_highlight_region; use rustc_errors::DiagnosticBuilder; use syntax::ast::Name; use syntax::symbol::keywords; @@ -48,7 +50,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// and then return the name `'1` for us to use. crate fn give_region_a_name( &self, - tcx: TyCtxt<'_, '_, 'tcx>, + infcx: &InferCtxt<'_, '_, 'tcx>, mir: &Mir<'tcx>, mir_def_id: DefId, fr: RegionVid, @@ -59,17 +61,18 @@ impl<'tcx> RegionInferenceContext<'tcx> { assert!(self.universal_regions.is_universal_region(fr)); - self.give_name_from_error_region(tcx, mir_def_id, fr, counter, diag) + self.give_name_from_error_region(infcx.tcx, mir_def_id, fr, counter, diag) .or_else(|| { self.give_name_if_anonymous_region_appears_in_arguments( - tcx, mir, mir_def_id, fr, counter, diag) + infcx, mir, mir_def_id, fr, counter, diag) }) .or_else(|| { self.give_name_if_anonymous_region_appears_in_upvars( - tcx, mir, fr, counter, diag) + infcx.tcx, mir, fr, counter, diag) }) .or_else(|| { - self.give_name_if_anonymous_region_appears_in_output(tcx, mir, fr, counter, diag) + self.give_name_if_anonymous_region_appears_in_output( + infcx.tcx, mir, fr, counter, diag) }) .unwrap_or_else(|| span_bug!(mir.span, "can't make a name for free region {:?}", fr)) } @@ -130,7 +133,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// ``` fn give_name_if_anonymous_region_appears_in_arguments( &self, - tcx: TyCtxt<'_, '_, 'tcx>, + infcx: &InferCtxt<'_, '_, 'tcx>, mir: &Mir<'tcx>, mir_def_id: DefId, fr: RegionVid, @@ -138,12 +141,13 @@ impl<'tcx> RegionInferenceContext<'tcx> { diag: &mut DiagnosticBuilder<'_>, ) -> Option<InternedString> { let implicit_inputs = self.universal_regions.defining_ty.implicit_inputs(); - let argument_index = self.get_argument_index_for_region(tcx, fr)?; + let argument_index = self.get_argument_index_for_region(infcx.tcx, fr)?; let arg_ty = self.universal_regions.unnormalized_input_tys[implicit_inputs + argument_index]; if let Some(region_name) = self.give_name_if_we_can_match_hir_ty_from_argument( - tcx, + infcx, + mir, mir_def_id, fr, arg_ty, @@ -169,7 +173,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { fn give_name_if_we_can_match_hir_ty_from_argument( &self, - tcx: TyCtxt<'_, '_, 'tcx>, + infcx: &InferCtxt<'_, '_, 'tcx>, + mir: &Mir<'tcx>, mir_def_id: DefId, needle_fr: RegionVid, argument_ty: Ty<'tcx>, @@ -177,17 +182,24 @@ impl<'tcx> RegionInferenceContext<'tcx> { counter: &mut usize, diag: &mut DiagnosticBuilder<'_>, ) -> Option<InternedString> { - let mir_node_id = tcx.hir.as_local_node_id(mir_def_id)?; - let fn_decl = tcx.hir.fn_decl(mir_node_id)?; + let mir_node_id = infcx.tcx.hir.as_local_node_id(mir_def_id)?; + let fn_decl = infcx.tcx.hir.fn_decl(mir_node_id)?; let argument_hir_ty: &hir::Ty = &fn_decl.inputs[argument_index]; match argument_hir_ty.node { // This indicates a variable with no type annotation, like // `|x|`... in that case, we can't highlight the type but // must highlight the variable. - hir::TyKind::Infer => None, + hir::TyKind::Infer => self.give_name_if_we_cannot_match_hir_ty( + infcx, + mir, + needle_fr, + argument_ty, + counter, + diag, + ), _ => self.give_name_if_we_can_match_hir_ty( - tcx, + infcx.tcx, needle_fr, argument_ty, argument_hir_ty, @@ -197,6 +209,49 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } + /// Attempts to highlight the specific part of a type in an argument + /// that has no type annotation. + /// For example, we might produce an annotation like this: + /// + /// ``` + /// | foo(|a, b| b) + /// | - - + /// | | | + /// | | has type `&'1 u32` + /// | has type `&'2 u32` + /// ``` + fn give_name_if_we_cannot_match_hir_ty( + &self, + infcx: &InferCtxt<'_, '_, 'tcx>, + mir: &Mir<'tcx>, + needle_fr: RegionVid, + argument_ty: Ty<'tcx>, + counter: &mut usize, + diag: &mut DiagnosticBuilder<'_>, + ) -> Option<InternedString> { + let type_name = with_highlight_region(needle_fr, *counter, || { + infcx.extract_type_name(&argument_ty) + }); + + debug!("give_name_if_we_cannot_match_hir_ty: type_name={:?} needle_fr={:?}", + type_name, needle_fr); + let assigned_region_name = if type_name.find(&format!("'{}", counter)).is_some() { + // Only add a label if we can confirm that a region was labelled. + let argument_index = self.get_argument_index_for_region(infcx.tcx, needle_fr)?; + let (_, span) = self.get_argument_name_and_span_for_region(mir, argument_index); + diag.span_label(span, format!("has type `{}`", type_name)); + + // This counter value will already have been used, so this function will increment it + // so the next value will be used next and return the region name that would have been + // used. + Some(self.synthesize_region_name(counter)) + } else { + None + }; + + assigned_region_name + } + /// Attempts to highlight the specific part of a type annotation /// that contains the anonymous reference we want to give a name /// to. For example, we might produce an annotation like this: diff --git a/src/librustc_mir/build/block.rs b/src/librustc_mir/build/block.rs index bbbe757e96e..c3637a5abeb 100644 --- a/src/librustc_mir/build/block.rs +++ b/src/librustc_mir/build/block.rs @@ -16,6 +16,8 @@ use rustc::mir::*; use rustc::hir; use syntax_pos::Span; +use std::slice; + impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { pub fn ast_block(&mut self, destination: &Place<'tcx>, @@ -126,7 +128,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { None, remainder_span, lint_level, - &pattern, + slice::from_ref(&pattern), ArmHasGuard(false), Some((None, initializer_span)), ); @@ -138,8 +140,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { }) })); } else { - scope = this.declare_bindings(None, remainder_span, lint_level, &pattern, - ArmHasGuard(false), None); + scope = this.declare_bindings( + None, remainder_span, lint_level, slice::from_ref(&pattern), + ArmHasGuard(false), None); // FIXME(#47184): We currently only insert `UserAssertTy` statements for // patterns that are bindings, this is as we do not want to deconstruct diff --git a/src/librustc_mir/build/expr/as_place.rs b/src/librustc_mir/build/expr/as_place.rs index 964841e7a9e..a38ca7ae5bf 100644 --- a/src/librustc_mir/build/expr/as_place.rs +++ b/src/librustc_mir/build/expr/as_place.rs @@ -11,7 +11,7 @@ //! See docs in build/expr/mod.rs use build::{BlockAnd, BlockAndExtension, Builder}; -use build::ForGuard::{OutsideGuard, RefWithinGuard, ValWithinGuard}; +use build::ForGuard::{OutsideGuard, RefWithinGuard}; use build::expr::category::Category; use hair::*; use rustc::mir::*; @@ -87,14 +87,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { block.and(Place::Local(Local::new(1))) } ExprKind::VarRef { id } => { - let place = if this.is_bound_var_in_guard(id) { - if this.hir.tcx().all_pat_vars_are_implicit_refs_within_guards() { - let index = this.var_local_id(id, RefWithinGuard); - Place::Local(index).deref() - } else { - let index = this.var_local_id(id, ValWithinGuard); - Place::Local(index) - } + let place = if this.is_bound_var_in_guard(id) && + this.hir.tcx().all_pat_vars_are_implicit_refs_within_guards() + { + let index = this.var_local_id(id, RefWithinGuard); + Place::Local(index).deref() } else { let index = this.var_local_id(id, OutsideGuard); Place::Local(index) diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index 5de316a6640..a509ec08a14 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -63,13 +63,13 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // injects a borrow of the matched input, which should have the same effect // as eddyb's hack. Once NLL is the default, we can remove the hack. - let dummy_source_info = self.source_info(span); + let dummy_source_info = self.source_info(discriminant_span); let dummy_access = Rvalue::Discriminant(discriminant_place.clone()); let dummy_ty = dummy_access.ty(&self.local_decls, tcx); let dummy_temp = self.temp(dummy_ty, dummy_source_info.span); self.cfg.push_assign(block, dummy_source_info, &dummy_temp, dummy_access); - let source_info = self.source_info(span); + let source_info = self.source_info(discriminant_span); let borrowed_input_temp = if tcx.generate_borrow_of_any_match_input() { // The region is unknown at this point; we rely on NLL // inference to find an appropriate one. Therefore you can @@ -97,7 +97,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let body = self.hir.mirror(arm.body.clone()); let scope = self.declare_bindings(None, body.span, LintLevel::Inherited, - &arm.patterns[0], + &arm.patterns[..], ArmHasGuard(arm.guard.is_some()), Some((Some(&discriminant_place), discriminant_span))); (body, scope.unwrap_or(self.source_scope)) @@ -118,11 +118,13 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { arms.iter() .enumerate() .flat_map(|(arm_index, arm)| { - arm.patterns.iter() - .map(move |pat| (arm_index, pat, arm.guard.clone())) + arm.patterns.iter().enumerate() + .map(move |(pat_index, pat)| { + (arm_index, pat_index, pat, arm.guard.clone()) + }) }) .zip(pre_binding_blocks.iter().zip(pre_binding_blocks.iter().skip(1))) - .map(|((arm_index, pattern, guard), + .map(|((arm_index, pat_index, pattern, guard), (pre_binding_block, next_candidate_pre_binding_block))| { if let (true, Some(borrow_temp)) = (tcx.emit_read_for_match(), @@ -134,9 +136,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // This should ensure that you cannot change // the variant for an enum while you are in // the midst of matching on it. - + let pattern_source_info = self.source_info(pattern.span); self.cfg.push(*pre_binding_block, Statement { - source_info, + source_info: pattern_source_info, kind: StatementKind::ReadForMatch(borrow_temp.clone()), }); } @@ -168,6 +170,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { bindings: vec![], guard, arm_index, + pat_index, pre_binding_block: *pre_binding_block, next_candidate_pre_binding_block: *next_candidate_pre_binding_block, } @@ -277,6 +280,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // since we don't call `match_candidates`, next fields is unused arm_index: 0, + pat_index: 0, pre_binding_block: block, next_candidate_pre_binding_block: block }; @@ -324,14 +328,15 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { mut visibility_scope: Option<SourceScope>, scope_span: Span, lint_level: LintLevel, - pattern: &Pattern<'tcx>, + patterns: &[Pattern<'tcx>], has_guard: ArmHasGuard, opt_match_place: Option<(Option<&Place<'tcx>>, Span)>) -> Option<SourceScope> { assert!(!(visibility_scope.is_some() && lint_level.is_explicit()), "can't have both a visibility and a lint scope at the same time"); let mut scope = self.source_scope; - self.visit_bindings(pattern, &mut |this, mutability, name, mode, var, span, ty| { + let num_patterns = patterns.len(); + self.visit_bindings(&patterns[0], &mut |this, mutability, name, mode, var, span, ty| { if visibility_scope.is_none() { visibility_scope = Some(this.new_source_scope(scope_span, LintLevel::Inherited, @@ -349,8 +354,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { scope, }; let visibility_scope = visibility_scope.unwrap(); - this.declare_binding(source_info, visibility_scope, mutability, name, mode, var, - ty, has_guard, opt_match_place.map(|(x, y)| (x.cloned(), y))); + this.declare_binding(source_info, visibility_scope, mutability, name, mode, + num_patterns, var, ty, has_guard, + opt_match_place.map(|(x, y)| (x.cloned(), y))); }); visibility_scope } @@ -453,6 +459,9 @@ pub struct Candidate<'pat, 'tcx:'pat> { // ...and the blocks for add false edges between candidates pre_binding_block: BasicBlock, next_candidate_pre_binding_block: BasicBlock, + + // This uniquely identifies this candidate *within* the arm. + pat_index: usize, } #[derive(Clone, Debug)] @@ -972,7 +981,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let autoref = self.hir.tcx().all_pat_vars_are_implicit_refs_within_guards(); if let Some(guard) = candidate.guard { if autoref { - self.bind_matched_candidate_for_guard(block, &candidate.bindings); + self.bind_matched_candidate_for_guard( + block, candidate.pat_index, &candidate.bindings); let guard_frame = GuardFrame { locals: candidate.bindings.iter() .map(|b| GuardFrameLocal::new(b.var_id, b.binding_mode)) @@ -1058,9 +1068,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // and thus all code/comments assume we are in that context. fn bind_matched_candidate_for_guard(&mut self, block: BasicBlock, + pat_index: usize, bindings: &[Binding<'tcx>]) { - debug!("bind_matched_candidate_for_guard(block={:?}, bindings={:?})", - block, bindings); + debug!("bind_matched_candidate_for_guard(block={:?}, pat_index={:?}, bindings={:?})", + block, pat_index, bindings); // Assign each of the bindings. Since we are binding for a // guard expression, this will never trigger moves out of the @@ -1099,8 +1110,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // used by the arm body itself. This eases // observing two-phase borrow restrictions. let val_for_guard = self.storage_live_binding( - block, binding.var_id, binding.span, ValWithinGuard); - self.schedule_drop_for_binding(binding.var_id, binding.span, ValWithinGuard); + block, binding.var_id, binding.span, ValWithinGuard(pat_index)); + self.schedule_drop_for_binding( + binding.var_id, binding.span, ValWithinGuard(pat_index)); // rust-lang/rust#27282: We reuse the two-phase // borrow infrastructure so that the mutable @@ -1146,16 +1158,26 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { /// Each binding (`ref mut var`/`ref var`/`mut var`/`var`, where /// the bound `var` has type `T` in the arm body) in a pattern - /// maps to *two* locals. The first local is a binding for + /// maps to `2+N` locals. The first local is a binding for /// occurrences of `var` in the guard, which will all have type - /// `&T`. The second local is a binding for occurrences of `var` - /// in the arm body, which will have type `T`. + /// `&T`. The N locals are bindings for the `T` that is referenced + /// by the first local; they are not used outside of the + /// guard. The last local is a binding for occurrences of `var` in + /// the arm body, which will have type `T`. + /// + /// The reason we have N locals rather than just 1 is to + /// accommodate rust-lang/rust#51348: If the arm has N candidate + /// patterns, then in general they can correspond to distinct + /// parts of the matched data, and we want them to be distinct + /// temps in order to simplify checks performed by our internal + /// leveraging of two-phase borrows). fn declare_binding(&mut self, source_info: SourceInfo, visibility_scope: SourceScope, mutability: Mutability, name: Name, mode: BindingMode, + num_patterns: usize, var_id: NodeId, var_ty: Ty<'tcx>, has_guard: ArmHasGuard, @@ -1189,7 +1211,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { }; let for_arm_body = self.local_decls.push(local.clone()); let locals = if has_guard.0 && tcx.all_pat_vars_are_implicit_refs_within_guards() { - let val_for_guard = self.local_decls.push(local); + let mut vals_for_guard = Vec::with_capacity(num_patterns); + for _ in 0..num_patterns { + let val_for_guard_idx = self.local_decls.push(local.clone()); + vals_for_guard.push(val_for_guard_idx); + } let ref_for_guard = self.local_decls.push(LocalDecl::<'tcx> { mutability, ty: tcx.mk_imm_ref(tcx.types.re_empty, var_ty), @@ -1200,7 +1226,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { internal: false, is_user_variable: Some(ClearCrossCrate::Set(BindingForm::RefForGuard)), }); - LocalsForNode::Three { val_for_guard, ref_for_guard, for_arm_body } + LocalsForNode::ForGuard { vals_for_guard, ref_for_guard, for_arm_body } } else { LocalsForNode::One(for_arm_body) }; diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs index 3ff209c872f..afa0d28dd77 100644 --- a/src/librustc_mir/build/matches/test.rs +++ b/src/librustc_mir/build/matches/test.rs @@ -631,6 +631,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { bindings: candidate.bindings.clone(), guard: candidate.guard.clone(), arm_index: candidate.arm_index, + pat_index: candidate.pat_index, pre_binding_block: candidate.pre_binding_block, next_candidate_pre_binding_block: candidate.next_candidate_pre_binding_block, } @@ -694,6 +695,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { bindings: candidate.bindings.clone(), guard: candidate.guard.clone(), arm_index: candidate.arm_index, + pat_index: candidate.pat_index, pre_binding_block: candidate.pre_binding_block, next_candidate_pre_binding_block: candidate.next_candidate_pre_binding_block, } diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 24228389fbf..054bd69c361 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -310,8 +310,31 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { #[derive(Debug)] enum LocalsForNode { + /// In the usual case, a node-id for an identifier maps to at most + /// one Local declaration. One(Local), - Three { val_for_guard: Local, ref_for_guard: Local, for_arm_body: Local }, + + /// The exceptional case is identifiers in a match arm's pattern + /// that are referenced in a guard of that match arm. For these, + /// we can have `2+k` Locals, where `k` is the number of candidate + /// patterns (separated by `|`) in the arm. + /// + /// * `for_arm_body` is the Local used in the arm body (which is + /// just like the `One` case above), + /// + /// * `ref_for_guard` is the Local used in the arm's guard (which + /// is a reference to a temp that is an alias of + /// `for_arm_body`). + /// + /// * `vals_for_guard` is the `k` Locals; at most one of them will + /// get initialized by the arm's execution, and after it is + /// initialized, `ref_for_guard` will be assigned a reference to + /// it. + /// + /// There reason we have `k` Locals rather than just 1 is to + /// accommodate some restrictions imposed by two-phase borrows, + /// which apply when we have a `ref mut` pattern. + ForGuard { vals_for_guard: Vec<Local>, ref_for_guard: Local, for_arm_body: Local }, } #[derive(Debug)] @@ -350,7 +373,10 @@ struct GuardFrame { /// 3. the temp for use outside of guard expressions. #[derive(Copy, Clone, Debug, PartialEq, Eq)] enum ForGuard { - ValWithinGuard, + /// The `usize` identifies for which candidate pattern we want the + /// local binding. We keep a temp per-candidate to accommodate + /// two-phase borrows (see `LocalsForNode` documentation). + ValWithinGuard(usize), RefWithinGuard, OutsideGuard, } @@ -359,12 +385,15 @@ impl LocalsForNode { fn local_id(&self, for_guard: ForGuard) -> Local { match (self, for_guard) { (&LocalsForNode::One(local_id), ForGuard::OutsideGuard) | - (&LocalsForNode::Three { val_for_guard: local_id, .. }, ForGuard::ValWithinGuard) | - (&LocalsForNode::Three { ref_for_guard: local_id, .. }, ForGuard::RefWithinGuard) | - (&LocalsForNode::Three { for_arm_body: local_id, .. }, ForGuard::OutsideGuard) => + (&LocalsForNode::ForGuard { ref_for_guard: local_id, .. }, ForGuard::RefWithinGuard) | + (&LocalsForNode::ForGuard { for_arm_body: local_id, .. }, ForGuard::OutsideGuard) => local_id, - (&LocalsForNode::One(_), ForGuard::ValWithinGuard) | + (&LocalsForNode::ForGuard { ref vals_for_guard, .. }, + ForGuard::ValWithinGuard(pat_idx)) => + vals_for_guard[pat_idx], + + (&LocalsForNode::One(_), ForGuard::ValWithinGuard(_)) | (&LocalsForNode::One(_), ForGuard::RefWithinGuard) => bug!("anything with one local should never be within a guard."), } @@ -740,7 +769,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { } _ => { scope = self.declare_bindings(scope, ast_body.span, - LintLevel::Inherited, &pattern, + LintLevel::Inherited, &[pattern.clone()], matches::ArmHasGuard(false), Some((Some(&place), span))); unpack!(block = self.place_into_pattern(block, pattern, &place, false)); diff --git a/src/librustc_mir/interpret/terminator/drop.rs b/src/librustc_mir/interpret/terminator/drop.rs index c0fafa7f83e..d750c1f47a6 100644 --- a/src/librustc_mir/interpret/terminator/drop.rs +++ b/src/librustc_mir/interpret/terminator/drop.rs @@ -78,7 +78,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> { self.eval_fn_call( instance, Some((Place::undef(), target)), - &vec![valty], + &[valty], span, fn_sig, ) diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 382248c2d15..54730ecd75f 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -14,8 +14,6 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! */ -#![deny(bare_trait_objects)] - #![feature(slice_patterns)] #![feature(slice_sort_by_cached_key)] #![feature(from_ref)] diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs index d35608068a6..937d01a0c5e 100644 --- a/src/librustc_mir/transform/elaborate_drops.rs +++ b/src/librustc_mir/transform/elaborate_drops.rs @@ -41,7 +41,20 @@ impl MirPass for ElaborateDrops { let id = tcx.hir.as_local_node_id(src.def_id).unwrap(); let param_env = tcx.param_env(src.def_id).with_reveal_all(); - let move_data = MoveData::gather_moves(mir, tcx).unwrap(); + let move_data = match MoveData::gather_moves(mir, tcx) { + Ok(move_data) => move_data, + Err((move_data, _move_errors)) => { + // The only way we should be allowing any move_errors + // in here is if we are in the migration path for the + // NLL-based MIR-borrowck. + // + // If we are in the migration path, we have already + // reported these errors as warnings to the user. So + // we will just ignore them here. + assert!(tcx.migrate_borrowck()); + move_data + } + }; let elaborate_patch = { let mir = &*mir; let env = MoveDataParamEnv { diff --git a/src/librustc_mir/transform/uniform_array_move_out.rs b/src/librustc_mir/transform/uniform_array_move_out.rs index 5019c74742a..7a8c35e7b96 100644 --- a/src/librustc_mir/transform/uniform_array_move_out.rs +++ b/src/librustc_mir/transform/uniform_array_move_out.rs @@ -222,7 +222,7 @@ impl RestoreSubsliceArrayMoveOut { // indices is an integer interval. If all checks pass do the replacent. // items are Vec<Option<LocalUse, index in source array, source place for init local>> fn check_and_patch<'tcx>(candidate: Location, - items: &Vec<Option<(&LocalUse, u32, &Place<'tcx>)>>, + items: &[Option<(&LocalUse, u32, &Place<'tcx>)>], opt_size: Option<u64>, patch: &mut MirPatch<'tcx>, dst_place: &Place<'tcx>) { diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index 689eb62042b..bbffeec631a 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -369,7 +369,9 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> }); } - let contents_drop = if adt.is_union() { + let skip_contents = + adt.is_union() || Some(adt.did) == self.tcx().lang_items().manually_drop(); + let contents_drop = if skip_contents { (self.succ, self.unwind) } else { self.open_drop_for_adt_contents(adt, substs) diff --git a/src/librustc_msan/lib.rs b/src/librustc_msan/lib.rs index 7bd1e98f85d..0c78fd74a23 100644 --- a/src/librustc_msan/lib.rs +++ b/src/librustc_msan/lib.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![deny(bare_trait_objects)] - #![sanitizer_runtime] #![feature(alloc_system)] #![feature(sanitizer_runtime)] diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index f27ca444672..c6bad9e1980 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -147,7 +147,7 @@ impl<'a> AstValidator<'a> { } } - fn check_late_bound_lifetime_defs(&self, params: &Vec<GenericParam>) { + fn check_late_bound_lifetime_defs(&self, params: &[GenericParam]) { // Check only lifetime parameters are present and that the lifetime // parameters that are present have no bounds. let non_lt_param_spans: Vec<_> = params.iter().filter_map(|param| match param.kind { diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs index 15d7c0fdaa3..41f1e782965 100644 --- a/src/librustc_passes/lib.rs +++ b/src/librustc_passes/lib.rs @@ -14,8 +14,6 @@ //! //! This API is completely unstable and subject to change. -#![deny(bare_trait_objects)] - #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] diff --git a/src/librustc_platform_intrinsics/lib.rs b/src/librustc_platform_intrinsics/lib.rs index 92e83fd70fa..b57debdd994 100644 --- a/src/librustc_platform_intrinsics/lib.rs +++ b/src/librustc_platform_intrinsics/lib.rs @@ -9,7 +9,6 @@ // except according to those terms. #![allow(bad_style)] -#![deny(bare_trait_objects)] pub struct Intrinsic { pub inputs: &'static [&'static Type], diff --git a/src/librustc_plugin/lib.rs b/src/librustc_plugin/lib.rs index b2c492f204f..348aa6a7cef 100644 --- a/src/librustc_plugin/lib.rs +++ b/src/librustc_plugin/lib.rs @@ -60,8 +60,6 @@ //! See the [`plugin` feature](../unstable-book/language-features/plugin.html) of //! the Unstable Book for more examples. -#![deny(bare_trait_objects)] - #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 7b13c98b31d..405952065da 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![deny(bare_trait_objects)] - #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index d8b9c58950f..725b3b4f150 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![deny(bare_trait_objects)] - #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 0ad652b4710..29b6f958cc1 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -783,7 +783,7 @@ impl<'a> Resolver<'a> { } }; let ident = Ident::new(Symbol::intern(name), span); - self.lookup_typo_candidate(&vec![ident], MacroNS, is_macro, span) + self.lookup_typo_candidate(&[ident], MacroNS, is_macro, span) }); if let Some(suggestion) = suggestion { diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index c84f194f023..a250d4a3598 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -13,7 +13,6 @@ html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(custom_attribute)] #![allow(unused_attributes)] -#![deny(bare_trait_objects)] #![recursion_limit="256"] diff --git a/src/librustc_target/lib.rs b/src/librustc_target/lib.rs index e611d26da56..8f491157439 100644 --- a/src/librustc_target/lib.rs +++ b/src/librustc_target/lib.rs @@ -21,8 +21,6 @@ //! one that doesn't; the one that doesn't might get decent parallel //! build speedups. -#![deny(bare_trait_objects)] - #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] diff --git a/src/librustc_target/spec/aarch64_unknown_fuchsia.rs b/src/librustc_target/spec/aarch64_fuchsia.rs index 4da6724ef62..28baf6f66e7 100644 --- a/src/librustc_target/spec/aarch64_unknown_fuchsia.rs +++ b/src/librustc_target/spec/aarch64_fuchsia.rs @@ -15,7 +15,7 @@ pub fn target() -> TargetResult { base.max_atomic_width = Some(128); Ok(Target { - llvm_target: "aarch64-unknown-fuchsia".to_string(), + llvm_target: "aarch64-fuchsia".to_string(), target_endian: "little".to_string(), target_pointer_width: "64".to_string(), target_c_int_width: "32".to_string(), @@ -23,7 +23,7 @@ pub fn target() -> TargetResult { arch: "aarch64".to_string(), target_os: "fuchsia".to_string(), target_env: "".to_string(), - target_vendor: "unknown".to_string(), + target_vendor: "".to_string(), linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { abi_blacklist: super::arm_base::abi_blacklist(), diff --git a/src/librustc_target/spec/fuchsia_base.rs b/src/librustc_target/spec/fuchsia_base.rs index 19a66b693f2..b593b835326 100644 --- a/src/librustc_target/spec/fuchsia_base.rs +++ b/src/librustc_target/spec/fuchsia_base.rs @@ -33,7 +33,7 @@ pub fn opts() -> TargetOptions { executables: true, target_family: Some("unix".to_string()), linker_is_gnu: true, - has_rpath: true, + has_rpath: false, pre_link_args: args, position_independent_executables: true, has_elf_tls: true, diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 9ac6e9835f0..c5d21cdc46a 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -332,8 +332,8 @@ supported_targets! { ("x86_64-apple-darwin", x86_64_apple_darwin), ("i686-apple-darwin", i686_apple_darwin), - ("aarch64-unknown-fuchsia", aarch64_unknown_fuchsia), - ("x86_64-unknown-fuchsia", x86_64_unknown_fuchsia), + ("aarch64-fuchsia", aarch64_fuchsia), + ("x86_64-fuchsia", x86_64_fuchsia), ("x86_64-unknown-l4re-uclibc", x86_64_unknown_l4re_uclibc), diff --git a/src/librustc_target/spec/x86_64_unknown_fuchsia.rs b/src/librustc_target/spec/x86_64_fuchsia.rs index a510ec8eb34..e8fa179887c 100644 --- a/src/librustc_target/spec/x86_64_unknown_fuchsia.rs +++ b/src/librustc_target/spec/x86_64_fuchsia.rs @@ -18,7 +18,7 @@ pub fn target() -> TargetResult { base.stack_probes = true; Ok(Target { - llvm_target: "x86_64-unknown-fuchsia".to_string(), + llvm_target: "x86_64-fuchsia".to_string(), target_endian: "little".to_string(), target_pointer_width: "64".to_string(), target_c_int_width: "32".to_string(), @@ -26,7 +26,7 @@ pub fn target() -> TargetResult { arch: "x86_64".to_string(), target_os: "fuchsia".to_string(), target_env: "".to_string(), - target_vendor: "unknown".to_string(), + target_vendor: "".to_string(), linker_flavor: LinkerFlavor::Gcc, options: base, }) diff --git a/src/librustc_traits/lib.rs b/src/librustc_traits/lib.rs index 2a4cacb5623..d17cf35f181 100644 --- a/src/librustc_traits/lib.rs +++ b/src/librustc_traits/lib.rs @@ -11,8 +11,6 @@ //! New recursive solver modeled on Chalk's recursive solver. Most of //! the guts are broken up into modules; see the comments in those modules. -#![deny(bare_trait_objects)] - #![feature(crate_in_paths)] #![feature(crate_visibility_modifier)] #![feature(extern_prelude)] diff --git a/src/librustc_tsan/lib.rs b/src/librustc_tsan/lib.rs index 7bd1e98f85d..0c78fd74a23 100644 --- a/src/librustc_tsan/lib.rs +++ b/src/librustc_tsan/lib.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![deny(bare_trait_objects)] - #![sanitizer_runtime] #![feature(alloc_system)] #![feature(sanitizer_runtime)] diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 220dd122b26..55aa38d942e 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -319,6 +319,17 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, E0053, "method `{}` has an incompatible type for trait", trait_m.ident); + if let TypeError::Mutability = terr { + if let Some(trait_err_span) = trait_err_span { + if let Ok(trait_err_str) = tcx.sess.codemap().span_to_snippet(trait_err_span) { + diag.span_suggestion( + impl_err_span, + "consider change the type to match the mutability in trait", + format!("{}", trait_err_str), + ); + } + } + } infcx.note_type_err(&mut diag, &cause, diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 03ecb945cbd..38743cc9cf6 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -211,8 +211,7 @@ fn check_associated_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } } ty::AssociatedKind::Existential => { - // FIXME(oli-obk) implement existential types in trait impls - unimplemented!() + // do nothing, existential types check themselves } } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 60f89282551..cd84a61bb2c 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1046,12 +1046,12 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx.mk_fn_def(def_id, substs) } ImplItemKind::Const(ref ty, _) => icx.to_ty(ty), - ImplItemKind::Existential(ref _bounds) => { + ImplItemKind::Existential(_) => { if tcx.impl_trait_ref(tcx.hir.get_parent_did(node_id)).is_none() { report_assoc_ty_on_inherent_impl(tcx, item.span); } - // FIXME(oli-obk) implement existential types in trait impls - unimplemented!() + + find_existential_constraints(tcx, def_id) } ImplItemKind::Type(ref ty) => { if tcx.impl_trait_ref(tcx.hir.get_parent_did(node_id)).is_none() { @@ -1186,8 +1186,10 @@ fn find_existential_constraints<'a, 'tcx>( } impl<'a, 'tcx> ConstraintLocator<'a, 'tcx> { fn check(&mut self, def_id: DefId) { + trace!("checking {:?}", def_id); // don't try to check items that cannot possibly constrain the type if !self.tcx.has_typeck_tables(def_id) { + trace!("no typeck tables for {:?}", def_id); return; } let ty = self @@ -1244,9 +1246,11 @@ fn find_existential_constraints<'a, 'tcx>( let mut locator = ConstraintLocator { def_id, tcx, found: None }; let node_id = tcx.hir.as_local_node_id(def_id).unwrap(); let parent = tcx.hir.get_parent(node_id); + trace!("parent_id: {:?}", parent); if parent == ast::CRATE_NODE_ID { intravisit::walk_crate(&mut locator, tcx.hir.krate()); } else { + trace!("parent: {:?}", tcx.hir.get(parent)); match tcx.hir.get(parent) { NodeItem(ref it) => intravisit::walk_item(&mut locator, it), NodeImplItem(ref it) => intravisit::walk_impl_item(&mut locator, it), @@ -1485,7 +1489,23 @@ fn explicit_predicates_of<'a, 'tcx>( &item.generics } - NodeImplItem(item) => &item.generics, + NodeImplItem(item) => match item.node { + ImplItemKind::Existential(ref bounds) => { + let substs = Substs::identity_for_item(tcx, def_id); + let anon_ty = tcx.mk_anon(def_id, substs); + + // Collect the bounds, i.e. the `A+B+'c` in `impl A+B+'c`. + let bounds = compute_bounds(&icx, + anon_ty, + bounds, + SizedByDefault::Yes, + tcx.def_span(def_id)); + + predicates.extend(bounds.predicates(tcx, anon_ty)); + &item.generics + }, + _ => &item.generics, + } NodeItem(item) => { match item.node { diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index e343fb1a57b..6bf1ec8f697 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -70,7 +70,6 @@ This API is completely unstable and subject to change. html_root_url = "https://doc.rust-lang.org/nightly/")] #![allow(non_camel_case_types)] -#![deny(bare_trait_objects)] #![feature(box_patterns)] #![feature(box_syntax)] diff --git a/src/librustc_typeck/outlives/utils.rs b/src/librustc_typeck/outlives/utils.rs index 5cb1822b04e..0d833c50d7e 100644 --- a/src/librustc_typeck/outlives/utils.rs +++ b/src/librustc_typeck/outlives/utils.rs @@ -27,7 +27,7 @@ pub fn insert_outlives_predicate<'tcx>( ) { // If the `'a` region is bound within the field type itself, we // don't want to propagate this constraint to the header. - if !is_free_region(outlived_region) { + if !is_free_region(tcx, outlived_region) { return; } @@ -120,7 +120,7 @@ pub fn insert_outlives_predicate<'tcx>( } UnpackedKind::Lifetime(r) => { - if !is_free_region(r) { + if !is_free_region(tcx, r) { return; } required_predicates.insert(ty::OutlivesPredicate(kind, outlived_region)); @@ -128,19 +128,36 @@ pub fn insert_outlives_predicate<'tcx>( } } -fn is_free_region(region: Region<'_>) -> bool { +fn is_free_region<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, region: Region<'_>) -> bool { // First, screen for regions that might appear in a type header. match region { - // *These* correspond to `T: 'a` relationships where `'a` is - // either declared on the type or `'static`: + // These correspond to `T: 'a` relationships: // // struct Foo<'a, T> { // field: &'a T, // this would generate a ReEarlyBound referencing `'a` - // field2: &'static T, // this would generate a ReStatic // } // // We care about these, so fall through. - RegionKind::ReStatic | RegionKind::ReEarlyBound(_) => true, + RegionKind::ReEarlyBound(_) => true, + + // These correspond to `T: 'static` relationships which can be + // rather surprising. We are therefore putting this behind a + // feature flag: + // + // struct Foo<'a, T> { + // field: &'static T, // this would generate a ReStatic + // } + RegionKind::ReStatic => { + if tcx + .sess + .features_untracked() + .infer_static_outlives_requirements + { + true + } else { + false + } + } // Late-bound regions can appear in `fn` types: // diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 0cdab134815..c30d6817b46 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -8,10 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use rustc::traits::auto_trait as auto; -use rustc::ty::TypeFoldable; use rustc::hir; +use rustc::traits::{self, auto_trait as auto}; +use rustc::ty::{self, ToPredicate, TypeFoldable}; +use rustc::ty::subst::Subst; +use rustc::infer::InferOk; use std::fmt::Debug; +use syntax_pos::DUMMY_SP; + +use core::DocAccessLevels; use super::*; @@ -75,6 +80,141 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { self.get_auto_trait_impls(did, &def_ctor, Some(name)) } + fn get_real_ty<F>(&self, + def_id: DefId, + def_ctor: &F, + real_name: &Option<Ident>, + generics: &ty::Generics, + ) -> hir::Ty + where F: Fn(DefId) -> Def { + let path = get_path_for_type(self.cx.tcx, def_id, def_ctor); + let mut segments = path.segments.into_vec(); + let last = segments.pop().unwrap(); + + segments.push(hir::PathSegment::new( + real_name.unwrap_or(last.ident), + self.generics_to_path_params(generics.clone()), + false, + )); + + let new_path = hir::Path { + span: path.span, + def: path.def, + segments: HirVec::from_vec(segments), + }; + + hir::Ty { + id: ast::DUMMY_NODE_ID, + node: hir::TyKind::Path(hir::QPath::Resolved(None, P(new_path))), + span: DUMMY_SP, + hir_id: hir::DUMMY_HIR_ID, + } + } + + pub fn get_blanket_impls<F>( + &self, + def_id: DefId, + def_ctor: &F, + name: Option<String>, + generics: &ty::Generics, + ) -> Vec<Item> + where F: Fn(DefId) -> Def { + let ty = self.cx.tcx.type_of(def_id); + let mut traits = Vec::new(); + if self.cx.access_levels.borrow().is_doc_reachable(def_id) { + let real_name = name.clone().map(|name| Ident::from_str(&name)); + let param_env = self.cx.tcx.param_env(def_id); + for &trait_def_id in self.cx.all_traits.iter() { + if !self.cx.access_levels.borrow().is_doc_reachable(trait_def_id) || + self.cx.generated_synthetics + .borrow_mut() + .get(&(def_id, trait_def_id)) + .is_some() { + continue + } + self.cx.tcx.for_each_relevant_impl(trait_def_id, ty, |impl_def_id| { + self.cx.tcx.infer_ctxt().enter(|infcx| { + let t_generics = infcx.tcx.generics_of(impl_def_id); + let trait_ref = infcx.tcx.impl_trait_ref(impl_def_id).unwrap(); + + match infcx.tcx.type_of(impl_def_id).sty { + ::rustc::ty::TypeVariants::TyParam(_) => {}, + _ => return, + } + + let substs = infcx.fresh_substs_for_item(DUMMY_SP, def_id); + let ty = ty.subst(infcx.tcx, substs); + let param_env = param_env.subst(infcx.tcx, substs); + + let impl_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id); + let trait_ref = trait_ref.subst(infcx.tcx, impl_substs); + + // Require the type the impl is implemented on to match + // our type, and ignore the impl if there was a mismatch. + let cause = traits::ObligationCause::dummy(); + let eq_result = infcx.at(&cause, param_env) + .eq(trait_ref.self_ty(), ty); + if let Ok(InferOk { value: (), obligations }) = eq_result { + // FIXME(eddyb) ignoring `obligations` might cause false positives. + drop(obligations); + + let may_apply = infcx.predicate_may_hold(&traits::Obligation::new( + cause.clone(), + param_env, + trait_ref.to_predicate(), + )); + if !may_apply { + return + } + self.cx.generated_synthetics.borrow_mut() + .insert((def_id, trait_def_id)); + let trait_ = hir::TraitRef { + path: get_path_for_type(infcx.tcx, + trait_def_id, + hir::def::Def::Trait), + ref_id: ast::DUMMY_NODE_ID, + }; + let provided_trait_methods = + infcx.tcx.provided_trait_methods(trait_def_id) + .into_iter() + .map(|meth| meth.ident.to_string()) + .collect(); + + let ty = self.get_real_ty(def_id, def_ctor, &real_name, generics); + let predicates = infcx.tcx.predicates_of(impl_def_id); + + traits.push(Item { + source: infcx.tcx.def_span(impl_def_id).clean(self.cx), + name: None, + attrs: Default::default(), + visibility: None, + def_id: self.next_def_id(impl_def_id.krate), + stability: None, + deprecation: None, + inner: ImplItem(Impl { + unsafety: hir::Unsafety::Normal, + generics: (t_generics, &predicates).clean(self.cx), + provided_trait_methods, + trait_: Some(trait_.clean(self.cx)), + for_: ty.clean(self.cx), + items: infcx.tcx.associated_items(impl_def_id) + .collect::<Vec<_>>() + .clean(self.cx), + polarity: None, + synthetic: false, + blanket_impl: Some(infcx.tcx.type_of(impl_def_id) + .clean(self.cx)), + }), + }); + debug!("{:?} => {}", trait_ref, may_apply); + } + }); + }); + } + } + traits + } + pub fn get_auto_trait_impls<F>( &self, def_id: DefId, @@ -122,6 +262,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { def_ctor, tcx.require_lang_item(lang_items::SyncTraitLangItem), ).into_iter()) + .chain(self.get_blanket_impls(def_id, def_ctor, name, &generics).into_iter()) .collect(); debug!( @@ -196,31 +337,8 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { } _ => unreachable!(), }; - - let path = get_path_for_type(self.cx.tcx, def_id, def_ctor); - let mut segments = path.segments.into_vec(); - let last = segments.pop().unwrap(); - let real_name = name.map(|name| Ident::from_str(&name)); - - segments.push(hir::PathSegment::new( - real_name.unwrap_or(last.ident), - self.generics_to_path_params(generics.clone()), - false, - )); - - let new_path = hir::Path { - span: path.span, - def: path.def, - segments: HirVec::from_vec(segments), - }; - - let ty = hir::Ty { - id: ast::DUMMY_NODE_ID, - node: hir::TyKind::Path(hir::QPath::Resolved(None, P(new_path))), - span: DUMMY_SP, - hir_id: hir::DUMMY_HIR_ID, - }; + let ty = self.get_real_ty(def_id, def_ctor, &real_name, &generics); return Some(Item { source: Span::empty(), @@ -239,6 +357,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { items: Vec::new(), polarity, synthetic: true, + blanket_impl: None, }), }); } diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 0117e4fde84..9245ef3cf50 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -275,7 +275,6 @@ pub fn build_impls(cx: &DocContext, did: DefId, auto_traits: bool) -> Vec<clean: if auto_traits { let auto_impls = get_auto_traits_with_def_id(cx, did); let mut renderinfo = cx.renderinfo.borrow_mut(); - let new_impls: Vec<clean::Item> = auto_impls.into_iter() .filter(|i| renderinfo.inlined.insert(i.def_id)).collect(); @@ -415,6 +414,7 @@ pub fn build_impl(cx: &DocContext, did: DefId, ret: &mut Vec<clean::Item>) { items: trait_items, polarity: Some(polarity.clean(cx)), synthetic: false, + blanket_impl: None, }), source: tcx.def_span(did).clean(cx), name: None, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 98684b27973..c050e30fea0 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -375,7 +375,7 @@ impl fmt::Debug for Item { let fake = MAX_DEF_ID.with(|m| m.borrow().get(&self.def_id.krate) .map(|id| self.def_id >= *id).unwrap_or(false)); - let def_id: &fmt::Debug = if fake { &"**FAKE**" } else { &self.def_id }; + let def_id: &dyn fmt::Debug = if fake { &"**FAKE**" } else { &self.def_id }; fmt.debug_struct("Item") .field("source", &self.source) @@ -1549,7 +1549,6 @@ impl GenericBound { } fn get_trait_type(&self) -> Option<Type> { - if let GenericBound::TraitBound(PolyTrait { ref trait_, .. }, _) = *self { return Some(trait_.clone()); } @@ -3880,6 +3879,7 @@ pub struct Impl { pub items: Vec<Item>, pub polarity: Option<ImplPolarity>, pub synthetic: bool, + pub blanket_impl: Option<Type>, } pub fn get_auto_traits_with_node_id(cx: &DocContext, id: ast::NodeId, name: String) -> Vec<Item> { @@ -3947,6 +3947,7 @@ impl Clean<Vec<Item>> for doctree::Impl { items, polarity: Some(self.polarity.clean(cx)), synthetic: false, + blanket_impl: None, }) }); ret diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 6e1b4589547..77375442d4c 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -11,7 +11,7 @@ use rustc_lint; use rustc_driver::{self, driver, target_features, abort_on_err}; use rustc::session::{self, config}; -use rustc::hir::def_id::{DefId, CrateNum}; +use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE}; use rustc::hir::def::Def; use rustc::middle::cstore::CrateStore; use rustc::middle::privacy::AccessLevels; @@ -55,7 +55,7 @@ pub struct DocContext<'a, 'tcx: 'a, 'rcx: 'a> { /// The stack of module NodeIds up till this point pub mod_ids: RefCell<Vec<NodeId>>, pub crate_name: Option<String>, - pub cstore: Rc<CrateStore>, + pub cstore: Rc<dyn CrateStore>, pub populated_all_crate_impls: Cell<bool>, // Note that external items for which `doc(hidden)` applies to are shown as // non-reachable while local items aren't. This is because we're reusing @@ -84,6 +84,7 @@ pub struct DocContext<'a, 'tcx: 'a, 'rcx: 'a> { /// Maps (type_id, trait_id) -> auto trait impl pub generated_synthetics: RefCell<FxHashSet<(DefId, DefId)>>, pub current_item_name: RefCell<Option<Name>>, + pub all_traits: Vec<DefId>, } impl<'a, 'tcx, 'rcx> DocContext<'a, 'tcx, 'rcx> { @@ -386,6 +387,7 @@ pub fn run_core(search_paths: SearchPaths, all_fake_def_ids: RefCell::new(FxHashSet()), generated_synthetics: RefCell::new(FxHashSet()), current_item_name: RefCell::new(None), + all_traits: tcx.all_traits(LOCAL_CRATE).to_vec(), }; debug!("crate: {:?}", tcx.hir.krate()); diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 0a25e9091de..feec513b975 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -767,7 +767,11 @@ fn fmt_impl(i: &clean::Impl, write!(f, " for ")?; } - fmt_type(&i.for_, f, use_absolute)?; + if let Some(ref ty) = i.blanket_impl { + fmt_type(ty, f, use_absolute)?; + } else { + fmt_type(&i.for_, f, use_absolute)?; + } fmt::Display::fmt(&WhereClause { gens: &i.generics, indent: 0, end_newline: true }, f)?; Ok(()) diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 5939d5341e3..6cf9b143373 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -395,7 +395,7 @@ impl Class { fn write_header(class: Option<&str>, id: Option<&str>, - out: &mut Write) + out: &mut dyn Write) -> io::Result<()> { write!(out, "<pre ")?; if let Some(id) = id { @@ -404,6 +404,6 @@ fn write_header(class: Option<&str>, write!(out, "class=\"rust {}\">\n", class.unwrap_or("")) } -fn write_footer(out: &mut Write) -> io::Result<()> { +fn write_footer(out: &mut dyn Write) -> io::Result<()> { write!(out, "</pre>\n") } diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index 5e93b20ea17..af7c0a04215 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -32,7 +32,7 @@ pub struct Page<'a> { } pub fn render<T: fmt::Display, S: fmt::Display>( - dst: &mut io::Write, layout: &Layout, page: &Page, sidebar: &S, t: &T, + dst: &mut dyn io::Write, layout: &Layout, page: &Page, sidebar: &S, t: &T, css_file_extension: bool, themes: &[PathBuf]) -> io::Result<()> { @@ -194,7 +194,7 @@ pub fn render<T: fmt::Display, S: fmt::Display>( ) } -pub fn redirect(dst: &mut io::Write, url: &str) -> io::Result<()> { +pub fn redirect(dst: &mut dyn io::Write, url: &str) -> io::Result<()> { // <script> triggers a redirect before refresh, so this is fine. write!(dst, r##"<!DOCTYPE html> diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index c06323b22dc..9f4f20e3539 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -176,7 +176,7 @@ pub enum ExternalLocation { } /// Metadata about implementations for a type or trait. -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct Impl { pub impl_item: clean::Item, } @@ -1821,7 +1821,7 @@ impl Context { } fn render_item(&self, - writer: &mut io::Write, + writer: &mut dyn io::Write, it: &clean::Item, pushname: bool) -> io::Result<()> { @@ -2688,7 +2688,7 @@ fn render_implementor(cx: &Context, implementor: &Impl, w: &mut fmt::Formatter, for it in &implementor.inner_impl().items { 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))?; + assoc_type(w, it, &[], Some(&tydef.type_), AssocItemLink::Anchor(None))?; write!(w, ";</span>")?; } } @@ -2898,18 +2898,18 @@ fn item_trait( render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All)?; let cache = cache(); - let impl_header = " - <h2 id='implementors' class='small-section-header'> - Implementors<a href='#implementors' class='anchor'></a> - </h2> - <ul class='item-list' id='implementors-list'> + let impl_header = "\ + <h2 id='implementors' class='small-section-header'>\ + Implementors<a href='#implementors' class='anchor'></a>\ + </h2>\ + <ul class='item-list' id='implementors-list'>\ "; - let synthetic_impl_header = " - <h2 id='synthetic-implementors' class='small-section-header'> - Auto implementors<a href='#synthetic-implementors' class='anchor'></a> - </h2> - <ul class='item-list' id='synthetic-implementors-list'> + let synthetic_impl_header = "\ + <h2 id='synthetic-implementors' class='small-section-header'>\ + Auto implementors<a href='#synthetic-implementors' class='anchor'></a>\ + </h2>\ + <ul class='item-list' id='synthetic-implementors-list'>\ "; let mut synthetic_types = Vec::new(); @@ -2940,9 +2940,9 @@ fn item_trait( .map_or(true, |d| cache.paths.contains_key(&d))); - let (synthetic, concrete) = local.iter() - .partition::<Vec<_>, _>(|i| i.inner_impl().synthetic); - + let (synthetic, concrete): (Vec<&&Impl>, Vec<&&Impl>) = local.iter() + .filter(|i| i.inner_impl().blanket_impl.is_none()) + .partition(|i| i.inner_impl().synthetic); if !foreign.is_empty() { write!(w, " @@ -3038,7 +3038,7 @@ fn assoc_const(w: &mut fmt::Formatter, } fn assoc_type<W: fmt::Write>(w: &mut W, it: &clean::Item, - bounds: &Vec<clean::GenericBound>, + bounds: &[clean::GenericBound], default: Option<&clean::Type>, link: AssocItemLink) -> fmt::Result { write!(w, "type <a href='{}' class=\"type\">{}</a>", @@ -3588,18 +3588,19 @@ fn render_assoc_items(w: &mut fmt::Formatter, if !non_trait.is_empty() { let render_mode = match what { AssocItemRender::All => { - write!(w, " - <h2 id='methods' class='small-section-header'> - Methods<a href='#methods' class='anchor'></a> - </h2> + write!(w, "\ + <h2 id='methods' class='small-section-header'>\ + Methods<a href='#methods' class='anchor'></a>\ + </h2>\ ")?; RenderMode::Normal } AssocItemRender::DerefFor { trait_, type_, deref_mut_ } => { - write!(w, " - <h2 id='deref-methods' class='small-section-header'> - Methods from {}<Target = {}><a href='#deref-methods' class='anchor'></a> - </h2> + write!(w, "\ + <h2 id='deref-methods' class='small-section-header'>\ + Methods from {}<Target = {}>\ + <a href='#deref-methods' class='anchor'></a>\ + </h2>\ ", trait_, type_)?; RenderMode::ForDeref { mut_: deref_mut_ } } @@ -3623,9 +3624,12 @@ fn render_assoc_items(w: &mut fmt::Formatter, render_deref_methods(w, cx, impl_, containing_item, has_deref_mut)?; } - let (synthetic, concrete) = traits + let (synthetic, concrete): (Vec<&&Impl>, Vec<&&Impl>) = traits .iter() - .partition::<Vec<_>, _>(|t| t.inner_impl().synthetic); + .partition(|t| t.inner_impl().synthetic); + let (blanket_impl, concrete) = concrete + .into_iter() + .partition(|t| t.inner_impl().blanket_impl.is_some()); struct RendererStruct<'a, 'b, 'c>(&'a Context, Vec<&'b &'b Impl>, &'c clean::Item); @@ -3637,23 +3641,36 @@ fn render_assoc_items(w: &mut fmt::Formatter, let impls = format!("{}", RendererStruct(cx, concrete, containing_item)); if !impls.is_empty() { - write!(w, " - <h2 id='implementations' class='small-section-header'> - Trait Implementations<a href='#implementations' class='anchor'></a> - </h2> + write!(w, "\ + <h2 id='implementations' class='small-section-header'>\ + Trait Implementations<a href='#implementations' class='anchor'></a>\ + </h2>\ <div id='implementations-list'>{}</div>", impls)?; } if !synthetic.is_empty() { - write!(w, " - <h2 id='synthetic-implementations' class='small-section-header'> - Auto Trait Implementations<a href='#synthetic-implementations' class='anchor'></a> - </h2> - <div id='synthetic-implementations-list'> + write!(w, "\ + <h2 id='synthetic-implementations' class='small-section-header'>\ + Auto Trait Implementations\ + <a href='#synthetic-implementations' class='anchor'></a>\ + </h2>\ + <div id='synthetic-implementations-list'>\ ")?; render_impls(cx, w, &synthetic, containing_item)?; write!(w, "</div>")?; } + + if !blanket_impl.is_empty() { + write!(w, "\ + <h2 id='blanket-implementations' class='small-section-header'>\ + Blanket Implementations\ + <a href='#blanket-implementations' class='anchor'></a>\ + </h2>\ + <div id='blanket-implementations-list'>\ + ")?; + render_impls(cx, w, &blanket_impl, containing_item)?; + write!(w, "</div>")?; + } } Ok(()) } @@ -3747,7 +3764,7 @@ fn spotlight_decl(decl: &clean::FnDecl) -> Result<String, fmt::Error> { for it in &impl_.items { if let clean::TypedefItem(ref tydef, _) = it.inner { out.push_str("<span class=\"where fmt-newline\"> "); - assoc_type(&mut out, it, &vec![], + assoc_type(&mut out, it, &[], Some(&tydef.type_), AssocItemLink::GotoSource(t_did, &FxHashSet()))?; out.push_str(";</span>"); @@ -4199,12 +4216,16 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { .collect::<String>() }; - let (synthetic, concrete) = v + let (synthetic, concrete): (Vec<&Impl>, Vec<&Impl>) = v .iter() .partition::<Vec<_>, _>(|i| i.inner_impl().synthetic); + let (blanket_impl, concrete): (Vec<&Impl>, Vec<&Impl>) = concrete + .into_iter() + .partition::<Vec<_>, _>(|i| i.inner_impl().blanket_impl.is_some()); let concrete_format = format_impls(concrete); let synthetic_format = format_impls(synthetic); + let blanket_format = format_impls(blanket_impl); if !concrete_format.is_empty() { out.push_str("<a class=\"sidebar-title\" href=\"#implementations\">\ @@ -4217,6 +4238,12 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { Auto Trait Implementations</a>"); out.push_str(&format!("<div class=\"sidebar-links\">{}</div>", synthetic_format)); } + + if !blanket_format.is_empty() { + out.push_str("<a class=\"sidebar-title\" href=\"#blanket-implementations\">\ + Blanket Implementations</a>"); + out.push_str(&format!("<div class=\"sidebar-links\">{}</div>", blanket_format)); + } } } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 9ebefdabbb4..00cad5e376a 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -373,6 +373,10 @@ pub fn main_args(args: &[String]) -> isize { for &name in passes::DEFAULT_PASSES { println!("{:>20}", name); } + println!("\nPasses run with `--document-private-items`:"); + for &name in passes::DEFAULT_PRIVATE_PASSES { + println!("{:>20}", name); + } return 0; } @@ -623,20 +627,16 @@ fn rust_input<R, F>(cratefile: PathBuf, where R: 'static + Send, F: 'static + Send + FnOnce(Output) -> R { - let mut default_passes = !matches.opt_present("no-defaults"); - let mut passes = matches.opt_strs("passes"); - let mut plugins = matches.opt_strs("plugins"); - - // We hardcode in the passes here, as this is a new flag and we - // are generally deprecating passes. - if matches.opt_present("document-private-items") { - default_passes = false; + let mut default_passes = if matches.opt_present("no-defaults") { + passes::DefaultPassOption::None + } else if matches.opt_present("document-private-items") { + passes::DefaultPassOption::Private + } else { + passes::DefaultPassOption::Default + }; - passes = vec![ - String::from("collapse-docs"), - String::from("unindent-comments"), - ]; - } + let mut manual_passes = matches.opt_strs("passes"); + let mut plugins = matches.opt_strs("plugins"); // First, parse the crate and extract all relevant information. let mut paths = SearchPaths::new(); @@ -706,13 +706,15 @@ where R: 'static + Send, if attr.is_word() { if name == Some("no_default_passes") { report_deprecated_attr("no_default_passes", &diag); - default_passes = false; + if default_passes == passes::DefaultPassOption::Default { + default_passes = passes::DefaultPassOption::None; + } } } else if let Some(value) = attr.value_str() { let sink = match name { Some("passes") => { report_deprecated_attr("passes = \"...\"", &diag); - &mut passes + &mut manual_passes }, Some("plugins") => { report_deprecated_attr("plugins = \"...\"", &diag); @@ -726,20 +728,15 @@ where R: 'static + Send, } if attr.is_word() && name == Some("document_private_items") { - default_passes = false; - - passes = vec![ - String::from("collapse-docs"), - String::from("unindent-comments"), - ]; + if default_passes == passes::DefaultPassOption::Default { + default_passes = passes::DefaultPassOption::Private; + } } } - if default_passes { - for name in passes::DEFAULT_PASSES.iter().rev() { - passes.insert(0, name.to_string()); - } - } + let mut passes: Vec<String> = + passes::defaults(default_passes).iter().map(|p| p.to_string()).collect(); + passes.extend(manual_passes); if !plugins.is_empty() { eprintln!("WARNING: --plugins no longer functions; see CVE-2018-1000622"); diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index 63b74ceafac..8de4fed5bf0 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -63,6 +63,33 @@ pub const DEFAULT_PASSES: &'static [&'static str] = &[ "propagate-doc-cfg", ]; +pub const DEFAULT_PRIVATE_PASSES: &'static [&'static str] = &[ + "strip-priv-imports", + "collapse-docs", + "unindent-comments", + "propagate-doc-cfg", +]; + +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub enum DefaultPassOption { + Default, + Private, + None, +} + +pub fn defaults(default_set: DefaultPassOption) -> &'static [&'static str] { + match default_set { + DefaultPassOption::Default => { + DEFAULT_PASSES + }, + DefaultPassOption::Private => { + DEFAULT_PRIVATE_PASSES + }, + DefaultPassOption::None => { + &[] + }, + } +} struct Stripper<'a> { retained: &'a mut DefIdSet, diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index eb980a7369b..2966b9e9819 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -249,7 +249,7 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize, } fn flush(&mut self) -> io::Result<()> { Ok(()) } } - struct Bomb(Arc<Mutex<Vec<u8>>>, Box<Write+Send>); + struct Bomb(Arc<Mutex<Vec<u8>>>, Box<dyn Write+Send>); impl Drop for Bomb { fn drop(&mut self) { let _ = self.1.write_all(&self.0.lock().unwrap()); diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs index 7c1bb69434d..a5f4b32b329 100644 --- a/src/libserialize/lib.rs +++ b/src/libserialize/lib.rs @@ -14,8 +14,6 @@ Core encoding and decoding interfaces. */ -#![deny(bare_trait_objects)] - #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/", diff --git a/src/libstd/error.rs b/src/libstd/error.rs index 1958915602f..29534696abc 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -138,7 +138,7 @@ pub trait Error: Debug + Display { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] - fn cause(&self) -> Option<&Error> { None } + fn cause(&self) -> Option<&dyn Error> { None } /// Get the `TypeId` of `self` #[doc(hidden)] @@ -151,22 +151,22 @@ pub trait Error: Debug + Display { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, E: Error + 'a> From<E> for Box<Error + 'a> { - fn from(err: E) -> Box<Error + 'a> { +impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> { + fn from(err: E) -> Box<dyn Error + 'a> { Box::new(err) } } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<Error + Send + Sync + 'a> { - fn from(err: E) -> Box<Error + Send + Sync + 'a> { +impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<dyn Error + Send + Sync + 'a> { + fn from(err: E) -> Box<dyn Error + Send + Sync + 'a> { Box::new(err) } } #[stable(feature = "rust1", since = "1.0.0")] -impl From<String> for Box<Error + Send + Sync> { - fn from(err: String) -> Box<Error + Send + Sync> { +impl From<String> for Box<dyn Error + Send + Sync> { + fn from(err: String) -> Box<dyn Error + Send + Sync> { #[derive(Debug)] struct StringError(String); @@ -185,38 +185,38 @@ impl From<String> for Box<Error + Send + Sync> { } #[stable(feature = "string_box_error", since = "1.6.0")] -impl From<String> for Box<Error> { - fn from(str_err: String) -> Box<Error> { - let err1: Box<Error + Send + Sync> = From::from(str_err); - let err2: Box<Error> = err1; +impl From<String> for Box<dyn Error> { + fn from(str_err: String) -> Box<dyn Error> { + let err1: Box<dyn Error + Send + Sync> = From::from(str_err); + let err2: Box<dyn Error> = err1; err2 } } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, 'b> From<&'b str> for Box<Error + Send + Sync + 'a> { - fn from(err: &'b str) -> Box<Error + Send + Sync + 'a> { +impl<'a, 'b> From<&'b str> for Box<dyn Error + Send + Sync + 'a> { + fn from(err: &'b str) -> Box<dyn Error + Send + Sync + 'a> { From::from(String::from(err)) } } #[stable(feature = "string_box_error", since = "1.6.0")] -impl<'a> From<&'a str> for Box<Error> { - fn from(err: &'a str) -> Box<Error> { +impl<'a> From<&'a str> for Box<dyn Error> { + fn from(err: &'a str) -> Box<dyn Error> { From::from(String::from(err)) } } #[stable(feature = "cow_box_error", since = "1.22.0")] -impl<'a, 'b> From<Cow<'b, str>> for Box<Error + Send + Sync + 'a> { - fn from(err: Cow<'b, str>) -> Box<Error + Send + Sync + 'a> { +impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + Send + Sync + 'a> { + fn from(err: Cow<'b, str>) -> Box<dyn Error + Send + Sync + 'a> { From::from(String::from(err)) } } #[stable(feature = "cow_box_error", since = "1.22.0")] -impl<'a> From<Cow<'a, str>> for Box<Error> { - fn from(err: Cow<'a, str>) -> Box<Error> { +impl<'a> From<Cow<'a, str>> for Box<dyn Error> { + fn from(err: Cow<'a, str>) -> Box<dyn Error> { From::from(String::from(err)) } } @@ -327,7 +327,7 @@ impl<T: Error> Error for Box<T> { Error::description(&**self) } - fn cause(&self) -> Option<&Error> { + fn cause(&self) -> Option<&dyn Error> { Error::cause(&**self) } } @@ -368,7 +368,7 @@ impl Error for char::ParseCharError { } // copied from any.rs -impl Error + 'static { +impl dyn Error + 'static { /// Returns true if the boxed type is the same as `T` #[stable(feature = "error_downcast", since = "1.3.0")] #[inline] @@ -390,7 +390,7 @@ impl Error + 'static { pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> { if self.is::<T>() { unsafe { - Some(&*(self as *const Error as *const T)) + Some(&*(self as *const dyn Error as *const T)) } } else { None @@ -404,7 +404,7 @@ impl Error + 'static { pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> { if self.is::<T>() { unsafe { - Some(&mut *(self as *mut Error as *mut T)) + Some(&mut *(self as *mut dyn Error as *mut T)) } } else { None @@ -412,60 +412,60 @@ impl Error + 'static { } } -impl Error + 'static + Send { +impl dyn Error + 'static + Send { /// Forwards to the method defined on the type `Any`. #[stable(feature = "error_downcast", since = "1.3.0")] #[inline] pub fn is<T: Error + 'static>(&self) -> bool { - <Error + 'static>::is::<T>(self) + <dyn Error + 'static>::is::<T>(self) } /// Forwards to the method defined on the type `Any`. #[stable(feature = "error_downcast", since = "1.3.0")] #[inline] pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> { - <Error + 'static>::downcast_ref::<T>(self) + <dyn Error + 'static>::downcast_ref::<T>(self) } /// Forwards to the method defined on the type `Any`. #[stable(feature = "error_downcast", since = "1.3.0")] #[inline] pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> { - <Error + 'static>::downcast_mut::<T>(self) + <dyn Error + 'static>::downcast_mut::<T>(self) } } -impl Error + 'static + Send + Sync { +impl dyn Error + 'static + Send + Sync { /// Forwards to the method defined on the type `Any`. #[stable(feature = "error_downcast", since = "1.3.0")] #[inline] pub fn is<T: Error + 'static>(&self) -> bool { - <Error + 'static>::is::<T>(self) + <dyn Error + 'static>::is::<T>(self) } /// Forwards to the method defined on the type `Any`. #[stable(feature = "error_downcast", since = "1.3.0")] #[inline] pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> { - <Error + 'static>::downcast_ref::<T>(self) + <dyn Error + 'static>::downcast_ref::<T>(self) } /// Forwards to the method defined on the type `Any`. #[stable(feature = "error_downcast", since = "1.3.0")] #[inline] pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> { - <Error + 'static>::downcast_mut::<T>(self) + <dyn Error + 'static>::downcast_mut::<T>(self) } } -impl Error { +impl dyn Error { #[inline] #[stable(feature = "error_downcast", since = "1.3.0")] /// Attempt to downcast the box to a concrete type. - pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<Error>> { + pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<dyn Error>> { if self.is::<T>() { unsafe { - let raw: *mut Error = Box::into_raw(self); + let raw: *mut dyn Error = Box::into_raw(self); Ok(Box::from_raw(raw as *mut T)) } } else { @@ -474,30 +474,30 @@ impl Error { } } -impl Error + Send { +impl dyn Error + Send { #[inline] #[stable(feature = "error_downcast", since = "1.3.0")] /// Attempt to downcast the box to a concrete type. pub fn downcast<T: Error + 'static>(self: Box<Self>) - -> Result<Box<T>, Box<Error + Send>> { - let err: Box<Error> = self; - <Error>::downcast(err).map_err(|s| unsafe { + -> Result<Box<T>, Box<dyn Error + Send>> { + let err: Box<dyn Error> = self; + <dyn Error>::downcast(err).map_err(|s| unsafe { // reapply the Send marker - transmute::<Box<Error>, Box<Error + Send>>(s) + transmute::<Box<dyn Error>, Box<dyn Error + Send>>(s) }) } } -impl Error + Send + Sync { +impl dyn Error + Send + Sync { #[inline] #[stable(feature = "error_downcast", since = "1.3.0")] /// Attempt to downcast the box to a concrete type. pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<Self>> { - let err: Box<Error> = self; - <Error>::downcast(err).map_err(|s| unsafe { + let err: Box<dyn Error> = self; + <dyn Error>::downcast(err).map_err(|s| unsafe { // reapply the Send+Sync marker - transmute::<Box<Error>, Box<Error + Send + Sync>>(s) + transmute::<Box<dyn Error>, Box<dyn Error + Send + Sync>>(s) }) } } @@ -533,13 +533,13 @@ mod tests { #[test] fn downcasting() { let mut a = A; - let a = &mut a as &mut (Error + 'static); + let a = &mut a as &mut (dyn Error + 'static); assert_eq!(a.downcast_ref::<A>(), Some(&A)); assert_eq!(a.downcast_ref::<B>(), None); assert_eq!(a.downcast_mut::<A>(), Some(&mut A)); assert_eq!(a.downcast_mut::<B>(), None); - let a: Box<Error> = Box::new(A); + let a: Box<dyn Error> = Box::new(A); match a.downcast::<B>() { Ok(..) => panic!("expected error"), Err(e) => assert_eq!(*e.downcast::<A>().unwrap(), A), diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index b816f4b7850..754e2bbc412 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -891,7 +891,7 @@ impl Error for IntoStringError { "C string contained non-utf8 bytes" } - fn cause(&self) -> Option<&Error> { + fn cause(&self) -> Option<&dyn Error> { Some(&self.error) } } diff --git a/src/libstd/io/error.rs b/src/libstd/io/error.rs index bdd675e6e2b..02a3ce8b9c4 100644 --- a/src/libstd/io/error.rs +++ b/src/libstd/io/error.rs @@ -83,7 +83,7 @@ enum Repr { #[derive(Debug)] struct Custom { kind: ErrorKind, - error: Box<error::Error+Send+Sync>, + error: Box<dyn error::Error+Send+Sync>, } /// A list specifying general categories of I/O error. @@ -250,12 +250,12 @@ impl Error { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn new<E>(kind: ErrorKind, error: E) -> Error - where E: Into<Box<error::Error+Send+Sync>> + where E: Into<Box<dyn error::Error+Send+Sync>> { Self::_new(kind, error.into()) } - fn _new(kind: ErrorKind, error: Box<error::Error+Send+Sync>) -> Error { + fn _new(kind: ErrorKind, error: Box<dyn error::Error+Send+Sync>) -> Error { Error { repr: Repr::Custom(Box::new(Custom { kind, @@ -373,7 +373,7 @@ impl Error { /// } /// ``` #[stable(feature = "io_error_inner", since = "1.3.0")] - pub fn get_ref(&self) -> Option<&(error::Error+Send+Sync+'static)> { + pub fn get_ref(&self) -> Option<&(dyn error::Error+Send+Sync+'static)> { match self.repr { Repr::Os(..) => None, Repr::Simple(..) => None, @@ -444,7 +444,7 @@ impl Error { /// } /// ``` #[stable(feature = "io_error_inner", since = "1.3.0")] - pub fn get_mut(&mut self) -> Option<&mut (error::Error+Send+Sync+'static)> { + pub fn get_mut(&mut self) -> Option<&mut (dyn error::Error+Send+Sync+'static)> { match self.repr { Repr::Os(..) => None, Repr::Simple(..) => None, @@ -478,7 +478,7 @@ impl Error { /// } /// ``` #[stable(feature = "io_error_inner", since = "1.3.0")] - pub fn into_inner(self) -> Option<Box<error::Error+Send+Sync>> { + pub fn into_inner(self) -> Option<Box<dyn error::Error+Send+Sync>> { match self.repr { Repr::Os(..) => None, Repr::Simple(..) => None, @@ -551,7 +551,7 @@ impl error::Error for Error { } } - fn cause(&self) -> Option<&error::Error> { + fn cause(&self) -> Option<&dyn error::Error> { match self.repr { Repr::Os(..) => None, Repr::Simple(..) => None, diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 2b4644bd013..85304874848 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -1972,7 +1972,7 @@ impl<T: BufRead> BufRead for Take<T> { } } -fn read_one_byte(reader: &mut Read) -> Option<Result<u8>> { +fn read_one_byte(reader: &mut dyn Read) -> Option<Result<u8>> { let mut buf = [0]; loop { return match reader.read(&mut buf) { @@ -2081,7 +2081,7 @@ impl std_error::Error for CharsError { CharsError::Other(ref e) => std_error::Error::description(e), } } - fn cause(&self) -> Option<&std_error::Error> { + fn cause(&self) -> Option<&dyn std_error::Error> { match *self { CharsError::NotUtf8 => None, CharsError::Other(ref e) => e.cause(), diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index fce85a200ba..fffe8fc559b 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -21,7 +21,7 @@ use thread::LocalKey; /// Stdout used by print! and println! macros thread_local! { - static LOCAL_STDOUT: RefCell<Option<Box<Write + Send>>> = { + static LOCAL_STDOUT: RefCell<Option<Box<dyn Write + Send>>> = { RefCell::new(None) } } @@ -624,7 +624,7 @@ impl<'a> fmt::Debug for StderrLock<'a> { with a more general mechanism", issue = "0")] #[doc(hidden)] -pub fn set_panic(sink: Option<Box<Write + Send>>) -> Option<Box<Write + Send>> { +pub fn set_panic(sink: Option<Box<dyn Write + Send>>) -> Option<Box<dyn Write + Send>> { use panicking::LOCAL_STDERR; use mem; LOCAL_STDERR.with(move |slot| { @@ -648,7 +648,7 @@ pub fn set_panic(sink: Option<Box<Write + Send>>) -> Option<Box<Write + Send>> { with a more general mechanism", issue = "0")] #[doc(hidden)] -pub fn set_print(sink: Option<Box<Write + Send>>) -> Option<Box<Write + Send>> { +pub fn set_print(sink: Option<Box<dyn Write + Send>>) -> Option<Box<dyn Write + Send>> { use mem; LOCAL_STDOUT.with(move |slot| { mem::replace(&mut *slot.borrow_mut(), sink) @@ -670,7 +670,7 @@ pub fn set_print(sink: Option<Box<Write + Send>>) -> Option<Box<Write + Send>> { /// However, if the actual I/O causes an error, this function does panic. fn print_to<T>( args: fmt::Arguments, - local_s: &'static LocalKey<RefCell<Option<Box<Write+Send>>>>, + local_s: &'static LocalKey<RefCell<Option<Box<dyn Write+Send>>>>, global_s: fn() -> T, label: &str, ) diff --git a/src/libstd/io/util.rs b/src/libstd/io/util.rs index 195310a26fe..33f741dbc38 100644 --- a/src/libstd/io/util.rs +++ b/src/libstd/io/util.rs @@ -223,7 +223,7 @@ mod tests { assert_eq!(copy(&mut r, &mut w).unwrap(), 4); let mut r = repeat(0).take(1 << 17); - assert_eq!(copy(&mut r as &mut Read, &mut w as &mut Write).unwrap(), 1 << 17); + assert_eq!(copy(&mut r as &mut dyn Read, &mut w as &mut dyn Write).unwrap(), 1 << 17); } #[test] diff --git a/src/libstd/net/parser.rs b/src/libstd/net/parser.rs index 008c5da171f..cf3e5354a31 100644 --- a/src/libstd/net/parser.rs +++ b/src/libstd/net/parser.rs @@ -58,7 +58,7 @@ impl<'a> Parser<'a> { } // Return result of first successful parser - fn read_or<T>(&mut self, parsers: &mut [Box<FnMut(&mut Parser) -> Option<T> + 'static>]) + fn read_or<T>(&mut self, parsers: &mut [Box<dyn FnMut(&mut Parser) -> Option<T> + 'static>]) -> Option<T> { for pf in parsers { if let Some(r) = self.read_atomically(|p: &mut Parser| pf(p)) { diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs index 6b4bbdddf32..75c7a3d9280 100644 --- a/src/libstd/net/tcp.rs +++ b/src/libstd/net/tcp.rs @@ -927,7 +927,7 @@ mod tests { use time::{Instant, Duration}; use thread; - fn each_ip(f: &mut FnMut(SocketAddr)) { + fn each_ip(f: &mut dyn FnMut(SocketAddr)) { f(next_test_ip4()); f(next_test_ip6()); } diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs index d25e29999cb..0ebe3284b4f 100644 --- a/src/libstd/net/udp.rs +++ b/src/libstd/net/udp.rs @@ -826,7 +826,7 @@ mod tests { use time::{Instant, Duration}; use thread; - fn each_ip(f: &mut FnMut(SocketAddr, SocketAddr)) { + fn each_ip(f: &mut dyn FnMut(SocketAddr, SocketAddr)) { f(next_test_ip4(), next_test_ip4()); f(next_test_ip6(), next_test_ip6()); } diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs index 451420ae88a..b8c1c4f9e68 100644 --- a/src/libstd/panic.rs +++ b/src/libstd/panic.rs @@ -421,6 +421,6 @@ pub fn catch_unwind<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> { /// } /// ``` #[stable(feature = "resume_unwind", since = "1.9.0")] -pub fn resume_unwind(payload: Box<Any + Send>) -> ! { +pub fn resume_unwind(payload: Box<dyn Any + Send>) -> ! { panicking::update_count_then_panic(payload) } diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index 46b6cf60705..283fd36af41 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -36,7 +36,7 @@ use sys_common::util; use thread; thread_local! { - pub static LOCAL_STDERR: RefCell<Option<Box<Write + Send>>> = { + pub static LOCAL_STDERR: RefCell<Option<Box<dyn Write + Send>>> = { RefCell::new(None) } } @@ -64,7 +64,7 @@ extern { #[derive(Copy, Clone)] enum Hook { Default, - Custom(*mut (Fn(&PanicInfo) + 'static + Sync + Send)), + Custom(*mut (dyn Fn(&PanicInfo) + 'static + Sync + Send)), } static HOOK_LOCK: RWLock = RWLock::new(); @@ -104,7 +104,7 @@ static mut HOOK: Hook = Hook::Default; /// panic!("Normal panic"); /// ``` #[stable(feature = "panic_hooks", since = "1.10.0")] -pub fn set_hook(hook: Box<Fn(&PanicInfo) + 'static + Sync + Send>) { +pub fn set_hook(hook: Box<dyn Fn(&PanicInfo) + 'static + Sync + Send>) { if thread::panicking() { panic!("cannot modify the panic hook from a panicking thread"); } @@ -149,7 +149,7 @@ pub fn set_hook(hook: Box<Fn(&PanicInfo) + 'static + Sync + Send>) { /// panic!("Normal panic"); /// ``` #[stable(feature = "panic_hooks", since = "1.10.0")] -pub fn take_hook() -> Box<Fn(&PanicInfo) + 'static + Sync + Send> { +pub fn take_hook() -> Box<dyn Fn(&PanicInfo) + 'static + Sync + Send> { if thread::panicking() { panic!("cannot modify the panic hook from a panicking thread"); } @@ -197,7 +197,7 @@ fn default_hook(info: &PanicInfo) { let thread = thread_info::current_thread(); let name = thread.as_ref().and_then(|t| t.name()).unwrap_or("<unnamed>"); - let write = |err: &mut ::io::Write| { + let write = |err: &mut dyn (::io::Write)| { let _ = writeln!(err, "thread '{}' panicked at '{}', {}", name, msg, location); @@ -248,7 +248,7 @@ pub fn update_panic_count(amt: isize) -> usize { pub use realstd::rt::update_panic_count; /// Invoke a closure, capturing the cause of an unwinding panic if one occurs. -pub unsafe fn try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<Any + Send>> { +pub unsafe fn try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>> { #[allow(unions_with_drop_fields)] union Data<F, R> { f: F, @@ -369,12 +369,12 @@ fn continue_panic_fmt(info: &PanicInfo) -> ! { } unsafe impl<'a> BoxMeUp for PanicPayload<'a> { - fn box_me_up(&mut self) -> *mut (Any + Send) { + fn box_me_up(&mut self) -> *mut (dyn Any + Send) { let contents = mem::replace(self.fill(), String::new()); Box::into_raw(Box::new(contents)) } - fn get(&mut self) -> &(Any + Send) { + fn get(&mut self) -> &(dyn Any + Send) { self.fill() } } @@ -419,15 +419,15 @@ pub fn begin_panic<M: Any + Send>(msg: M, file_line_col: &(&'static str, u32, u3 } unsafe impl<A: Send + 'static> BoxMeUp for PanicPayload<A> { - fn box_me_up(&mut self) -> *mut (Any + Send) { + fn box_me_up(&mut self) -> *mut (dyn Any + Send) { let data = match self.inner.take() { - Some(a) => Box::new(a) as Box<Any + Send>, + Some(a) => Box::new(a) as Box<dyn Any + Send>, None => Box::new(()), }; Box::into_raw(data) } - fn get(&mut self) -> &(Any + Send) { + fn get(&mut self) -> &(dyn Any + Send) { match self.inner { Some(ref a) => a, None => &(), @@ -441,7 +441,7 @@ pub fn begin_panic<M: Any + Send>(msg: M, file_line_col: &(&'static str, u32, u3 /// Executes the primary logic for a panic, including checking for recursive /// panics, panic hooks, and finally dispatching to the panic runtime to either /// abort or unwind. -fn rust_panic_with_hook(payload: &mut BoxMeUp, +fn rust_panic_with_hook(payload: &mut dyn BoxMeUp, message: Option<&fmt::Arguments>, file_line_col: &(&str, u32, u32)) -> ! { let (file, line, col) = *file_line_col; @@ -496,17 +496,17 @@ fn rust_panic_with_hook(payload: &mut BoxMeUp, } /// Shim around rust_panic. Called by resume_unwind. -pub fn update_count_then_panic(msg: Box<Any + Send>) -> ! { +pub fn update_count_then_panic(msg: Box<dyn Any + Send>) -> ! { update_panic_count(1); - struct RewrapBox(Box<Any + Send>); + struct RewrapBox(Box<dyn Any + Send>); unsafe impl BoxMeUp for RewrapBox { - fn box_me_up(&mut self) -> *mut (Any + Send) { + fn box_me_up(&mut self) -> *mut (dyn Any + Send) { Box::into_raw(mem::replace(&mut self.0, Box::new(()))) } - fn get(&mut self) -> &(Any + Send) { + fn get(&mut self) -> &(dyn Any + Send) { &*self.0 } } @@ -517,9 +517,9 @@ pub fn update_count_then_panic(msg: Box<Any + Send>) -> ! { /// A private no-mangle function on which to slap yer breakpoints. #[no_mangle] #[allow(private_no_mangle_fns)] // yes we get it, but we like breakpoints -pub fn rust_panic(mut msg: &mut BoxMeUp) -> ! { +pub fn rust_panic(mut msg: &mut dyn BoxMeUp) -> ! { let code = unsafe { - let obj = &mut msg as *mut &mut BoxMeUp; + let obj = &mut msg as *mut &mut dyn BoxMeUp; __rust_start_panic(obj as usize) }; rtabort!("failed to initiate panic, error {}", code) diff --git a/src/libstd/process.rs b/src/libstd/process.rs index 00051d4487a..39692836866 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -813,13 +813,13 @@ impl fmt::Debug for Output { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { let stdout_utf8 = str::from_utf8(&self.stdout); - let stdout_debug: &fmt::Debug = match stdout_utf8 { + let stdout_debug: &dyn fmt::Debug = match stdout_utf8 { Ok(ref str) => str, Err(_) => &self.stdout }; let stderr_utf8 = str::from_utf8(&self.stderr); - let stderr_debug: &fmt::Debug = match stderr_utf8 { + let stderr_debug: &dyn fmt::Debug = match stderr_utf8 { Ok(ref str) => str, Err(_) => &self.stderr }; diff --git a/src/libstd/rt.rs b/src/libstd/rt.rs index 8f945470b7e..9e957bd87d7 100644 --- a/src/libstd/rt.rs +++ b/src/libstd/rt.rs @@ -29,7 +29,7 @@ pub use panicking::{begin_panic, begin_panic_fmt, update_panic_count}; // To reduce the generated code of the new `lang_start`, this function is doing // the real work. #[cfg(not(test))] -fn lang_start_internal(main: &(Fn() -> i32 + Sync + ::panic::RefUnwindSafe), +fn lang_start_internal(main: &(dyn Fn() -> i32 + Sync + ::panic::RefUnwindSafe), argc: isize, argv: *const *const u8) -> isize { use panic; use sys; diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs index cbda5afadcd..02a96b01cca 100644 --- a/src/libstd/sync/mpsc/mod.rs +++ b/src/libstd/sync/mpsc/mod.rs @@ -1638,7 +1638,7 @@ impl<T: Send> error::Error for SendError<T> { "sending on a closed channel" } - fn cause(&self) -> Option<&error::Error> { + fn cause(&self) -> Option<&dyn error::Error> { None } } @@ -1681,7 +1681,7 @@ impl<T: Send> error::Error for TrySendError<T> { } } - fn cause(&self) -> Option<&error::Error> { + fn cause(&self) -> Option<&dyn error::Error> { None } } @@ -1709,7 +1709,7 @@ impl error::Error for RecvError { "receiving on a closed channel" } - fn cause(&self) -> Option<&error::Error> { + fn cause(&self) -> Option<&dyn error::Error> { None } } @@ -1742,7 +1742,7 @@ impl error::Error for TryRecvError { } } - fn cause(&self) -> Option<&error::Error> { + fn cause(&self) -> Option<&dyn error::Error> { None } } @@ -1783,7 +1783,7 @@ impl error::Error for RecvTimeoutError { } } - fn cause(&self) -> Option<&error::Error> { + fn cause(&self) -> Option<&dyn error::Error> { None } } diff --git a/src/libstd/sync/mpsc/select.rs b/src/libstd/sync/mpsc/select.rs index 9310dad9172..a7a284cfb79 100644 --- a/src/libstd/sync/mpsc/select.rs +++ b/src/libstd/sync/mpsc/select.rs @@ -93,7 +93,7 @@ pub struct Handle<'rx, T:Send+'rx> { next: *mut Handle<'static, ()>, prev: *mut Handle<'static, ()>, added: bool, - packet: &'rx (Packet+'rx), + packet: &'rx (dyn Packet+'rx), // due to our fun transmutes, we be sure to place this at the end. (nothing // previous relies on T) diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs index 443e2a6980d..10282ecb658 100644 --- a/src/libstd/sync/once.rs +++ b/src/libstd/sync/once.rs @@ -309,7 +309,7 @@ impl Once { #[cold] fn call_inner(&self, ignore_poisoning: bool, - init: &mut FnMut(bool)) { + init: &mut dyn FnMut(bool)) { let mut state = self.state.load(Ordering::SeqCst); 'outer: loop { diff --git a/src/libstd/sys/cloudabi/thread.rs b/src/libstd/sys/cloudabi/thread.rs index 5d66936b2a4..8cca47efd22 100644 --- a/src/libstd/sys/cloudabi/thread.rs +++ b/src/libstd/sys/cloudabi/thread.rs @@ -32,7 +32,7 @@ unsafe impl Send for Thread {} unsafe impl Sync for Thread {} impl Thread { - pub unsafe fn new<'a>(stack: usize, p: Box<FnBox() + 'a>) -> io::Result<Thread> { + pub unsafe fn new<'a>(stack: usize, p: Box<dyn FnBox() + 'a>) -> io::Result<Thread> { let p = box p; let mut native: libc::pthread_t = mem::zeroed(); let mut attr: libc::pthread_attr_t = mem::zeroed(); diff --git a/src/libstd/sys/redox/process.rs b/src/libstd/sys/redox/process.rs index d0b94e14f54..02bc467541e 100644 --- a/src/libstd/sys/redox/process.rs +++ b/src/libstd/sys/redox/process.rs @@ -51,7 +51,7 @@ pub struct Command { uid: Option<u32>, gid: Option<u32>, saw_nul: bool, - closures: Vec<Box<FnMut() -> io::Result<()> + Send + Sync>>, + closures: Vec<Box<dyn FnMut() -> io::Result<()> + Send + Sync>>, stdin: Option<Stdio>, stdout: Option<Stdio>, stderr: Option<Stdio>, @@ -122,7 +122,7 @@ impl Command { } pub fn before_exec(&mut self, - f: Box<FnMut() -> io::Result<()> + Send + Sync>) { + f: Box<dyn FnMut() -> io::Result<()> + Send + Sync>) { self.closures.push(f); } diff --git a/src/libstd/sys/redox/thread.rs b/src/libstd/sys/redox/thread.rs index 110d46ca3ab..f4177087d77 100644 --- a/src/libstd/sys/redox/thread.rs +++ b/src/libstd/sys/redox/thread.rs @@ -28,7 +28,7 @@ unsafe impl Send for Thread {} unsafe impl Sync for Thread {} impl Thread { - pub unsafe fn new<'a>(_stack: usize, p: Box<FnBox() + 'a>) -> io::Result<Thread> { + pub unsafe fn new<'a>(_stack: usize, p: Box<dyn FnBox() + 'a>) -> io::Result<Thread> { let p = box p; let id = cvt(syscall::clone(syscall::CLONE_VM | syscall::CLONE_FS | syscall::CLONE_FILES))?; diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs index 6396bb3a49e..77f125f3c5b 100644 --- a/src/libstd/sys/unix/process/process_common.rs +++ b/src/libstd/sys/unix/process/process_common.rs @@ -52,7 +52,7 @@ pub struct Command { uid: Option<uid_t>, gid: Option<gid_t>, saw_nul: bool, - closures: Vec<Box<FnMut() -> io::Result<()> + Send + Sync>>, + closures: Vec<Box<dyn FnMut() -> io::Result<()> + Send + Sync>>, stdin: Option<Stdio>, stdout: Option<Stdio>, stderr: Option<Stdio>, @@ -155,12 +155,12 @@ impl Command { self.gid } - pub fn get_closures(&mut self) -> &mut Vec<Box<FnMut() -> io::Result<()> + Send + Sync>> { + pub fn get_closures(&mut self) -> &mut Vec<Box<dyn FnMut() -> io::Result<()> + Send + Sync>> { &mut self.closures } pub fn before_exec(&mut self, - f: Box<FnMut() -> io::Result<()> + Send + Sync>) { + f: Box<dyn FnMut() -> io::Result<()> + Send + Sync>) { self.closures.push(f); } diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 7fdecc9c0c0..e26306c045d 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -49,7 +49,7 @@ unsafe fn pthread_attr_setstacksize(_attr: *mut libc::pthread_attr_t, } impl Thread { - pub unsafe fn new<'a>(stack: usize, p: Box<FnBox() + 'a>) + pub unsafe fn new<'a>(stack: usize, p: Box<dyn FnBox() + 'a>) -> io::Result<Thread> { let p = box p; let mut native: libc::pthread_t = mem::zeroed(); diff --git a/src/libstd/sys/wasm/thread.rs b/src/libstd/sys/wasm/thread.rs index 728e678a2e8..8173a624211 100644 --- a/src/libstd/sys/wasm/thread.rs +++ b/src/libstd/sys/wasm/thread.rs @@ -19,7 +19,7 @@ pub struct Thread(Void); pub const DEFAULT_MIN_STACK_SIZE: usize = 4096; impl Thread { - pub unsafe fn new<'a>(_stack: usize, _p: Box<FnBox() + 'a>) + pub unsafe fn new<'a>(_stack: usize, _p: Box<dyn FnBox() + 'a>) -> io::Result<Thread> { unsupported() diff --git a/src/libstd/sys/windows/thread.rs b/src/libstd/sys/windows/thread.rs index b6f63303dc2..44ec872b244 100644 --- a/src/libstd/sys/windows/thread.rs +++ b/src/libstd/sys/windows/thread.rs @@ -28,7 +28,7 @@ pub struct Thread { } impl Thread { - pub unsafe fn new<'a>(stack: usize, p: Box<FnBox() + 'a>) + pub unsafe fn new<'a>(stack: usize, p: Box<dyn FnBox() + 'a>) -> io::Result<Thread> { let p = box p; diff --git a/src/libstd/sys_common/at_exit_imp.rs b/src/libstd/sys_common/at_exit_imp.rs index d268d9ad6f9..b28a4d2f8be 100644 --- a/src/libstd/sys_common/at_exit_imp.rs +++ b/src/libstd/sys_common/at_exit_imp.rs @@ -17,7 +17,7 @@ use ptr; use mem; use sys_common::mutex::Mutex; -type Queue = Vec<Box<FnBox()>>; +type Queue = Vec<Box<dyn FnBox()>>; // NB these are specifically not types from `std::sync` as they currently rely // on poisoning and this module needs to operate at a lower level than requiring @@ -68,7 +68,7 @@ pub fn cleanup() { } } -pub fn push(f: Box<FnBox()>) -> bool { +pub fn push(f: Box<dyn FnBox()>) -> bool { unsafe { let _guard = LOCK.lock(); if init() { diff --git a/src/libstd/sys_common/backtrace.rs b/src/libstd/sys_common/backtrace.rs index 2db47bd5947..77371782977 100644 --- a/src/libstd/sys_common/backtrace.rs +++ b/src/libstd/sys_common/backtrace.rs @@ -49,7 +49,7 @@ pub struct Frame { const MAX_NB_FRAMES: usize = 100; /// Prints the current backtrace. -pub fn print(w: &mut Write, format: PrintFormat) -> io::Result<()> { +pub fn print(w: &mut dyn Write, format: PrintFormat) -> io::Result<()> { static LOCK: Mutex = Mutex::new(); // Use a lock to prevent mixed output in multithreading context. @@ -62,7 +62,7 @@ pub fn print(w: &mut Write, format: PrintFormat) -> io::Result<()> { } } -fn _print(w: &mut Write, format: PrintFormat) -> io::Result<()> { +fn _print(w: &mut dyn Write, format: PrintFormat) -> io::Result<()> { let mut frames = [Frame { exact_position: ptr::null(), symbol_addr: ptr::null(), @@ -176,7 +176,7 @@ pub fn log_enabled() -> Option<PrintFormat> { /// /// These output functions should now be used everywhere to ensure consistency. /// You may want to also use `output_fileline`. -fn output(w: &mut Write, idx: usize, frame: Frame, +fn output(w: &mut dyn Write, idx: usize, frame: Frame, s: Option<&str>, format: PrintFormat) -> io::Result<()> { // Remove the `17: 0x0 - <unknown>` line. if format == PrintFormat::Short && frame.exact_position == ptr::null() { @@ -201,7 +201,7 @@ fn output(w: &mut Write, idx: usize, frame: Frame, /// /// See also `output`. #[allow(dead_code)] -fn output_fileline(w: &mut Write, +fn output_fileline(w: &mut dyn Write, file: &[u8], line: u32, format: PrintFormat) -> io::Result<()> { @@ -253,7 +253,7 @@ fn output_fileline(w: &mut Write, // Note that this demangler isn't quite as fancy as it could be. We have lots // of other information in our symbols like hashes, version, type information, // etc. Additionally, this doesn't handle glue symbols at all. -pub fn demangle(writer: &mut Write, mut s: &str, format: PrintFormat) -> io::Result<()> { +pub fn demangle(writer: &mut dyn Write, mut s: &str, format: PrintFormat) -> io::Result<()> { // During ThinLTO LLVM may import and rename internal symbols, so strip out // those endings first as they're one of the last manglings applied to // symbol names. diff --git a/src/libstd/sys_common/poison.rs b/src/libstd/sys_common/poison.rs index e74c40ae04b..1625efe4a2a 100644 --- a/src/libstd/sys_common/poison.rs +++ b/src/libstd/sys_common/poison.rs @@ -251,7 +251,7 @@ impl<T> Error for TryLockError<T> { } } - fn cause(&self) -> Option<&Error> { + fn cause(&self) -> Option<&dyn Error> { match *self { TryLockError::Poisoned(ref p) => Some(p), _ => None diff --git a/src/libstd/sys_common/thread.rs b/src/libstd/sys_common/thread.rs index da6f58ef6bb..86a5e2b8694 100644 --- a/src/libstd/sys_common/thread.rs +++ b/src/libstd/sys_common/thread.rs @@ -21,7 +21,7 @@ pub unsafe fn start_thread(main: *mut u8) { let _handler = stack_overflow::Handler::new(); // Finally, let's run some code. - Box::from_raw(main as *mut Box<FnBox()>)() + Box::from_raw(main as *mut Box<dyn FnBox()>)() } pub fn min_stack() -> usize { diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 90f054186d1..ae804ad409e 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -1175,7 +1175,7 @@ impl fmt::Debug for Thread { /// /// [`Result`]: ../../std/result/enum.Result.html #[stable(feature = "rust1", since = "1.0.0")] -pub type Result<T> = ::result::Result<T, Box<Any + Send + 'static>>; +pub type Result<T> = ::result::Result<T, Box<dyn Any + Send + 'static>>; // This packet is used to communicate the return value between the child thread // and the parent thread. Memory is shared through the `Arc` within and there's @@ -1276,6 +1276,11 @@ impl<T> JoinInner<T> { #[stable(feature = "rust1", since = "1.0.0")] pub struct JoinHandle<T>(JoinInner<T>); +#[stable(feature = "joinhandle_impl_send_sync", since = "1.29.0")] +unsafe impl<T> Send for JoinHandle<T> {} +#[stable(feature = "joinhandle_impl_send_sync", since = "1.29.0")] +unsafe impl<T> Sync for JoinHandle<T> {} + impl<T> JoinHandle<T> { /// Extracts a handle to the underlying thread. /// @@ -1438,7 +1443,7 @@ mod tests { rx.recv().unwrap(); } - fn avoid_copying_the_body<F>(spawnfn: F) where F: FnOnce(Box<Fn() + Send>) { + fn avoid_copying_the_body<F>(spawnfn: F) where F: FnOnce(Box<dyn Fn() + Send>) { let (tx, rx) = channel(); let x: Box<_> = box 1; @@ -1485,7 +1490,7 @@ mod tests { // (well, it would if the constant were 8000+ - I lowered it to be more // valgrind-friendly. try this at home, instead..!) const GENERATIONS: u32 = 16; - fn child_no(x: u32) -> Box<Fn() + Send> { + fn child_no(x: u32) -> Box<dyn Fn() + Send> { return Box::new(move|| { if x < GENERATIONS { thread::spawn(move|| child_no(x+1)()); @@ -1531,10 +1536,10 @@ mod tests { #[test] fn test_try_panic_message_any() { match thread::spawn(move|| { - panic!(box 413u16 as Box<Any + Send>); + panic!(box 413u16 as Box<dyn Any + Send>); }).join() { Err(e) => { - type T = Box<Any + Send>; + type T = Box<dyn Any + Send>; assert!(e.is::<T>()); let any = e.downcast::<T>().unwrap(); assert!(any.is::<u16>()); diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index d746ac3c577..137b94230a3 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -22,11 +22,11 @@ pub use self::ReprAttr::*; pub use self::StabilityLevel::*; use ast; -use ast::{AttrId, Attribute, Name, Ident, Path, PathSegment}; +use ast::{AttrId, Attribute, AttrStyle, Name, Ident, Path, PathSegment}; use ast::{MetaItem, MetaItemKind, NestedMetaItem, NestedMetaItemKind}; use ast::{Lit, LitKind, Expr, ExprKind, Item, Local, Stmt, StmtKind, GenericParam}; use codemap::{BytePos, Spanned, respan, dummy_spanned}; -use syntax_pos::Span; +use syntax_pos::{FileName, Span}; use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration}; use parse::parser::Parser; use parse::{self, ParseSess, PResult}; @@ -821,3 +821,33 @@ derive_has_attrs! { Item, Expr, Local, ast::ForeignItem, ast::StructField, ast::ImplItem, ast::TraitItem, ast::Arm, ast::Field, ast::FieldPat, ast::Variant_ } + +pub fn inject(mut krate: ast::Crate, parse_sess: &ParseSess, attrs: &[String]) -> ast::Crate { + for raw_attr in attrs { + let mut parser = parse::new_parser_from_source_str( + parse_sess, + FileName::CliCrateAttr, + raw_attr.clone(), + ); + + let start_span = parser.span; + let (path, tokens) = panictry!(parser.parse_path_and_tokens()); + let end_span = parser.span; + if parser.token != token::Eof { + parse_sess.span_diagnostic + .span_err(start_span.to(end_span), "invalid crate attribute"); + continue; + } + + krate.attrs.push(Attribute { + id: mk_attr_id(), + style: AttrStyle::Inner, + path, + tokens, + is_sugared_doc: false, + span: start_span.to(end_span), + }); + } + + krate +} diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 30137439e77..087fec09719 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -396,6 +396,9 @@ declare_features! ( // Infer outlives requirements; RFC 2093 (active, infer_outlives_requirements, "1.26.0", Some(44493), None), + // Infer outlives requirements; RFC 2093 + (active, infer_static_outlives_requirements, "1.26.0", Some(44493), None), + // Multiple patterns with `|` in `if let` and `while let` (active, if_while_or_patterns, "1.26.0", Some(48215), None), @@ -1057,6 +1060,12 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG "infer outlives requirements is an experimental feature", cfg_fn!(infer_outlives_requirements))), + // RFC #2093 + ("infer_static_outlives_requirements", Normal, Gated(Stability::Unstable, + "infer_static_outlives_requirements", + "infer 'static lifetime requirements", + cfg_fn!(infer_static_outlives_requirements))), + // RFC 2070 ("panic_implementation", Normal, Gated(Stability::Unstable, "panic_implementation", diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index d241ae1d442..60de94821bb 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -14,8 +14,6 @@ //! //! This API is completely unstable and subject to change. -#![deny(bare_trait_objects)] - #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/", diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 64309dd9b8b..56760546c50 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -6514,6 +6514,39 @@ impl<'a> Parser<'a> { }) } + fn parse_crate_name_with_dashes(&mut self) -> PResult<'a, ast::Ident> { + let error_msg = "crate name using dashes are not valid in `extern crate` statements"; + let suggestion_msg = "if the original crate name uses dashes you need to use underscores \ + in the code"; + let mut ident = self.parse_ident()?; + let mut idents = vec![]; + let mut replacement = vec![]; + let mut fixed_crate_name = false; + // Accept `extern crate name-like-this` for better diagnostics + let dash = token::Token::BinOp(token::BinOpToken::Minus); + if self.token == dash { // Do not include `-` as part of the expected tokens list + while self.eat(&dash) { + fixed_crate_name = true; + replacement.push((self.prev_span, "_".to_string())); + idents.push(self.parse_ident()?); + } + } + if fixed_crate_name { + let fixed_name_sp = ident.span.to(idents.last().unwrap().span); + let mut fixed_name = format!("{}", ident.name); + for part in idents { + fixed_name.push_str(&format!("_{}", part.name)); + } + ident = Ident::from_str(&fixed_name).with_span_pos(fixed_name_sp); + + let mut err = self.struct_span_err(fixed_name_sp, error_msg); + err.span_label(fixed_name_sp, "dash-separated idents are not valid"); + err.multipart_suggestion(suggestion_msg, replacement); + err.emit(); + } + Ok(ident) + } + /// Parse extern crate links /// /// # Examples @@ -6525,7 +6558,8 @@ impl<'a> Parser<'a> { visibility: Visibility, attrs: Vec<Attribute>) -> PResult<'a, P<Item>> { - let orig_name = self.parse_ident()?; + // Accept `extern crate name-like-this` for better diagnostics + let orig_name = self.parse_crate_name_with_dashes()?; let (item_name, orig_name) = if let Some(rename) = self.parse_rename()? { (rename, Some(orig_name.name)) } else { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 0ef390beac9..08c9ec4c989 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -3065,7 +3065,7 @@ impl<'a> State<'a> { unsafety: ast::Unsafety, decl: &ast::FnDecl, name: Option<ast::Ident>, - generic_params: &Vec<ast::GenericParam>) + generic_params: &[ast::GenericParam]) -> io::Result<()> { self.ibox(INDENT_UNIT)?; if !generic_params.is_empty() { diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs index ff76e788b3c..f0d33835cd0 100644 --- a/src/libsyntax_ext/lib.rs +++ b/src/libsyntax_ext/lib.rs @@ -10,8 +10,6 @@ //! Syntax extensions in the Rust compiler. -#![deny(bare_trait_objects)] - #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index cc09a944e4c..44cd53282ec 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -14,8 +14,6 @@ //! //! This API is completely unstable and subject to change. -#![deny(bare_trait_objects)] - #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] @@ -100,6 +98,8 @@ pub enum FileName { ProcMacroSourceCode, /// Strings provided as --cfg [cfgspec] stored in a crate_cfg CfgSpec, + /// Strings provided as crate attributes in the CLI + CliCrateAttr, /// Custom sources for explicit parser calls from plugins and drivers Custom(String), } @@ -115,6 +115,7 @@ impl std::fmt::Display for FileName { Anon => write!(fmt, "<anon>"), ProcMacroSourceCode => write!(fmt, "<proc-macro source code>"), CfgSpec => write!(fmt, "cfgspec"), + CliCrateAttr => write!(fmt, "<crate attribute>"), Custom(ref s) => write!(fmt, "<{}>", s), } } @@ -137,6 +138,7 @@ impl FileName { MacroExpansion | ProcMacroSourceCode | CfgSpec | + CliCrateAttr | Custom(_) | QuoteExpansion => false, } @@ -150,6 +152,7 @@ impl FileName { MacroExpansion | ProcMacroSourceCode | CfgSpec | + CliCrateAttr | Custom(_) | QuoteExpansion => false, Macros(_) => true, @@ -634,15 +637,14 @@ impl MultiSpan { /// `SpanLabel` instances with empty labels. pub fn span_labels(&self) -> Vec<SpanLabel> { let is_primary = |span| self.primary_spans.contains(&span); - let mut span_labels = vec![]; - for &(span, ref label) in &self.span_labels { - span_labels.push(SpanLabel { + let mut span_labels = self.span_labels.iter().map(|&(span, ref label)| + SpanLabel { span, is_primary: is_primary(span), label: Some(label.clone()) - }); - } + } + ).collect::<Vec<_>>(); for &span in &self.primary_spans { if !span_labels.iter().any(|sl| sl.span == span) { diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs index a012f4e776f..cf92ce27ee5 100644 --- a/src/libterm/lib.rs +++ b/src/libterm/lib.rs @@ -66,9 +66,9 @@ pub mod terminfo; mod win; /// Alias for stdout terminals. -pub type StdoutTerminal = Terminal<Output = Stdout> + Send; +pub type StdoutTerminal = dyn Terminal<Output = Stdout> + Send; /// Alias for stderr terminals. -pub type StderrTerminal = Terminal<Output = Stderr> + Send; +pub type StderrTerminal = dyn Terminal<Output = Stderr> + Send; #[cfg(not(windows))] /// Return a Terminal wrapping stdout, or None if a terminal couldn't be diff --git a/src/libterm/terminfo/mod.rs b/src/libterm/terminfo/mod.rs index c5e68eed407..51e0fa315f4 100644 --- a/src/libterm/terminfo/mod.rs +++ b/src/libterm/terminfo/mod.rs @@ -58,7 +58,7 @@ impl error::Error for Error { "failed to create TermInfo" } - fn cause(&self) -> Option<&error::Error> { + fn cause(&self) -> Option<&dyn error::Error> { use self::Error::*; match self { &IoError(ref e) => Some(e), diff --git a/src/libterm/terminfo/parser/compiled.rs b/src/libterm/terminfo/parser/compiled.rs index 0cdea64db8b..d5e5df54733 100644 --- a/src/libterm/terminfo/parser/compiled.rs +++ b/src/libterm/terminfo/parser/compiled.rs @@ -164,7 +164,7 @@ pub static stringnames: &'static[&'static str] = &[ "cbt", "_", "cr", "csr", "tb "OTG3", "OTG1", "OTG4", "OTGR", "OTGL", "OTGU", "OTGD", "OTGH", "OTGV", "OTGC", "meml", "memu", "box1"]; -fn read_le_u16(r: &mut io::Read) -> io::Result<u16> { +fn read_le_u16(r: &mut dyn io::Read) -> io::Result<u16> { let mut b = [0; 2]; let mut amt = 0; while amt < b.len() { @@ -176,7 +176,7 @@ fn read_le_u16(r: &mut io::Read) -> io::Result<u16> { Ok((b[0] as u16) | ((b[1] as u16) << 8)) } -fn read_byte(r: &mut io::Read) -> io::Result<u8> { +fn read_byte(r: &mut dyn io::Read) -> io::Result<u8> { match r.bytes().next() { Some(s) => s, None => Err(io::Error::new(io::ErrorKind::Other, "end of file")), @@ -185,7 +185,7 @@ fn read_byte(r: &mut io::Read) -> io::Result<u8> { /// Parse a compiled terminfo entry, using long capability names if `longnames` /// is true -pub fn parse(file: &mut io::Read, longnames: bool) -> Result<TermInfo, String> { +pub fn parse(file: &mut dyn io::Read, longnames: bool) -> Result<TermInfo, String> { macro_rules! t( ($e:expr) => ( match $e { Ok(e) => e, diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 9f670de4f5b..ed5b5565d89 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -27,8 +27,6 @@ // this crate, which relies on this attribute (rather than the value of `--crate-name` passed by // cargo) to detect this crate. -#![deny(bare_trait_objects)] - #![crate_name = "test"] #![unstable(feature = "test", issue = "27812")] #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", diff --git a/src/libunwind/lib.rs b/src/libunwind/lib.rs index ea5eee3cc7d..2b3c19c067e 100644 --- a/src/libunwind/lib.rs +++ b/src/libunwind/lib.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![deny(bare_trait_objects)] - #![no_std] #![unstable(feature = "panic_unwind", issue = "32837")] diff --git a/src/stage0.txt b/src/stage0.txt index f2c0e9e3b2a..aa6339c8522 100644 --- a/src/stage0.txt +++ b/src/stage0.txt @@ -12,7 +12,7 @@ # source tarball for a stable release you'll likely see `1.x.0` for rustc and # `0.x.0` for Cargo where they were released on `date`. -date: 2018-07-13 +date: 2018-07-27 rustc: beta cargo: beta diff --git a/src/test/compile-fail/specialization/issue-52050.rs b/src/test/compile-fail/specialization/issue-52050.rs new file mode 100644 index 00000000000..70cdb4899c4 --- /dev/null +++ b/src/test/compile-fail/specialization/issue-52050.rs @@ -0,0 +1,42 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(specialization)] + +// Regression test for #52050: when inserting the blanket impl `I` +// into the tree, we had to replace the child node for `Foo`, which +// led to the struture of the tree being messed up. + +use std::iter::Iterator; + +trait IntoPyDictPointer { } + +struct Foo { } + +impl Iterator for Foo { + type Item = (); + fn next(&mut self) -> Option<()> { + None + } +} + +impl IntoPyDictPointer for Foo { } + +impl<I> IntoPyDictPointer for I +where + I: Iterator, +{ +} + +impl IntoPyDictPointer for () //~ ERROR conflicting implementations +{ +} + +fn main() { } diff --git a/src/test/run-pass/z-crate-attr.rs b/src/test/run-pass/z-crate-attr.rs new file mode 100644 index 00000000000..3df0985a2a3 --- /dev/null +++ b/src/test/run-pass/z-crate-attr.rs @@ -0,0 +1,21 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// This test checks if an unstable feature is enabled with the -Zcrate-attr=feature(foo) flag. If +// the exact feature used here is causing problems feel free to replace it with another +// perma-unstable feature. + +// compile-flags: -Zcrate-attr=feature(abi_unadjusted) + +#![allow(dead_code)] + +extern "unadjusted" fn foo() {} + +fn main() {} diff --git a/src/test/rustdoc/generic-impl.rs b/src/test/rustdoc/generic-impl.rs new file mode 100644 index 00000000000..e2665fd8f37 --- /dev/null +++ b/src/test/rustdoc/generic-impl.rs @@ -0,0 +1,25 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_name = "foo"] + +use std::fmt; + +// @!has foo/struct.Bar.html '//h3[@id="impl-ToString"]//code' 'impl<T> ToString for T' +pub struct Bar; + +// @has foo/struct.Foo.html '//h3[@id="impl-ToString"]//code' 'impl<T> ToString for T' +pub struct Foo; + +impl fmt::Display for Foo { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Foo") + } +} diff --git a/src/test/rustdoc/manual_impl.rs b/src/test/rustdoc/manual_impl.rs index befd3161ac4..54a8a764833 100644 --- a/src/test/rustdoc/manual_impl.rs +++ b/src/test/rustdoc/manual_impl.rs @@ -56,7 +56,6 @@ impl T for S1 { // @!has - '//*[@class="docblock"]' 'Docs associated with the trait a_method definition.' // @!has - '//*[@class="docblock"]' 'Docs associated with the trait c_method definition.' // @has - '//*[@class="docblock"]' 'Docs associated with the trait b_method definition.' -// @!has - '//*[@class="docblock"]' 'Read more' pub struct S2(usize); /// Docs associated with the S2 trait implementation. diff --git a/src/test/rustdoc/sidebar-items.rs b/src/test/rustdoc/sidebar-items.rs index 9be40441e9d..3ecd6b63510 100644 --- a/src/test/rustdoc/sidebar-items.rs +++ b/src/test/rustdoc/sidebar-items.rs @@ -31,11 +31,11 @@ pub trait Foo { // @has - '//*[@class="sidebar-title"][@href="#fields"]' 'Fields' // @has - '//*[@class="sidebar-links"]/a[@href="#structfield.f"]' 'f' // @has - '//*[@class="sidebar-links"]/a[@href="#structfield.u"]' 'u' -// @!has - '//*[@class="sidebar-links"]/a' 'w' +// @!has - '//*[@class="sidebar-links"]/a' 'waza' pub struct Bar { pub f: u32, pub u: u32, - w: u32, + waza: u32, } // @has foo/enum.En.html @@ -51,9 +51,9 @@ pub enum En { // @has - '//*[@class="sidebar-title"][@href="#fields"]' 'Fields' // @has - '//*[@class="sidebar-links"]/a[@href="#structfield.f1"]' 'f1' // @has - '//*[@class="sidebar-links"]/a[@href="#structfield.f2"]' 'f2' -// @!has - '//*[@class="sidebar-links"]/a' 'w' +// @!has - '//*[@class="sidebar-links"]/a' 'waza' pub union MyUnion { pub f1: u32, pub f2: f32, - w: u32, + waza: u32, } diff --git a/src/test/ui/bad-crate-name.rs b/src/test/ui/bad-crate-name.rs new file mode 100644 index 00000000000..70e1806a20b --- /dev/null +++ b/src/test/ui/bad-crate-name.rs @@ -0,0 +1,15 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +extern crate krate-name-here; +//~^ ERROR crate name using dashes are not valid in `extern crate` statements +//~| ERROR can't find crate for `krate_name_here` + +fn main() {} diff --git a/src/test/ui/bad-crate-name.stderr b/src/test/ui/bad-crate-name.stderr new file mode 100644 index 00000000000..8348badeeeb --- /dev/null +++ b/src/test/ui/bad-crate-name.stderr @@ -0,0 +1,19 @@ +error: crate name using dashes are not valid in `extern crate` statements + --> $DIR/bad-crate-name.rs:11:14 + | +LL | extern crate krate-name-here; + | ^^^^^^^^^^^^^^^ dash-separated idents are not valid +help: if the original crate name uses dashes you need to use underscores in the code + | +LL | extern crate krate_name_here; + | ^ ^ + +error[E0463]: can't find crate for `krate_name_here` + --> $DIR/bad-crate-name.rs:11:1 + | +LL | extern crate krate-name-here; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0463`. diff --git a/src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.edition.stderr b/src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.edition.stderr new file mode 100644 index 00000000000..fa82efa3533 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.edition.stderr @@ -0,0 +1,9 @@ +error[E0507]: cannot move out of borrowed content + --> $DIR/borrowck-feature-nll-overrides-migrate.rs:32:17 + | +LL | (|| { let bar = foo; bar.take() })(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0507`. diff --git a/src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.rs b/src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.rs new file mode 100644 index 00000000000..72043938f53 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.rs @@ -0,0 +1,40 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// This is a test that the `#![feature(nll)]` opt-in overrides the +// migration mode. The intention here is to emulate the goal behavior +// that `--edition 2018` effects on borrowck (modeled here by `-Z +// borrowck=migrate`) are themselves overridden by the +// `#![feature(nll)]` opt-in. +// +// Therefore, for developer convenience, under `#[feature(nll)]` the +// NLL checks will be emitted as errors *even* in the presence of `-Z +// borrowck=migrate`. + +// revisions: zflag edition +// [zflag]compile-flags: -Z borrowck=migrate +// [edition]compile-flags: --edition 2018 + +#![feature(nll)] + +fn main() { + match Some(&4) { + None => {}, + ref mut foo + if { + (|| { let bar = foo; bar.take() })(); + //[zflag]~^ ERROR cannot move out of borrowed content [E0507] + //[edition]~^^ ERROR cannot move out of borrowed content [E0507] + false + } => {}, + Some(ref _s) => println!("Note this arm is bogus; the `Some` became `None` in the guard."), + _ => println!("Here is some supposedly unreachable code."), + } +} diff --git a/src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.zflag.stderr b/src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.zflag.stderr new file mode 100644 index 00000000000..fa82efa3533 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.zflag.stderr @@ -0,0 +1,9 @@ +error[E0507]: cannot move out of borrowed content + --> $DIR/borrowck-feature-nll-overrides-migrate.rs:32:17 + | +LL | (|| { let bar = foo; bar.take() })(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0507`. diff --git a/src/test/ui/borrowck/borrowck-migrate-to-nll.edition.stderr b/src/test/ui/borrowck/borrowck-migrate-to-nll.edition.stderr new file mode 100644 index 00000000000..f5a9db36406 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-migrate-to-nll.edition.stderr @@ -0,0 +1,24 @@ +warning[E0507]: cannot move out of borrowed content + --> $DIR/borrowck-migrate-to-nll.rs:35:17 + | +LL | (|| { let bar = foo; bar.take() })(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content + | + = warning: This error has been downgraded to a warning for backwards compatibility with previous releases. + It represents potential unsoundness in your code. + This warning will become a hard error in the future. + +warning[E0507]: cannot move out of `foo`, as it is immutable for the pattern guard + --> $DIR/borrowck-migrate-to-nll.rs:35:17 + | +LL | (|| { let bar = foo; bar.take() })(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | cannot move out of `foo`, as it is immutable for the pattern guard + | cannot move + | + = note: variables bound in patterns are immutable until the end of the pattern guard + = warning: This error has been downgraded to a warning for backwards compatibility with previous releases. + It represents potential unsoundness in your code. + This warning will become a hard error in the future. + diff --git a/src/test/ui/borrowck/borrowck-migrate-to-nll.rs b/src/test/ui/borrowck/borrowck-migrate-to-nll.rs new file mode 100644 index 00000000000..e7f2bfbfedb --- /dev/null +++ b/src/test/ui/borrowck/borrowck-migrate-to-nll.rs @@ -0,0 +1,41 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// This is a test of the borrowck migrate mode. It leverages #27282, a +// bug that is fixed by NLL: this code is (unsoundly) accepted by +// AST-borrowck, but is correctly rejected by the NLL borrowck. +// +// Therefore, for backwards-compatiblity, under borrowck=migrate the +// NLL checks will be emitted as *warnings*. + +// NLL mode makes this compile-fail; we cannot currently encode a +// test that is run-pass or compile-fail based on compare-mode. So +// just ignore it instead: + +// ignore-compare-mode-nll + +// revisions: zflag edition +//[zflag]compile-flags: -Z borrowck=migrate +//[edition]compile-flags: --edition 2018 +//[zflag] run-pass +//[edition] run-pass + +fn main() { + match Some(&4) { + None => {}, + ref mut foo + if { + (|| { let bar = foo; bar.take() })(); + false + } => {}, + Some(ref _s) => println!("Note this arm is bogus; the `Some` became `None` in the guard."), + _ => println!("Here is some supposedly unreachable code."), + } +} diff --git a/src/test/ui/borrowck/borrowck-migrate-to-nll.zflag.stderr b/src/test/ui/borrowck/borrowck-migrate-to-nll.zflag.stderr new file mode 100644 index 00000000000..f5a9db36406 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-migrate-to-nll.zflag.stderr @@ -0,0 +1,24 @@ +warning[E0507]: cannot move out of borrowed content + --> $DIR/borrowck-migrate-to-nll.rs:35:17 + | +LL | (|| { let bar = foo; bar.take() })(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content + | + = warning: This error has been downgraded to a warning for backwards compatibility with previous releases. + It represents potential unsoundness in your code. + This warning will become a hard error in the future. + +warning[E0507]: cannot move out of `foo`, as it is immutable for the pattern guard + --> $DIR/borrowck-migrate-to-nll.rs:35:17 + | +LL | (|| { let bar = foo; bar.take() })(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | cannot move out of `foo`, as it is immutable for the pattern guard + | cannot move + | + = note: variables bound in patterns are immutable until the end of the pattern guard + = warning: This error has been downgraded to a warning for backwards compatibility with previous releases. + It represents potential unsoundness in your code. + This warning will become a hard error in the future. + diff --git a/src/test/ui/borrowck/issue-41962.stderr b/src/test/ui/borrowck/issue-41962.stderr index bd5d2a46fd8..4048243acfa 100644 --- a/src/test/ui/borrowck/issue-41962.stderr +++ b/src/test/ui/borrowck/issue-41962.stderr @@ -17,26 +17,22 @@ LL | if let Some(thing) = maybe { = note: move occurs because the value has type `std::vec::Vec<bool>`, which does not implement the `Copy` trait error[E0382]: use of moved value: `maybe` (Mir) - --> $DIR/issue-41962.rs:17:9 + --> $DIR/issue-41962.rs:17:30 | -LL | if let Some(thing) = maybe { - | ^ ----- value moved here - | _________| - | | -LL | | } - | |_________^ value used here after move +LL | if let Some(thing) = maybe { + | ----- ^^^^^ value used here after move + | | + | value moved here | = note: move occurs because value has type `std::vec::Vec<bool>`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `maybe` (Mir) - --> $DIR/issue-41962.rs:17:9 + --> $DIR/issue-41962.rs:17:30 | -LL | if let Some(thing) = maybe { - | ^ ----- value moved here - | _________| - | | -LL | | } - | |_________^ value borrowed here after move +LL | if let Some(thing) = maybe { + | ----- ^^^^^ value borrowed here after move + | | + | value moved here | = note: move occurs because value has type `std::vec::Vec<bool>`, which does not implement the `Copy` trait diff --git a/src/test/ui/borrowck/issue-51348-multi-ref-mut-in-guard.rs b/src/test/ui/borrowck/issue-51348-multi-ref-mut-in-guard.rs new file mode 100644 index 00000000000..c9d39fa360e --- /dev/null +++ b/src/test/ui/borrowck/issue-51348-multi-ref-mut-in-guard.rs @@ -0,0 +1,33 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// We used to ICE if you had a single match arm with multiple +// candidate patterns with `ref mut` identifiers used in the arm's +// guard. +// +// Also, this test expands on the original bug's example by actually +// trying to double check that we are matching against the right part +// of the input data based on which candidate pattern actually fired. + +// 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 } + _ => { 0 } + } +} + +fn main() { + assert_eq!(foo(&mut Ok((3, 4))), 3); + assert_eq!(foo(&mut Err((3, 4))), 4); +} diff --git a/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.nll.stderr b/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.nll.stderr index 9c7e3db67a6..0ac295c54bc 100644 --- a/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.nll.stderr +++ b/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.nll.stderr @@ -10,8 +10,8 @@ error: unsatisfied lifetime constraints LL | invoke(&x, |a, b| if a > b { a } else { b }); //~ ERROR E0495 | ----------^^^^^----------------- | | | | - | | | free region requires that `'1` must outlive `'2` - | | lifetime `'1` appears in this argument + | | | requires that `'1` must outlive `'2` + | | has type `&'1 i32` | lifetime `'2` appears in return type error: aborting due to previous error diff --git a/src/test/ui/feature-gate-infer_static_outlives_requirements.rs b/src/test/ui/feature-gate-infer_static_outlives_requirements.rs new file mode 100644 index 00000000000..7b68449859e --- /dev/null +++ b/src/test/ui/feature-gate-infer_static_outlives_requirements.rs @@ -0,0 +1,22 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Needs an explicit where clause stating outlives condition. (RFC 2093) + +// Type T needs to outlive lifetime 'static. +struct Foo<U> { + bar: Bar<U> //~ ERROR 15:5: 15:16: the parameter type `U` may not live long enough [E0310] +} +struct Bar<T: 'static> { + x: T, +} + + +fn main() { } diff --git a/src/test/ui/feature-gate-infer_static_outlives_requirements.stderr b/src/test/ui/feature-gate-infer_static_outlives_requirements.stderr new file mode 100644 index 00000000000..13022b901a7 --- /dev/null +++ b/src/test/ui/feature-gate-infer_static_outlives_requirements.stderr @@ -0,0 +1,17 @@ +error[E0310]: the parameter type `U` may not live long enough + --> $DIR/feature-gate-infer_static_outlives_requirements.rs:15:5 + | +LL | struct Foo<U> { + | - help: consider adding an explicit lifetime bound `U: 'static`... +LL | bar: Bar<U> //~ ERROR 15:5: 15:16: the parameter type `U` may not live long enough [E0310] + | ^^^^^^^^^^^ + | +note: ...so that the type `U` will meet its required lifetime bounds + --> $DIR/feature-gate-infer_static_outlives_requirements.rs:15:5 + | +LL | bar: Bar<U> //~ ERROR 15:5: 15:16: the parameter type `U` may not live long enough [E0310] + | ^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0310`. diff --git a/src/test/ui/generator/generator-with-nll.rs b/src/test/ui/generator/generator-with-nll.rs index 3223ff4dc8b..fdfe9e2c562 100644 --- a/src/test/ui/generator/generator-with-nll.rs +++ b/src/test/ui/generator/generator-with-nll.rs @@ -8,17 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: -Z borrowck=compare - #![feature(generators)] #![feature(nll)] fn main() { || { // The reference in `_a` is a Legal with NLL since it ends before the yield - let _a = &mut true; //~ ERROR borrow may still be in use when generator yields (Ast) - let b = &mut true; //~ ERROR borrow may still be in use when generator yields (Ast) - //~^ borrow may still be in use when generator yields (Mir) + let _a = &mut true; + let b = &mut true; + //~^ borrow may still be in use when generator yields yield (); println!("{}", b); }; diff --git a/src/test/ui/generator/generator-with-nll.stderr b/src/test/ui/generator/generator-with-nll.stderr index 7e39d3c5459..1dc663d8bcb 100644 --- a/src/test/ui/generator/generator-with-nll.stderr +++ b/src/test/ui/generator/generator-with-nll.stderr @@ -1,30 +1,12 @@ -error[E0626]: borrow may still be in use when generator yields (Ast) - --> $DIR/generator-with-nll.rs:19:23 +error[E0626]: borrow may still be in use when generator yields + --> $DIR/generator-with-nll.rs:18:17 | -LL | let _a = &mut true; //~ ERROR borrow may still be in use when generator yields (Ast) - | ^^^^ -... -LL | yield (); - | -------- possible yield occurs here - -error[E0626]: borrow may still be in use when generator yields (Ast) - --> $DIR/generator-with-nll.rs:20:22 - | -LL | let b = &mut true; //~ ERROR borrow may still be in use when generator yields (Ast) - | ^^^^ -LL | //~^ borrow may still be in use when generator yields (Mir) -LL | yield (); - | -------- possible yield occurs here - -error[E0626]: borrow may still be in use when generator yields (Mir) - --> $DIR/generator-with-nll.rs:20:17 - | -LL | let b = &mut true; //~ ERROR borrow may still be in use when generator yields (Ast) +LL | let b = &mut true; | ^^^^^^^^^ -LL | //~^ borrow may still be in use when generator yields (Mir) +LL | //~^ borrow may still be in use when generator yields LL | yield (); | -------- possible yield occurs here -error: aborting due to 3 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0626`. diff --git a/src/test/ui/impl-trait/associated-existential-type-generic-trait.rs b/src/test/ui/impl-trait/associated-existential-type-generic-trait.rs new file mode 100644 index 00000000000..c9bf7b87ef4 --- /dev/null +++ b/src/test/ui/impl-trait/associated-existential-type-generic-trait.rs @@ -0,0 +1,40 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(existential_type)] +// compile-pass + +trait Bar {} +struct Dummy<U>(U); +impl<V> Bar for Dummy<V> {} + +trait Foo<T> { + type Assoc: Bar; + fn foo(t: T) -> Self::Assoc; +} + +impl<W> Foo<W> for i32 { + existential type Assoc: Bar; + fn foo(w: W) -> Self::Assoc { + Dummy(w) + } +} + +struct NonGeneric; +impl Bar for NonGeneric {} + +impl<W> Foo<W> for u32 { + existential type Assoc: Bar; + fn foo(_: W) -> Self::Assoc { + NonGeneric + } +} + +fn main() {} diff --git a/src/test/ui/impl-trait/associated-existential-type-trivial.rs b/src/test/ui/impl-trait/associated-existential-type-trivial.rs new file mode 100644 index 00000000000..78593fe319c --- /dev/null +++ b/src/test/ui/impl-trait/associated-existential-type-trivial.rs @@ -0,0 +1,30 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(existential_type)] +// compile-pass + +trait Bar {} +struct Dummy; +impl Bar for Dummy {} + +trait Foo { + type Assoc: Bar; + fn foo() -> Self::Assoc; +} + +impl Foo for i32 { + existential type Assoc: Bar; + fn foo() -> Self::Assoc { + Dummy + } +} + +fn main() {} diff --git a/src/test/ui/impl-trait/associated-existential-type.rs b/src/test/ui/impl-trait/associated-existential-type.rs new file mode 100644 index 00000000000..d880428411f --- /dev/null +++ b/src/test/ui/impl-trait/associated-existential-type.rs @@ -0,0 +1,34 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(existential_type)] +// compile-pass + +trait Bar {} +struct Dummy; +impl Bar for Dummy {} + +trait Foo { + type Assoc: Bar; + fn foo() -> Self::Assoc; + fn bar() -> Self::Assoc; +} + +impl Foo for i32 { + existential type Assoc: Bar; + fn foo() -> Self::Assoc { + Dummy + } + fn bar() -> Self::Assoc { + Dummy + } +} + +fn main() {} diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr b/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr index c6f8d2e519c..bbc63e6feca 100644 --- a/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr +++ b/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr @@ -10,21 +10,19 @@ warning: not reporting region error due to nll LL | self.x.iter().map(|a| a.0) | ^^^^ -error: borrowed data escapes outside of closure +error: unsatisfied lifetime constraints --> $DIR/static-return-lifetime-infered.rs:17:9 | LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> { - | ----- `self` is a reference that is only valid in the closure body + | - let's call the lifetime of this reference `'1` LL | self.x.iter().map(|a| a.0) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `self` escapes the closure body here + | ^^^^^^^^^^^^^ requires that `'1` must outlive `'static` -error: borrowed data escapes outside of closure +error: unsatisfied lifetime constraints --> $DIR/static-return-lifetime-infered.rs:21:9 | -LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> { - | -------- `self` is a reference that is only valid in the closure body LL | self.x.iter().map(|a| a.0) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `self` escapes the closure body here + | ^^^^^^^^^^^^^ requires that `'a` must outlive `'static` error: aborting due to 2 previous errors diff --git a/src/test/ui/in-band-lifetimes/impl/dyn-trait.nll.stderr b/src/test/ui/in-band-lifetimes/impl/dyn-trait.nll.stderr index e26b1956d5e..f5d98e04ad8 100644 --- a/src/test/ui/in-band-lifetimes/impl/dyn-trait.nll.stderr +++ b/src/test/ui/in-band-lifetimes/impl/dyn-trait.nll.stderr @@ -4,13 +4,13 @@ warning: not reporting region error due to nll LL | static_val(x); //~ ERROR cannot infer | ^ -error: borrowed data escapes outside of closure +error: borrowed data escapes outside of function --> $DIR/dyn-trait.rs:32:5 | LL | fn with_dyn_debug_static<'a>(x: Box<dyn Debug + 'a>) { - | - `x` is a reference that is only valid in the closure body + | - `x` is a reference that is only valid in the function body LL | static_val(x); //~ ERROR cannot infer - | ^^^^^^^^^^^^^ `x` escapes the closure body here + | ^^^^^^^^^^^^^ `x` escapes the function body here error: aborting due to previous error diff --git a/src/test/ui/issue-10291.nll.stderr b/src/test/ui/issue-10291.nll.stderr index 1358fe010b4..6de00ffd48c 100644 --- a/src/test/ui/issue-10291.nll.stderr +++ b/src/test/ui/issue-10291.nll.stderr @@ -8,7 +8,7 @@ error: unsatisfied lifetime constraints --> $DIR/issue-10291.rs:12:5 | LL | drop::<Box<for<'z> FnMut(&'z isize) -> &'z isize>>(Box::new(|z| { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ free region requires that `'x` must outlive `'static` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'x` must outlive `'static` error: aborting due to previous error diff --git a/src/test/ui/issue-13033.stderr b/src/test/ui/issue-13033.stderr index 2db3cb80a81..f06d7360d85 100644 --- a/src/test/ui/issue-13033.stderr +++ b/src/test/ui/issue-13033.stderr @@ -9,6 +9,10 @@ LL | fn bar(&mut self, other: &Foo) {} | = note: expected type `fn(&mut Baz, &mut dyn Foo)` found type `fn(&mut Baz, &dyn Foo)` +help: consider change the type to match the mutability in trait + | +LL | fn bar(&mut self, other: &mut Foo) {} + | ^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issue-16683.nll.stderr b/src/test/ui/issue-16683.nll.stderr index f9dda27da09..890bb426441 100644 --- a/src/test/ui/issue-16683.nll.stderr +++ b/src/test/ui/issue-16683.nll.stderr @@ -10,13 +10,13 @@ warning: not reporting region error due to nll LL | self.a(); //~ ERROR cannot infer | ^ -error: borrowed data escapes outside of closure +error: borrowed data escapes outside of function --> $DIR/issue-16683.rs:14:9 | LL | fn b(&self) { - | ----- `self` is a reference that is only valid in the closure body + | ----- `self` is a reference that is only valid in the function body LL | self.a(); //~ ERROR cannot infer - | ^^^^^^^^ `self` escapes the closure body here + | ^^^^^^^^ `self` escapes the function body here error: aborting due to previous error diff --git a/src/test/ui/issue-17385.nll.stderr b/src/test/ui/issue-17385.nll.stderr index c3387e58fcf..85924a75261 100644 --- a/src/test/ui/issue-17385.nll.stderr +++ b/src/test/ui/issue-17385.nll.stderr @@ -1,26 +1,20 @@ error[E0382]: use of moved value: `foo` - --> $DIR/issue-17385.rs:28:5 + --> $DIR/issue-17385.rs:28:11 | -LL | drop(foo); - | --- value moved here -LL | / match foo { //~ ERROR use of moved value -LL | | X(1) => (), -LL | | _ => unreachable!() -LL | | } - | |_____^ value used here after move +LL | drop(foo); + | --- value moved here +LL | match foo { //~ ERROR use of moved value + | ^^^ value used here after move | = note: move occurs because `foo` has type `X`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `foo` - --> $DIR/issue-17385.rs:28:5 + --> $DIR/issue-17385.rs:28:11 | -LL | drop(foo); - | --- value moved here -LL | / match foo { //~ ERROR use of moved value -LL | | X(1) => (), -LL | | _ => unreachable!() -LL | | } - | |_____^ value borrowed here after move +LL | drop(foo); + | --- value moved here +LL | match foo { //~ ERROR use of moved value + | ^^^ value borrowed here after move | = note: move occurs because `foo` has type `X`, which does not implement the `Copy` trait @@ -36,28 +30,22 @@ LL | X(1) => (), = note: move occurs because `foo` has type `X`, which does not implement the `Copy` trait error[E0382]: use of moved value: `e` - --> $DIR/issue-17385.rs:35:5 + --> $DIR/issue-17385.rs:35:11 | -LL | drop(e); - | - value moved here -LL | / match e { //~ ERROR use of moved value -LL | | Enum::Variant1 => unreachable!(), -LL | | Enum::Variant2 => () -LL | | } - | |_____^ value used here after move +LL | drop(e); + | - value moved here +LL | match e { //~ ERROR use of moved value + | ^ value used here after move | = note: move occurs because `e` has type `Enum`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `e` - --> $DIR/issue-17385.rs:35:5 + --> $DIR/issue-17385.rs:35:11 | -LL | drop(e); - | - value moved here -LL | / match e { //~ ERROR use of moved value -LL | | Enum::Variant1 => unreachable!(), -LL | | Enum::Variant2 => () -LL | | } - | |_____^ value borrowed here after move +LL | drop(e); + | - value moved here +LL | match e { //~ ERROR use of moved value + | ^ value borrowed here after move | = note: move occurs because `e` has type `Enum`, which does not implement the `Copy` trait diff --git a/src/test/ui/issue-17758.nll.stderr b/src/test/ui/issue-17758.nll.stderr index 5775135aefc..c51a72f885d 100644 --- a/src/test/ui/issue-17758.nll.stderr +++ b/src/test/ui/issue-17758.nll.stderr @@ -10,13 +10,13 @@ warning: not reporting region error due to nll LL | self.foo(); | ^^^ -error: borrowed data escapes outside of closure +error: borrowed data escapes outside of function --> $DIR/issue-17758.rs:17:9 | LL | fn bar(&self) { - | ----- `self` is a reference that is only valid in the closure body + | ----- `self` is a reference that is only valid in the function body LL | self.foo(); - | ^^^^^^^^^^ `self` escapes the closure body here + | ^^^^^^^^^^ `self` escapes the function body here error: aborting due to previous error diff --git a/src/test/ui/issue-20801.nll.stderr b/src/test/ui/issue-20801.nll.stderr index 0394309a6e2..fc94cc423c5 100644 --- a/src/test/ui/issue-20801.nll.stderr +++ b/src/test/ui/issue-20801.nll.stderr @@ -2,25 +2,37 @@ error[E0507]: cannot move out of borrowed content --> $DIR/issue-20801.rs:36:22 | LL | let a = unsafe { *mut_ref() }; - | ^^^^^^^^^^ cannot move out of borrowed content + | ^^^^^^^^^^ + | | + | cannot move out of borrowed content + | help: consider using a reference instead: `&*mut_ref()` error[E0507]: cannot move out of borrowed content --> $DIR/issue-20801.rs:39:22 | LL | let b = unsafe { *imm_ref() }; - | ^^^^^^^^^^ cannot move out of borrowed content + | ^^^^^^^^^^ + | | + | cannot move out of borrowed content + | help: consider using a reference instead: `&*imm_ref()` error[E0507]: cannot move out of borrowed content --> $DIR/issue-20801.rs:42:22 | LL | let c = unsafe { *mut_ptr() }; - | ^^^^^^^^^^ cannot move out of borrowed content + | ^^^^^^^^^^ + | | + | cannot move out of borrowed content + | help: consider using a reference instead: `&*mut_ptr()` error[E0507]: cannot move out of borrowed content --> $DIR/issue-20801.rs:45:22 | LL | let d = unsafe { *const_ptr() }; - | ^^^^^^^^^^^^ cannot move out of borrowed content + | ^^^^^^^^^^^^ + | | + | cannot move out of borrowed content + | help: consider using a reference instead: `&*const_ptr()` error: aborting due to 4 previous errors diff --git a/src/test/ui/issue-27282-move-match-input-into-guard.stderr b/src/test/ui/issue-27282-move-match-input-into-guard.stderr index f89388f1738..d264bf8d273 100644 --- a/src/test/ui/issue-27282-move-match-input-into-guard.stderr +++ b/src/test/ui/issue-27282-move-match-input-into-guard.stderr @@ -1,21 +1,14 @@ error[E0505]: cannot move out of `b` because it is borrowed --> $DIR/issue-27282-move-match-input-into-guard.rs:26:16 | -LL | match b { - | _____- - | |_____| - | || -LL | || &mut false => {}, -LL | || _ if { (|| { let bar = b; *bar = false; })(); - | || ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ move out of `b` occurs here -LL | || //~^ ERROR cannot move out of `b` because it is borrowed [E0505] -... || -LL | || _ => panic!("surely we could never get here, since rustc warns it is unreachable."), -LL | || } - | || - - | ||_____| - | |______borrow of `b` occurs here - | borrow later used here +LL | match b { + | - borrow of `b` occurs here +LL | &mut false => {}, +LL | _ if { (|| { let bar = b; *bar = false; })(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ move out of `b` occurs here +... +LL | &mut true => { println!("You might think we should get here"); }, + | --------- borrow later used here error[E0382]: use of moved value: `*b` --> $DIR/issue-27282-move-match-input-into-guard.rs:29:14 diff --git a/src/test/ui/issue-27282-mutate-before-diverging-arm-1.stderr b/src/test/ui/issue-27282-mutate-before-diverging-arm-1.stderr index 8f7fe9d33fe..fb11090c222 100644 --- a/src/test/ui/issue-27282-mutate-before-diverging-arm-1.stderr +++ b/src/test/ui/issue-27282-mutate-before-diverging-arm-1.stderr @@ -1,24 +1,16 @@ error[E0500]: closure requires unique access to `x` but it is already borrowed --> $DIR/issue-27282-mutate-before-diverging-arm-1.rs:33:14 | -LL | match x { - | _____- - | |_____| - | || -LL | || &mut None => panic!("unreachable"), -LL | || &mut Some(&_) if { -LL | || // ForceFnOnce needed to exploit #27282 -LL | || (|| { *x = None; drop(force_fn_once); })(); - | || ^^ - borrow occurs due to use of `x` in closure - | || | - | || closure construction occurs here -... || -LL | || _ => panic!("unreachable"), -LL | || } - | || - - | ||_____| - | |______borrow occurs here - | borrow later used here +LL | match x { + | - borrow occurs here +... +LL | (|| { *x = None; drop(force_fn_once); })(); + | ^^ - borrow occurs due to use of `x` in closure + | | + | closure construction occurs here +... +LL | &mut Some(&a) if { // this binds to garbage if we've corrupted discriminant + | ------------- borrow later used here error: aborting due to previous error diff --git a/src/test/ui/issue-27282-mutate-before-diverging-arm-2.stderr b/src/test/ui/issue-27282-mutate-before-diverging-arm-2.stderr index df5e4300cec..6e643d30185 100644 --- a/src/test/ui/issue-27282-mutate-before-diverging-arm-2.stderr +++ b/src/test/ui/issue-27282-mutate-before-diverging-arm-2.stderr @@ -1,25 +1,16 @@ error[E0500]: closure requires unique access to `x` but it is already borrowed --> $DIR/issue-27282-mutate-before-diverging-arm-2.rs:38:18 | -LL | match x { - | _____- - | |_____| - | || -LL | || &mut None => panic!("unreachable"), -LL | || &mut Some(&_) -LL | || if { -LL | || // ForceFnOnce needed to exploit #27282 -LL | || (|| { *x = None; drop(force_fn_once); })(); - | || ^^ - borrow occurs due to use of `x` in closure - | || | - | || closure construction occurs here -... || -LL | || _ => panic!("unreachable"), -LL | || } - | || - - | ||_____| - | |______borrow occurs here - | borrow later used here +LL | match x { + | - borrow occurs here +... +LL | (|| { *x = None; drop(force_fn_once); })(); + | ^^ - borrow occurs due to use of `x` in closure + | | + | closure construction occurs here +... +LL | &mut Some(&2) + | ------------- borrow later used here error: aborting due to previous error diff --git a/src/test/ui/issue-40510-1.nll.stderr b/src/test/ui/issue-40510-1.nll.stderr index 73a8d58290d..312ec6e742e 100644 --- a/src/test/ui/issue-40510-1.nll.stderr +++ b/src/test/ui/issue-40510-1.nll.stderr @@ -6,7 +6,7 @@ LL | || { | |_____| | || LL | || &mut x - | || ^^^^^^ free region requires that `'1` must outlive `'2` + | || ^^^^^^ return requires that `'1` must outlive `'2` LL | || }; | || - | ||_____| diff --git a/src/test/ui/issue-40510-3.nll.stderr b/src/test/ui/issue-40510-3.nll.stderr index 4133c69f031..eb44850e639 100644 --- a/src/test/ui/issue-40510-3.nll.stderr +++ b/src/test/ui/issue-40510-3.nll.stderr @@ -9,7 +9,7 @@ LL | || || { | ||_________^ LL | ||| x.push(()) LL | ||| } - | |||_________^ free region requires that `'1` must outlive `'2` + | |||_________^ requires that `'1` must outlive `'2` LL | || }; | || - | ||_____| diff --git a/src/test/ui/issue-47412.stderr b/src/test/ui/issue-47412.stderr index 6ca404003a5..d8a47efc0aa 100644 --- a/src/test/ui/issue-47412.stderr +++ b/src/test/ui/issue-47412.stderr @@ -1,16 +1,16 @@ error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/issue-47412.rs:21:5 + --> $DIR/issue-47412.rs:21:11 | LL | match u.void {} - | ^^^^^^^^^^^^^^^ access to union field + | ^^^^^^ access to union field | = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block - --> $DIR/issue-47412.rs:27:5 + --> $DIR/issue-47412.rs:27:11 | LL | match *ptr {} - | ^^^^^^^^^^^^^ dereference of raw pointer + | ^^^^ dereference of raw pointer | = note: raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior diff --git a/src/test/ui/issue-52213.nll.stderr b/src/test/ui/issue-52213.nll.stderr index c288cf9ed82..7dd513d1b71 100644 --- a/src/test/ui/issue-52213.nll.stderr +++ b/src/test/ui/issue-52213.nll.stderr @@ -8,7 +8,7 @@ error: unsatisfied lifetime constraints --> $DIR/issue-52213.rs:13:11 | LL | ((u,),) => u, - | ^ free region requires that `'a` must outlive `'b` + | ^ requires that `'a` must outlive `'b` error: aborting due to previous error diff --git a/src/test/ui/issue-52533-1.nll.stderr b/src/test/ui/issue-52533-1.nll.stderr new file mode 100644 index 00000000000..87fda1dd99c --- /dev/null +++ b/src/test/ui/issue-52533-1.nll.stderr @@ -0,0 +1,17 @@ +warning: not reporting region error due to nll + --> $DIR/issue-52533-1.rs:19:18 + | +LL | gimme(|x, y| y) + | ^ + +error: unsatisfied lifetime constraints + --> $DIR/issue-52533-1.rs:19:18 + | +LL | gimme(|x, y| y) + | - - ^ closure was supposed to return data with lifetime `'1` but it is returning data with lifetime `'2` + | | | + | | has type `&Foo<'_, '1, u32>` + | has type `&Foo<'_, '2, u32>` + +error: aborting due to previous error + diff --git a/src/liballoc/repeat-generic-slice.rs b/src/test/ui/issue-52533-1.rs index 5c14ee4fd83..22af5a86702 100644 --- a/src/liballoc/repeat-generic-slice.rs +++ b/src/test/ui/issue-52533-1.rs @@ -8,12 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(repeat_generic_slice)] +#![allow(warnings)] + +struct Foo<'a, 'b, T: 'a + 'b> { x: &'a T, y: &'b T } + +fn gimme(_: impl for<'a, 'b, 'c> FnOnce(&'a Foo<'a, 'b, u32>, + &'a Foo<'a, 'c, u32>) -> &'a Foo<'a, 'b, u32>) { } fn main() { - assert_eq!([1, 2].repeat(2), vec![1, 2, 1, 2]); - assert_eq!([1, 2, 3, 4].repeat(0), vec![]); - assert_eq!([1, 2, 3, 4].repeat(1), vec![1, 2, 3, 4]); - assert_eq!([1, 2, 3, 4].repeat(3), - vec![1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]); + gimme(|x, y| y) + //~^ ERROR mismatched types [E0308] } diff --git a/src/test/ui/issue-52533-1.stderr b/src/test/ui/issue-52533-1.stderr new file mode 100644 index 00000000000..38deb7d66de --- /dev/null +++ b/src/test/ui/issue-52533-1.stderr @@ -0,0 +1,22 @@ +error[E0308]: mismatched types + --> $DIR/issue-52533-1.rs:19:18 + | +LL | gimme(|x, y| y) + | ^ lifetime mismatch + | + = note: expected type `&Foo<'_, '_, u32>` + found type `&Foo<'_, '_, u32>` +note: the anonymous lifetime #4 defined on the body at 19:11... + --> $DIR/issue-52533-1.rs:19:11 + | +LL | gimme(|x, y| y) + | ^^^^^^^^ +note: ...does not necessarily outlive the anonymous lifetime #3 defined on the body at 19:11 + --> $DIR/issue-52533-1.rs:19:11 + | +LL | gimme(|x, y| y) + | ^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/issue-52533.nll.stderr b/src/test/ui/issue-52533.nll.stderr new file mode 100644 index 00000000000..a13b06e3204 --- /dev/null +++ b/src/test/ui/issue-52533.nll.stderr @@ -0,0 +1,17 @@ +warning: not reporting region error due to nll + --> $DIR/issue-52533.rs:15:16 + | +LL | foo(|a, b| b) + | ^ + +error: unsatisfied lifetime constraints + --> $DIR/issue-52533.rs:15:16 + | +LL | foo(|a, b| b) + | - - ^ closure was supposed to return data with lifetime `'1` but it is returning data with lifetime `'2` + | | | + | | has type `&'1 u32` + | has type `&'2 u32` + +error: aborting due to previous error + diff --git a/src/test/ui/issue-52533.rs b/src/test/ui/issue-52533.rs new file mode 100644 index 00000000000..08f2805cefd --- /dev/null +++ b/src/test/ui/issue-52533.rs @@ -0,0 +1,17 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn foo(_: impl for<'a> FnOnce(&'a u32, &u32) -> &'a u32) { +} + +fn main() { + foo(|a, b| b) + //~^ ERROR lifetime of reference outlives lifetime of borrowed content... +} diff --git a/src/test/ui/issue-52533.stderr b/src/test/ui/issue-52533.stderr new file mode 100644 index 00000000000..76a2470a2e0 --- /dev/null +++ b/src/test/ui/issue-52533.stderr @@ -0,0 +1,20 @@ +error[E0312]: lifetime of reference outlives lifetime of borrowed content... + --> $DIR/issue-52533.rs:15:16 + | +LL | foo(|a, b| b) + | ^ + | +note: ...the reference is valid for the anonymous lifetime #2 defined on the body at 15:9... + --> $DIR/issue-52533.rs:15:9 + | +LL | foo(|a, b| b) + | ^^^^^^^^ +note: ...but the borrowed content is only valid for the anonymous lifetime #3 defined on the body at 15:9 + --> $DIR/issue-52533.rs:15:9 + | +LL | foo(|a, b| b) + | ^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0312`. diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.nll.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.nll.stderr index 5451562cdfb..e5b001def56 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.nll.stderr +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.nll.stderr @@ -5,18 +5,12 @@ LL | other //~ ERROR explicit lifetime | ^^^^^ error[E0621]: explicit lifetime required in the type of `other` - --> $DIR/ex1-return-one-existing-name-early-bound-in-struct.rs:18:9 + --> $DIR/ex1-return-one-existing-name-early-bound-in-struct.rs:18:15 | -LL | fn bar(&self, other: Foo) -> Foo<'a> { - | ----- consider changing the type of `other` to `Foo<'a>` -LL | / match *self { -LL | | Foo::Bar(s) => { -LL | | if s == "test" { -LL | | other //~ ERROR explicit lifetime -... | -LL | | } -LL | | } - | |_________^ lifetime `'a` required +LL | fn bar(&self, other: Foo) -> Foo<'a> { + | ----- consider changing the type of `other` to `Foo<'a>` +LL | match *self { + | ^^^^^ lifetime `'a` required error: aborting due to previous error diff --git a/src/test/ui/mismatched_types/E0053.stderr b/src/test/ui/mismatched_types/E0053.stderr index 1b16694bf2c..f707a600f29 100644 --- a/src/test/ui/mismatched_types/E0053.stderr +++ b/src/test/ui/mismatched_types/E0053.stderr @@ -21,6 +21,10 @@ LL | fn bar(&mut self) { } | = note: expected type `fn(&Bar)` found type `fn(&mut Bar)` +help: consider change the type to match the mutability in trait + | +LL | fn bar(&self) { } + | ^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.stderr b/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.stderr index 28b16641e4d..631af21cac5 100644 --- a/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.stderr +++ b/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.stderr @@ -21,6 +21,10 @@ LL | fn bar(&mut self, bar: &Bar) { } //~ ERROR incompatible type | = note: expected type `fn(&mut Bar, &mut Bar)` found type `fn(&mut Bar, &Bar)` +help: consider change the type to match the mutability in trait + | +LL | fn bar(&mut self, bar: &mut Bar) { } //~ ERROR incompatible type + | ^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/nll/borrowed-match-issue-45045.stderr b/src/test/ui/nll/borrowed-match-issue-45045.stderr index 7904e601579..acbba9ee187 100644 --- a/src/test/ui/nll/borrowed-match-issue-45045.stderr +++ b/src/test/ui/nll/borrowed-match-issue-45045.stderr @@ -1,17 +1,14 @@ error[E0503]: cannot use `e` because it was mutably borrowed - --> $DIR/borrowed-match-issue-45045.rs:24:5 + --> $DIR/borrowed-match-issue-45045.rs:24:11 | -LL | let f = &mut e; - | ------ borrow of `e` occurs here -LL | let g = f; -LL | / match e { //~ cannot use `e` because it was mutably borrowed [E0503] -LL | | Xyz::A => println!("a"), -LL | | //~^ cannot use `e` because it was mutably borrowed [E0503] -LL | | Xyz::B => println!("b"), -LL | | }; - | |_____^ use of borrowed `e` -LL | *g = Xyz::B; - | ----------- borrow later used here +LL | let f = &mut e; + | ------ borrow of `e` occurs here +LL | let g = f; +LL | match e { //~ cannot use `e` because it was mutably borrowed [E0503] + | ^ use of borrowed `e` +... +LL | *g = Xyz::B; + | ----------- borrow later used here error[E0503]: cannot use `e` because it was mutably borrowed --> $DIR/borrowed-match-issue-45045.rs:25:9 diff --git a/src/test/ui/nll/cannot-move-block-spans.nll.stderr b/src/test/ui/nll/cannot-move-block-spans.nll.stderr new file mode 100644 index 00000000000..814e11b6f06 --- /dev/null +++ b/src/test/ui/nll/cannot-move-block-spans.nll.stderr @@ -0,0 +1,85 @@ +error[E0507]: cannot move out of borrowed content + --> $DIR/cannot-move-block-spans.rs:15:15 + | +LL | let x = { *r }; //~ ERROR + | ^^ + | | + | cannot move out of borrowed content + | help: consider removing this dereference operator: `r` + +error[E0507]: cannot move out of borrowed content + --> $DIR/cannot-move-block-spans.rs:16:22 + | +LL | let y = unsafe { *r }; //~ ERROR + | ^^ + | | + | cannot move out of borrowed content + | help: consider removing this dereference operator: `r` + +error[E0507]: cannot move out of borrowed content + --> $DIR/cannot-move-block-spans.rs:17:26 + | +LL | let z = loop { break *r; }; //~ ERROR + | ^^ + | | + | cannot move out of borrowed content + | help: consider removing this dereference operator: `r` + +error[E0508]: cannot move out of type `[std::string::String; 2]`, a non-copy array + --> $DIR/cannot-move-block-spans.rs:21:15 + | +LL | let x = { arr[0] }; //~ ERROR + | ^^^^^^ + | | + | cannot move out of here + | help: consider using a reference instead: `&arr[0]` + +error[E0508]: cannot move out of type `[std::string::String; 2]`, a non-copy array + --> $DIR/cannot-move-block-spans.rs:22:22 + | +LL | let y = unsafe { arr[0] }; //~ ERROR + | ^^^^^^ + | | + | cannot move out of here + | help: consider using a reference instead: `&arr[0]` + +error[E0508]: cannot move out of type `[std::string::String; 2]`, a non-copy array + --> $DIR/cannot-move-block-spans.rs:23:26 + | +LL | let z = loop { break arr[0]; }; //~ ERROR + | ^^^^^^ + | | + | cannot move out of here + | help: consider using a reference instead: `&arr[0]` + +error[E0507]: cannot move out of borrowed content + --> $DIR/cannot-move-block-spans.rs:27:38 + | +LL | let x = { let mut u = 0; u += 1; *r }; //~ ERROR + | ^^ + | | + | cannot move out of borrowed content + | help: consider removing this dereference operator: `r` + +error[E0507]: cannot move out of borrowed content + --> $DIR/cannot-move-block-spans.rs:28:45 + | +LL | let y = unsafe { let mut u = 0; u += 1; *r }; //~ ERROR + | ^^ + | | + | cannot move out of borrowed content + | help: consider removing this dereference operator: `r` + +error[E0507]: cannot move out of borrowed content + --> $DIR/cannot-move-block-spans.rs:29:49 + | +LL | let z = loop { let mut u = 0; u += 1; break *r; u += 2; }; //~ ERROR + | ^^ + | | + | cannot move out of borrowed content + | help: consider removing this dereference operator: `r` + +error: aborting due to 9 previous errors + +Some errors occurred: E0507, E0508. +For more information about an error, try `rustc --explain E0507`. diff --git a/src/test/ui/nll/cannot-move-block-spans.rs b/src/test/ui/nll/cannot-move-block-spans.rs new file mode 100644 index 00000000000..5a84a4ca48e --- /dev/null +++ b/src/test/ui/nll/cannot-move-block-spans.rs @@ -0,0 +1,32 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that the we point to the inner expression when moving out to initialize +// a variable, and that we don't give a useless suggestion such as &{ *r }. + +pub fn deref(r: &String) { + let x = { *r }; //~ ERROR + let y = unsafe { *r }; //~ ERROR + let z = loop { break *r; }; //~ ERROR +} + +pub fn index(arr: [String; 2]) { + let x = { arr[0] }; //~ ERROR + let y = unsafe { arr[0] }; //~ ERROR + let z = loop { break arr[0]; }; //~ ERROR +} + +pub fn additional_statement_cases(r: &String) { + let x = { let mut u = 0; u += 1; *r }; //~ ERROR + let y = unsafe { let mut u = 0; u += 1; *r }; //~ ERROR + let z = loop { let mut u = 0; u += 1; break *r; u += 2; }; //~ ERROR +} + +fn main() {} diff --git a/src/test/ui/nll/cannot-move-block-spans.stderr b/src/test/ui/nll/cannot-move-block-spans.stderr new file mode 100644 index 00000000000..d4956900239 --- /dev/null +++ b/src/test/ui/nll/cannot-move-block-spans.stderr @@ -0,0 +1,58 @@ +error[E0507]: cannot move out of borrowed content + --> $DIR/cannot-move-block-spans.rs:15:15 + | +LL | let x = { *r }; //~ ERROR + | ^^ cannot move out of borrowed content + +error[E0507]: cannot move out of borrowed content + --> $DIR/cannot-move-block-spans.rs:16:22 + | +LL | let y = unsafe { *r }; //~ ERROR + | ^^ cannot move out of borrowed content + +error[E0507]: cannot move out of borrowed content + --> $DIR/cannot-move-block-spans.rs:17:26 + | +LL | let z = loop { break *r; }; //~ ERROR + | ^^ cannot move out of borrowed content + +error[E0508]: cannot move out of type `[std::string::String; 2]`, a non-copy array + --> $DIR/cannot-move-block-spans.rs:21:15 + | +LL | let x = { arr[0] }; //~ ERROR + | ^^^^^^ cannot move out of here + +error[E0508]: cannot move out of type `[std::string::String; 2]`, a non-copy array + --> $DIR/cannot-move-block-spans.rs:22:22 + | +LL | let y = unsafe { arr[0] }; //~ ERROR + | ^^^^^^ cannot move out of here + +error[E0508]: cannot move out of type `[std::string::String; 2]`, a non-copy array + --> $DIR/cannot-move-block-spans.rs:23:26 + | +LL | let z = loop { break arr[0]; }; //~ ERROR + | ^^^^^^ cannot move out of here + +error[E0507]: cannot move out of borrowed content + --> $DIR/cannot-move-block-spans.rs:27:38 + | +LL | let x = { let mut u = 0; u += 1; *r }; //~ ERROR + | ^^ cannot move out of borrowed content + +error[E0507]: cannot move out of borrowed content + --> $DIR/cannot-move-block-spans.rs:28:45 + | +LL | let y = unsafe { let mut u = 0; u += 1; *r }; //~ ERROR + | ^^ cannot move out of borrowed content + +error[E0507]: cannot move out of borrowed content + --> $DIR/cannot-move-block-spans.rs:29:49 + | +LL | let z = loop { let mut u = 0; u += 1; break *r; u += 2; }; //~ ERROR + | ^^ cannot move out of borrowed content + +error: aborting due to 9 previous errors + +Some errors occurred: E0507, E0508. +For more information about an error, try `rustc --explain E0507`. diff --git a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr index d6f54218360..ccf116e640d 100644 --- a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr +++ b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr @@ -8,10 +8,10 @@ error: unsatisfied lifetime constraints --> $DIR/escape-argument-callee.rs:36:45 | LL | let mut closure = expect_sig(|p, y| *p = y); - | - - ^^^^^^ free region requires that `'1` must outlive `'2` + | - - ^^^^^^ requires that `'1` must outlive `'2` | | | - | | lifetime `'1` appears in this argument - | lifetime `'2` appears in this argument + | | has type `&'1 i32` + | has type `&mut &'2 i32` note: No external requirements --> $DIR/escape-argument-callee.rs:36:38 diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr index a7a50a3a029..b4508824901 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr @@ -8,9 +8,9 @@ error: unsatisfied lifetime constraints --> $DIR/propagate-approximated-fail-no-postdom.rs:57:13 | LL | |_outlives1, _outlives2, _outlives3, x, y| { - | ---------- ---------- lifetime `'2` appears in this argument + | ---------- ---------- has type `std::cell::Cell<&'2 &u32>` | | - | lifetime `'1` appears in this argument + | has type `std::cell::Cell<&&'1 u32>` ... LL | demand_y(x, y, p) //~ ERROR | ^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr index 3177cd7c28f..33e4240736f 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr @@ -23,18 +23,18 @@ LL | | }); = note: number of external vids: 2 = note: where '_#1r: '_#0r -error: borrowed data escapes outside of closure +error: borrowed data escapes outside of function --> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:45:5 | LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { - | ------ `cell_a` is a reference that is only valid in the closure body + | ------ `cell_a` is a reference that is only valid in the function body LL | / establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { LL | | //~^ ERROR LL | | LL | | // Only works if 'x: 'y: LL | | demand_y(x, y, x.get()) //~ WARNING not reporting region error due to nll LL | | }); - | |______^ `cell_a` escapes the closure body here + | |______^ `cell_a` escapes the function body here note: No external requirements --> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:44:1 diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr index 089c88abcdd..5f98a0fd36d 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr @@ -23,18 +23,18 @@ LL | | }); = note: number of external vids: 3 = note: where '_#1r: '_#0r -error: borrowed data escapes outside of closure +error: borrowed data escapes outside of function --> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:48:5 | LL | fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { - | ------ `cell_a` is a reference that is only valid in the closure body + | ------ `cell_a` is a reference that is only valid in the function body LL | / establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { LL | | //~^ ERROR LL | | // Only works if 'x: 'y: LL | | demand_y(x, y, x.get()) LL | | //~^ WARNING not reporting region error due to nll LL | | }); - | |______^ `cell_a` escapes the closure body here + | |______^ `cell_a` escapes the function body here note: No external requirements --> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:47:1 diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr index fb98c506c7d..40ebda4419b 100644 --- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr @@ -8,9 +8,9 @@ error: unsatisfied lifetime constraints --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:47:9 | LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { - | --------- - lifetime `'1` appears in this argument + | --------- - has type `&std::cell::Cell<&'1 u32>` | | - | lifetime `'2` appears in this argument + | has type `&std::cell::Cell<&'2 &u32>` LL | // Only works if 'x: 'y: LL | demand_y(x, y, x.get()) | ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr index 73d39a8502b..37ea6103976 100644 --- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr @@ -8,9 +8,9 @@ error: unsatisfied lifetime constraints --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:51:9 | LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { - | ---------- ---------- lifetime `'2` appears in this argument + | ---------- ---------- has type `&std::cell::Cell<&'2 &u32>` | | - | lifetime `'1` appears in this argument + | has type `&std::cell::Cell<&'1 &u32>` LL | // Only works if 'x: 'y: LL | demand_y(x, y, x.get()) | ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` diff --git a/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr b/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr index d012dca2527..b0562711627 100644 --- a/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr +++ b/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr @@ -8,7 +8,7 @@ error: unsatisfied lifetime constraints --> $DIR/region-lbr-named-does-not-outlive-static.rs:19:5 | LL | &*x - | ^^^ free region requires that `'a` must outlive `'static` + | ^^^ requires that `'a` must outlive `'static` error: aborting due to previous error diff --git a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr index 5724cdbd8c9..d6d1645ceea 100644 --- a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr +++ b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr @@ -8,10 +8,10 @@ error: unsatisfied lifetime constraints --> $DIR/return-wrong-bound-region.rs:21:23 | LL | expect_sig(|a, b| b); // ought to return `a` - | - - ^ free region requires that `'1` must outlive `'2` + | - - ^ closure was supposed to return data with lifetime `'1` but it is returning data with lifetime `'2` | | | - | | lifetime `'1` appears in this argument - | lifetime `'2` appears in this argument + | | has type `&'1 i32` + | has type `&'2 i32` note: No external requirements --> $DIR/return-wrong-bound-region.rs:21:16 diff --git a/src/test/ui/nll/issue-50716.stderr b/src/test/ui/nll/issue-50716.stderr index 8acf2ef51ec..f12ab9b4f96 100644 --- a/src/test/ui/nll/issue-50716.stderr +++ b/src/test/ui/nll/issue-50716.stderr @@ -1,11 +1,11 @@ -error: borrowed data escapes outside of closure +error: borrowed data escapes outside of function --> $DIR/issue-50716.rs:25:14 | LL | fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>) - | - `s` is a reference that is only valid in the closure body + | - `s` is a reference that is only valid in the function body ... LL | let _x = *s; //~ ERROR - | ^^ `s` escapes the closure body here + | ^^ `s` escapes the function body here error: aborting due to previous error diff --git a/src/test/ui/nll/mir_check_cast_reify.stderr b/src/test/ui/nll/mir_check_cast_reify.stderr index 13f90e1f159..d8f186a2232 100644 --- a/src/test/ui/nll/mir_check_cast_reify.stderr +++ b/src/test/ui/nll/mir_check_cast_reify.stderr @@ -4,14 +4,14 @@ warning: not reporting region error due to nll LL | let f: fn(_) -> _ = foo; | ^^^ -error: borrowed data escapes outside of closure +error: borrowed data escapes outside of function --> $DIR/mir_check_cast_reify.rs:48:5 | LL | fn bar<'a>(x: &'a u32) -> &'static u32 { - | - `x` is a reference that is only valid in the closure body + | - `x` is a reference that is only valid in the function body ... LL | f(x) - | ^^^^ `x` escapes the closure body here + | ^^^^ `x` escapes the function body here error: aborting due to previous error diff --git a/src/test/ui/nll/mir_check_cast_unsafe_fn.stderr b/src/test/ui/nll/mir_check_cast_unsafe_fn.stderr index b08c6f32e6b..98c03e37814 100644 --- a/src/test/ui/nll/mir_check_cast_unsafe_fn.stderr +++ b/src/test/ui/nll/mir_check_cast_unsafe_fn.stderr @@ -4,14 +4,14 @@ warning: not reporting region error due to nll LL | let g: unsafe fn(_) -> _ = f; | ^ -error: borrowed data escapes outside of closure +error: borrowed data escapes outside of function --> $DIR/mir_check_cast_unsafe_fn.rs:20:14 | LL | fn bar<'a>(input: &'a u32, f: fn(&'a u32) -> &'a u32) -> &'static u32 { - | ----- `input` is a reference that is only valid in the closure body + | ----- `input` is a reference that is only valid in the function body ... LL | unsafe { g(input) } - | ^^^^^^^^ `input` escapes the closure body here + | ^^^^^^^^ `input` escapes the function body here error: aborting due to previous error diff --git a/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.rs b/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.rs new file mode 100644 index 00000000000..72d5127c294 --- /dev/null +++ b/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.rs @@ -0,0 +1,29 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-tidy-linelength + +#![feature(infer_outlives_requirements)] + +/* + * We don't infer `T: 'static` outlives relationships by default. + * Instead an additional feature gate `infer_static_outlives_requirements` + * is required. + */ + +struct Foo<U> { + bar: Bar<U> //~ ERROR 22:5: 22:16: the parameter type `U` may not live long enough [E0310] +} +struct Bar<T: 'static> { + x: T, +} + +fn main() {} + diff --git a/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.stderr b/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.stderr new file mode 100644 index 00000000000..775ac215e19 --- /dev/null +++ b/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.stderr @@ -0,0 +1,17 @@ +error[E0310]: the parameter type `U` may not live long enough + --> $DIR/dont-infer-static.rs:22:5 + | +LL | struct Foo<U> { + | - help: consider adding an explicit lifetime bound `U: 'static`... +LL | bar: Bar<U> //~ ERROR 22:5: 22:16: the parameter type `U` may not live long enough [E0310] + | ^^^^^^^^^^^ + | +note: ...so that the type `U` will meet its required lifetime bounds + --> $DIR/dont-infer-static.rs:22:5 + | +LL | bar: Bar<U> //~ ERROR 22:5: 22:16: the parameter type `U` may not live long enough [E0310] + | ^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0310`. diff --git a/src/test/ui/rfc-2093-infer-outlives/infer-static.rs b/src/test/ui/rfc-2093-infer-outlives/infer-static.rs new file mode 100644 index 00000000000..aeca18c24b3 --- /dev/null +++ b/src/test/ui/rfc-2093-infer-outlives/infer-static.rs @@ -0,0 +1,24 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(rustc_attrs)] +#![feature(infer_outlives_requirements)] +#![feature(infer_static_outlives_requirements)] + +#[rustc_outlives] +struct Foo<U> { //~ ERROR 16:1: 18:2: rustc_outlives + bar: Bar<U> +} +struct Bar<T: 'static> { + x: T, +} + +fn main() {} + diff --git a/src/test/ui/rfc-2093-infer-outlives/infer-static.stderr b/src/test/ui/rfc-2093-infer-outlives/infer-static.stderr new file mode 100644 index 00000000000..f167e522df6 --- /dev/null +++ b/src/test/ui/rfc-2093-infer-outlives/infer-static.stderr @@ -0,0 +1,12 @@ +error: rustc_outlives + --> $DIR/infer-static.rs:16:1 + | +LL | / struct Foo<U> { //~ ERROR 16:1: 18:2: rustc_outlives +LL | | bar: Bar<U> +LL | | } + | |_^ + | + = note: U : 'static + +error: aborting due to previous error + diff --git a/src/test/ui/span/issue-40157.nll.stderr b/src/test/ui/span/issue-40157.nll.stderr index def4a308bc7..09e634ba725 100644 --- a/src/test/ui/span/issue-40157.nll.stderr +++ b/src/test/ui/span/issue-40157.nll.stderr @@ -2,11 +2,11 @@ error[E0597]: `foo` does not live long enough --> $DIR/issue-40157.rs:12:53 | LL | {println!("{:?}", match { let foo = vec![1, 2]; foo.get(1) } { x => x });} - | ------------------------------^^^-------------------- - | | | | - | | | `foo` dropped here while still borrowed - | | borrowed value does not live long enough - | borrow later used here + | ------------------------^^^--------- + | | | | + | | | `foo` dropped here while still borrowed + | | borrowed value does not live long enough + | borrow later used here error: aborting due to previous error diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index bb20678d4a1..83b2895e1d6 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -46,9 +46,9 @@ static HOSTS: &'static [&'static str] = &[ static TARGETS: &'static [&'static str] = &[ "aarch64-apple-ios", + "aarch64-fuchsia", "aarch64-linux-android", "aarch64-unknown-cloudabi", - "aarch64-unknown-fuchsia", "aarch64-unknown-linux-gnu", "aarch64-unknown-linux-musl", "arm-linux-androideabi", @@ -101,6 +101,7 @@ static TARGETS: &'static [&'static str] = &[ "wasm32-unknown-unknown", "x86_64-apple-darwin", "x86_64-apple-ios", + "x86_64-fuchsia", "x86_64-linux-android", "x86_64-pc-windows-gnu", "x86_64-pc-windows-msvc", @@ -108,7 +109,6 @@ static TARGETS: &'static [&'static str] = &[ "x86_64-sun-solaris", "x86_64-unknown-cloudabi", "x86_64-unknown-freebsd", - "x86_64-unknown-fuchsia", "x86_64-unknown-linux-gnu", "x86_64-unknown-linux-gnux32", "x86_64-unknown-linux-musl", diff --git a/src/tools/cargo b/src/tools/cargo -Subproject 506eea76edbf7198258265ddabcf320365bc4c5 +Subproject 2cd36b4ed1aef1ae39a30783e006411d1a4218a diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml index 582ba5adfe5..6639ba51b12 100644 --- a/src/tools/compiletest/Cargo.toml +++ b/src/tools/compiletest/Cargo.toml @@ -13,7 +13,7 @@ regex = "0.2" serde = "1.0" serde_json = "1.0" serde_derive = "1.0" -rustfix = "0.3.1" +rustfix = "0.4.1" [target.'cfg(unix)'.dependencies] libc = "0.2" diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index eeb280e1de3..d77261f4959 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -14,7 +14,7 @@ use std::io::prelude::*; use std::io::BufReader; use std::path::{Path, PathBuf}; -use common::{self, Config, Mode}; +use common::{self, CompareMode, Config, Mode}; use util; use extract_gdb_version; @@ -416,7 +416,7 @@ impl TestProps { } } -fn iter_header(testfile: &Path, cfg: Option<&str>, it: &mut FnMut(&str)) { +fn iter_header(testfile: &Path, cfg: Option<&str>, it: &mut dyn FnMut(&str)) { if testfile.is_dir() { return; } @@ -608,7 +608,12 @@ impl Config { common::DebugInfoLldb => name == "lldb", common::Pretty => name == "pretty", _ => false, - } || (self.target != self.host && name == "cross-compile") + } || (self.target != self.host && name == "cross-compile") || + match self.compare_mode { + Some(CompareMode::Nll) => name == "compare-mode-nll", + Some(CompareMode::Polonius) => name == "compare-mode-polonius", + None => false, + } } else { false } diff --git a/src/tools/compiletest/src/read2.rs b/src/tools/compiletest/src/read2.rs index 5bf898f5f1b..f056a041c13 100644 --- a/src/tools/compiletest/src/read2.rs +++ b/src/tools/compiletest/src/read2.rs @@ -21,7 +21,7 @@ mod imp { pub fn read2( out_pipe: ChildStdout, err_pipe: ChildStderr, - data: &mut FnMut(bool, &mut Vec<u8>, bool), + data: &mut dyn FnMut(bool, &mut Vec<u8>, bool), ) -> io::Result<()> { let mut buffer = Vec::new(); out_pipe.read_to_end(&mut buffer)?; @@ -45,7 +45,7 @@ mod imp { pub fn read2( mut out_pipe: ChildStdout, mut err_pipe: ChildStderr, - data: &mut FnMut(bool, &mut Vec<u8>, bool), + data: &mut dyn FnMut(bool, &mut Vec<u8>, bool), ) -> io::Result<()> { unsafe { libc::fcntl(out_pipe.as_raw_fd(), libc::F_SETFL, libc::O_NONBLOCK); @@ -133,7 +133,7 @@ mod imp { pub fn read2( out_pipe: ChildStdout, err_pipe: ChildStderr, - data: &mut FnMut(bool, &mut Vec<u8>, bool), + data: &mut dyn FnMut(bool, &mut Vec<u8>, bool), ) -> io::Result<()> { let mut out = Vec::new(); let mut err = Vec::new(); diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index ad86844cec3..ce7828144cd 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -21,7 +21,7 @@ use filetime::FileTime; use header::TestProps; use json; use regex::Regex; -use rustfix::{apply_suggestions, get_suggestions_from_json}; +use rustfix::{apply_suggestions, get_suggestions_from_json, Filter}; use util::{logv, PathBufExt}; use std::collections::hash_map::DefaultHasher; @@ -2621,7 +2621,11 @@ impl<'test> TestCx<'test> { let unfixed_code = self .load_expected_output_from_path(&self.testpaths.file) .unwrap(); - let suggestions = get_suggestions_from_json(&proc_res.stderr, &HashSet::new()).unwrap(); + let suggestions = get_suggestions_from_json( + &proc_res.stderr, + &HashSet::new(), + Filter::Everything, + ).unwrap(); let fixed_code = apply_suggestions(&unfixed_code, &suggestions).expect(&format!( "failed to apply suggestions for {:?} with rustfix", self.testpaths.file diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs index ade7ae0a4ae..e72f90554d3 100644 --- a/src/tools/error_index_generator/main.rs +++ b/src/tools/error_index_generator/main.rs @@ -44,18 +44,18 @@ impl OutputFormat { } trait Formatter { - fn header(&self, output: &mut Write) -> Result<(), Box<Error>>; - fn title(&self, output: &mut Write) -> Result<(), Box<Error>>; - fn error_code_block(&self, output: &mut Write, info: &ErrorMetadata, - err_code: &str) -> Result<(), Box<Error>>; - fn footer(&self, output: &mut Write) -> Result<(), Box<Error>>; + fn header(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>>; + fn title(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>>; + fn error_code_block(&self, output: &mut dyn Write, info: &ErrorMetadata, + err_code: &str) -> Result<(), Box<dyn Error>>; + fn footer(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>>; } struct HTMLFormatter; struct MarkdownFormatter; impl Formatter for HTMLFormatter { - fn header(&self, output: &mut Write) -> Result<(), Box<Error>> { + fn header(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>> { write!(output, r##"<!DOCTYPE html> <html> <head> @@ -75,13 +75,13 @@ impl Formatter for HTMLFormatter { Ok(()) } - fn title(&self, output: &mut Write) -> Result<(), Box<Error>> { + fn title(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>> { write!(output, "<h1>Rust Compiler Error Index</h1>\n")?; Ok(()) } - fn error_code_block(&self, output: &mut Write, info: &ErrorMetadata, - err_code: &str) -> Result<(), Box<Error>> { + fn error_code_block(&self, output: &mut dyn Write, info: &ErrorMetadata, + err_code: &str) -> Result<(), Box<dyn Error>> { // Enclose each error in a div so they can be shown/hidden en masse. let desc_desc = match info.description { Some(_) => "error-described", @@ -108,7 +108,7 @@ impl Formatter for HTMLFormatter { Ok(()) } - fn footer(&self, output: &mut Write) -> Result<(), Box<Error>> { + fn footer(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>> { write!(output, r##"<script> function onEach(arr, func) {{ if (arr && arr.length > 0 && func) {{ @@ -174,17 +174,17 @@ onEach(document.getElementsByClassName('rust-example-rendered'), function(e) {{ impl Formatter for MarkdownFormatter { #[allow(unused_variables)] - fn header(&self, output: &mut Write) -> Result<(), Box<Error>> { + fn header(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>> { Ok(()) } - fn title(&self, output: &mut Write) -> Result<(), Box<Error>> { + fn title(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>> { write!(output, "# Rust Compiler Error Index\n")?; Ok(()) } - fn error_code_block(&self, output: &mut Write, info: &ErrorMetadata, - err_code: &str) -> Result<(), Box<Error>> { + fn error_code_block(&self, output: &mut dyn Write, info: &ErrorMetadata, + err_code: &str) -> Result<(), Box<dyn Error>> { Ok(match info.description { Some(ref desc) => write!(output, "## {}\n{}\n", err_code, desc)?, None => (), @@ -192,13 +192,13 @@ impl Formatter for MarkdownFormatter { } #[allow(unused_variables)] - fn footer(&self, output: &mut Write) -> Result<(), Box<Error>> { + fn footer(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>> { Ok(()) } } /// Load all the metadata files from `metadata_dir` into an in-memory map. -fn load_all_errors(metadata_dir: &Path) -> Result<ErrorMetadataMap, Box<Error>> { +fn load_all_errors(metadata_dir: &Path) -> Result<ErrorMetadataMap, Box<dyn Error>> { let mut all_errors = BTreeMap::new(); for entry in read_dir(metadata_dir)? { @@ -219,7 +219,7 @@ fn load_all_errors(metadata_dir: &Path) -> Result<ErrorMetadataMap, Box<Error>> /// Output an HTML page for the errors in `err_map` to `output_path`. fn render_error_page<T: Formatter>(err_map: &ErrorMetadataMap, output_path: &Path, - formatter: T) -> Result<(), Box<Error>> { + formatter: T) -> Result<(), Box<dyn Error>> { let mut output_file = File::create(output_path)?; formatter.header(&mut output_file)?; @@ -232,7 +232,7 @@ fn render_error_page<T: Formatter>(err_map: &ErrorMetadataMap, output_path: &Pat formatter.footer(&mut output_file) } -fn main_with_result(format: OutputFormat, dst: &Path) -> Result<(), Box<Error>> { +fn main_with_result(format: OutputFormat, dst: &Path) -> Result<(), Box<dyn Error>> { let build_arch = env::var("CFG_BUILD")?; let metadata_dir = get_metadata_dir(&build_arch); let err_map = load_all_errors(&metadata_dir)?; diff --git a/src/tools/remote-test-client/src/main.rs b/src/tools/remote-test-client/src/main.rs index 2f5275bb5be..011bf551140 100644 --- a/src/tools/remote-test-client/src/main.rs +++ b/src/tools/remote-test-client/src/main.rs @@ -177,7 +177,7 @@ fn start_qemu_emulator(target: &str, _ => panic!("cannot start emulator for: {}"< target), } - fn add_files(w: &mut Write, root: &Path, cur: &Path) { + fn add_files(w: &mut dyn Write, root: &Path, cur: &Path) { for entry in t!(cur.read_dir()) { let entry = t!(entry); let path = entry.path(); @@ -297,7 +297,7 @@ fn run(files: String, args: Vec<String>) { } } -fn send(path: &Path, dst: &mut Write) { +fn send(path: &Path, dst: &mut dyn Write) { t!(dst.write_all(path.file_name().unwrap().to_str().unwrap().as_bytes())); t!(dst.write_all(&[0])); let mut file = t!(File::open(&path)); diff --git a/src/tools/remote-test-server/src/main.rs b/src/tools/remote-test-server/src/main.rs index ae13acd58bb..5116f6662ff 100644 --- a/src/tools/remote-test-server/src/main.rs +++ b/src/tools/remote-test-server/src/main.rs @@ -270,7 +270,7 @@ fn recv<B: BufRead>(dir: &Path, io: &mut B) -> PathBuf { return dst } -fn my_copy(src: &mut Read, which: u8, dst: &Mutex<Write>) { +fn my_copy(src: &mut dyn Read, which: u8, dst: &Mutex<dyn Write>) { let mut b = [0; 1024]; loop { let n = t!(src.read(&mut b)); @@ -290,7 +290,7 @@ fn my_copy(src: &mut Read, which: u8, dst: &Mutex<Write>) { } } -fn read_u32(r: &mut Read) -> u32 { +fn read_u32(r: &mut dyn Read) -> u32 { let mut len = [0; 4]; t!(r.read_exact(&mut len)); ((len[0] as u32) << 24) | diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 5105fc4ca4c..1a2e0f7fb24 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -26,6 +26,7 @@ static LICENSES: &'static [&'static str] = &[ "MIT OR Apache-2.0", "MIT", "Unlicense/MIT", + "Unlicense OR MIT", ]; /// These are exceptions to Rust's permissive licensing policy, and diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index c9bc1b9d849..f68ba0b095b 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -334,7 +334,7 @@ fn get_and_check_lib_features(base_src_path: &Path, } fn map_lib_features(base_src_path: &Path, - mf: &mut FnMut(Result<(&str, Feature), &str>, &Path, usize)) { + mf: &mut dyn FnMut(Result<(&str, Feature), &str>, &Path, usize)) { let mut contents = String::new(); super::walk(base_src_path, &mut |path| super::filter_dirs(path) || path.ends_with("src/test"), diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index 46217a42009..bb041b39785 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -82,13 +82,13 @@ fn filter_dirs(path: &Path) -> bool { skip.iter().any(|p| path.ends_with(p)) } -fn walk_many(paths: &[&Path], skip: &mut FnMut(&Path) -> bool, f: &mut FnMut(&Path)) { +fn walk_many(paths: &[&Path], skip: &mut dyn FnMut(&Path) -> bool, f: &mut dyn FnMut(&Path)) { for path in paths { walk(path, skip, f); } } -fn walk(path: &Path, skip: &mut FnMut(&Path) -> bool, f: &mut FnMut(&Path)) { +fn walk(path: &Path, skip: &mut dyn FnMut(&Path) -> bool, f: &mut dyn FnMut(&Path)) { for entry in t!(fs::read_dir(path), path) { let entry = t!(entry); let kind = t!(entry.file_type()); |
