diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fe6bea9d8dc..e04b1bdfefd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -494,16 +494,11 @@ the version in `Cargo.lock`, so the build can no longer continue. To resolve this, we need to update `Cargo.lock`. Luckily, cargo provides a command to do this easily. -First, go into the `src/` directory since that is where `Cargo.toml` is in -the rust repository. Then run, `cargo update -p rustfmt-nightly` to solve -the problem. - ``` -$ cd src $ cargo update -p rustfmt-nightly ``` -This should change the version listed in `src/Cargo.lock` to the new version you updated +This should change the version listed in `Cargo.lock` to the new version you updated the submodule to. Running `./x.py build` should work now. ## Writing Documentation diff --git a/src/Cargo.lock b/Cargo.lock similarity index 95% rename from src/Cargo.lock rename to Cargo.lock index 94a07f6c91c..6a2b1bc41ef 100644 --- a/src/Cargo.lock +++ b/Cargo.lock @@ -341,7 +341,7 @@ dependencies = [ "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "pulldown-cmark 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -605,12 +605,13 @@ dependencies = [ [[package]] name = "derive_more" -version = "0.11.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.13.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.21 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -658,6 +659,14 @@ dependencies = [ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ena" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "env_logger" version = "0.5.12" @@ -724,7 +733,7 @@ name = "failure_derive" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1331,7 +1340,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1581,7 +1590,7 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "0.4.13" +version = "0.4.24" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1632,6 +1641,15 @@ dependencies = [ "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "pulldown-cmark" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "quick-error" version = "1.2.2" @@ -1660,23 +1678,23 @@ name = "quote" version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "racer" -version = "2.1.9" +version = "2.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)", "humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-syntax 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-syntax 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1798,7 +1816,7 @@ dependencies = [ [[package]] name = "rls" -version = "0.130.5" +version = "1.31.6" dependencies = [ "cargo 0.33.0", "cargo_metadata 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1813,20 +1831,20 @@ dependencies = [ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "ordslice 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "racer 2.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "racer 2.1.13 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rls-analysis 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rls-blacklist 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rls-analysis 0.16.8 (registry+https://github.com/rust-lang/crates.io-index)", + "rls-blacklist 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "rls-data 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)", "rls-rustc 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rls-vfs 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "rls-vfs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-workspace-hack 1.0.0", "rustc_tools_util 0.1.0", - "rustfmt-nightly 0.99.6", + "rustfmt-nightly 1.0.0", "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1837,7 +1855,7 @@ dependencies = [ [[package]] name = "rls-analysis" -version = "0.16.1" +version = "0.16.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "derive-new 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1852,7 +1870,7 @@ dependencies = [ [[package]] name = "rls-blacklist" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1883,9 +1901,10 @@ dependencies = [ [[package]] name = "rls-vfs" -version = "0.4.6" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1932,15 +1951,20 @@ dependencies = [ [[package]] name = "rustc-ap-arena" -version = "274.0.0" +version = "297.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rustc-ap-rustc_data_structures 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_data_structures 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rustc-ap-graphviz" +version = "297.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "rustc-ap-rustc_cratesio_shim" -version = "274.0.0" +version = "297.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1950,7 +1974,7 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_data_structures" -version = "274.0.0" +version = "297.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1958,8 +1982,9 @@ dependencies = [ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_cratesio_shim 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-serialize 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-graphviz 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_cratesio_shim 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-rayon-core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1969,33 +1994,34 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_errors" -version = "274.0.0" +version = "297.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_cratesio_shim 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_data_structures 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-serialize 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-syntax_pos 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_cratesio_shim 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_data_structures 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-syntax_pos 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustc-ap-rustc_target" -version = "274.0.0" +version = "297.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_cratesio_shim 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-serialize 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_cratesio_shim 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_data_structures 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustc-ap-serialize" -version = "274.0.0" +version = "297.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2003,29 +2029,29 @@ dependencies = [ [[package]] name = "rustc-ap-syntax" -version = "274.0.0" +version = "297.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_data_structures 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_errors 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_target 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-serialize 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-syntax_pos 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_data_structures 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_errors 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_target 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-syntax_pos 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustc-ap-syntax_pos" -version = "274.0.0" +version = "297.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-arena 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_data_structures 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-serialize 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-arena 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_data_structures 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2187,7 +2213,7 @@ name = "rustc_data_structures" version = "0.0.0" dependencies = [ "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "ena 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", + "ena 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "graphviz 0.0.0", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2526,7 +2552,7 @@ dependencies = [ [[package]] name = "rustfmt-nightly" -version = "0.99.6" +version = "1.0.0" dependencies = [ "assert_cli 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2541,9 +2567,9 @@ dependencies = [ "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_target 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-syntax 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-syntax_pos 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_target 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-syntax 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-syntax_pos 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-workspace-hack 1.0.0", "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2620,7 +2646,7 @@ name = "serde_derive" version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2762,7 +2788,7 @@ name = "strum_macros" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2792,7 +2818,17 @@ name = "syn" version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syn" +version = "0.15.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2810,7 +2846,7 @@ name = "synstructure" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3237,11 +3273,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum curl-sys 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)" = "721c204978be2143fab0a84b708c49d79d1f6100b8785610f456043a90708870" "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 derive_more 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46c7f14685a20f5dd08e7f754f2ea8cc064d8f4214ae21116c106a2768ba7b9b" +"checksum derive_more 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f57d78cf3bd45270dad4e70c21ec77a960b36c7a841ff9db76aaa775a8fb871" "checksum diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3c2b69f912779fbb121ceb775d74d51e915af17aaebc38d28a592843a2dd0a3a" "checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" "checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" "checksum elasticlunr-rs 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4837d77a1e157489a3933b743fd774ae75074e0e390b2b7f071530048a0d87ee" +"checksum ena 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "25b4e5febb25f08c49f1b07dc33a182729a6b21edfb562b5aef95f78e0dbe5bb" "checksum ena 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "88dc8393b3c7352f94092497f6b52019643e493b6b890eb417cdb7c46117e621" "checksum env_logger 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)" = "f4d7e69c283751083d53d01eac767407343b8b69c4bd70058e08adc2637cb257" "checksum env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "afb070faf94c85d17d50ca44f6ad076bce18ae92f0037d350947240a36e9d42e" @@ -3342,15 +3379,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" "checksum pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a029430f0d744bc3d15dd474d591bed2402b645d024583082b9f63bb936dac6" "checksum proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1b06e2f335f48d24442b35a19df506a835fb3547bc3c06ef27340da9acf5cae7" -"checksum proc-macro2 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "ee5697238f0d893c7f0ecc59c0999f18d2af85e424de441178bcacc9f9e6cf67" +"checksum proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)" = "77619697826f31a02ae974457af0b29b723e5619e113e9397b8b82c6bd253f09" "checksum proptest 0.8.7 (registry+https://github.com/rust-lang/crates.io-index)" = "926d0604475349f463fe44130aae73f2294b5309ab2ca0310b998bd334ef191f" "checksum pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fdf85cda6cadfae5428a54661d431330b312bc767ddbc57adbedc24da66e32" +"checksum pulldown-cmark 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eef52fac62d0ea7b9b4dc7da092aa64ea7ec3d90af6679422d3d7e0e14b6ee15" "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" "checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8" "checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5" -"checksum racer 2.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "5eeddfffd44c83eb03eedf5eb336e9c75303534fe28728a9f6b39a6e6f07ccff" +"checksum racer 2.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "344a53b68d889ab5f44d0617f2bbe1f696abe6a730bd41fa619cfc6fa83a6078" "checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd" "checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" "checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2" @@ -3363,20 +3401,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7" "checksum regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "747ba3b235651f6e2f67dfa8bcdcd073ddb7c243cb21c442fc12395dfcac212d" "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" -"checksum rls-analysis 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9a625690e3bf1204ce27b50f71e508ee788214b2d51e26e4e5db884a83627673" -"checksum rls-blacklist 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e4a9cc2545ccb7e05b355bfe047b8039a6ec12270d5f3c996b766b340a50f7d2" +"checksum rls-analysis 0.16.8 (registry+https://github.com/rust-lang/crates.io-index)" = "2a1d3a2a8c03e380331aefb8b5e3e06f3065602fbaa6657ba0ac649dc99d8537" +"checksum rls-blacklist 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b8ce1fdac03e138c4617ff87b194e1ff57a39bb985a044ccbd8673d30701e411" "checksum rls-data 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a209ce46bb52813cbe0786a7baadc0c1a3f5543ef93f179eda3b841ed72cf2e" "checksum rls-rustc 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9dba7390427aefa953608429701e3665192ca810ba8ae09301e001b7c7bed0" "checksum rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d7c7046dc6a92f2ae02ed302746db4382e75131b9ce20ce967259f6b5867a6a" -"checksum rls-vfs 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ecbc8541b4c341d6271eae10f869dd9d36db871afe184f5b6f9bffbd6ed0373f" -"checksum rustc-ap-arena 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "866fda692855b38f9d6562f0e952c75c6ebe4032d7dd63c608a88e7c4d3f8087" -"checksum rustc-ap-rustc_cratesio_shim 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6c2343e11a97b4eb3bee29cd5f9314ea409a87baee5d3fec8d1516d1633412e" -"checksum rustc-ap-rustc_data_structures 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b88f905f7ab99bf14220a3a87eff60ec143af8136fd0ca8573641c78be532ec8" -"checksum rustc-ap-rustc_errors 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c86fda6cf42e0355b7ecf40f14888340c20b7b864c9d37f6ffca85fe87200652" -"checksum rustc-ap-rustc_target 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8fa8622299beac8c40270e8536a7b0509ca80f227a2b56550019a325fa5a60c0" -"checksum rustc-ap-serialize 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d16cc3d014af9a524c0bed6ca806c3170e39d5987180f0f8ce8fb7df5113576c" -"checksum rustc-ap-syntax 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2a29f280f04f4f45e1bdd773ab5e667b36e757bfbbd01193c330815b9e76d05a" -"checksum rustc-ap-syntax_pos 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c2ea27b65311571c7614deb393691eb18c5e41fd4fd9d8490304e128e1358646" +"checksum rls-vfs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "72d56425bd5aa86d9d4372b76f0381d3b4bda9c0220e71956c9fcc929f45c1f1" +"checksum rustc-ap-arena 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b69fd4a0e8a3ecd99b497965d05f6f04dd2e4601a6146a841dbe4c8e77c2b30c" +"checksum rustc-ap-graphviz 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8136418dbc491bab74aa0565eaa2086754a7a81a5e74a1d84d6168d18e889e7" +"checksum rustc-ap-rustc_cratesio_shim 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a972feda82332d1d05b1ba5a097e915cd9c9c8f1af2bd7b08af09fb88c753d5f" +"checksum rustc-ap-rustc_data_structures 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "582584c6c48b0ece4b8aef3f9bb59d94d17c5665612bc87a71f509e45a3113b5" +"checksum rustc-ap-rustc_errors 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cd852096944d0ac6af1aefa9639a2ae6dede217606ce97f88ff0dcc8c86d6ff6" +"checksum rustc-ap-rustc_target 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "98301a272ecfeec29d2d4e97b07238707c2b89d86fc3a4a5f31a00728f14e288" +"checksum rustc-ap-serialize 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f13510e617e2e322e3297038fd6a7346f2297124af9e10e33a627c5d544e9d" +"checksum rustc-ap-syntax 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0792f5a9ccfc5ec13bb5b0472fa49e145481029c39f6bf5b1a36decc99c3328f" +"checksum rustc-ap-syntax_pos 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0df9f97f41650d23b14f92f7267f8c61089655efb4533d82bf8991f99245198d" "checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395" "checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8" "checksum rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c6d5a683c6ba4ed37959097e88d71c9e8e26659a3cb5be8b389078e7ad45306" @@ -3412,6 +3451,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" "checksum syn 0.13.11 (registry+https://github.com/rust-lang/crates.io-index)" = "14f9bf6292f3a61d2c716723fdb789a41bbe104168e6f496dc6497e531ea1b9b" "checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" +"checksum syn 0.15.21 (registry+https://github.com/rust-lang/crates.io-index)" = "816b7af21405b011a23554ea2dc3f6576dc86ca557047c34098c1d741f10f823" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" "checksum synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "85bb9b7550d063ea184027c9b8c20ac167cd36d3e06b3a40bceb9d746dc1a7b7" "checksum tar 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "69e16840a1e0a1f1a880b739ef1cc6a4b85496c99b8aa786ccffce6e0c15624c" diff --git a/src/Cargo.toml b/Cargo.toml similarity index 53% rename from src/Cargo.toml rename to Cargo.toml index e8c44ea57c2..1e1d7a40967 100644 --- a/src/Cargo.toml +++ b/Cargo.toml @@ -1,31 +1,31 @@ [workspace] members = [ - "bootstrap", - "rustc", - "libstd", - "libtest", - "librustc_codegen_llvm", - "tools/cargotest", - "tools/clippy", - "tools/compiletest", - "tools/error_index_generator", - "tools/linkchecker", - "tools/rustbook", - "tools/unstable-book-gen", - "tools/tidy", - "tools/build-manifest", - "tools/remote-test-client", - "tools/remote-test-server", - "tools/rust-installer", - "tools/cargo", - "tools/rustdoc", - "tools/rls", - "tools/rustfmt", - "tools/miri", - "tools/rustdoc-themes", + "src/bootstrap", + "src/rustc", + "src/libstd", + "src/libtest", + "src/librustc_codegen_llvm", + "src/tools/cargotest", + "src/tools/clippy", + "src/tools/compiletest", + "src/tools/error_index_generator", + "src/tools/linkchecker", + "src/tools/rustbook", + "src/tools/unstable-book-gen", + "src/tools/tidy", + "src/tools/build-manifest", + "src/tools/remote-test-client", + "src/tools/remote-test-server", + "src/tools/rust-installer", + "src/tools/cargo", + "src/tools/rustdoc", + "src/tools/rls", + "src/tools/rustfmt", + "src/tools/miri", + "src/tools/rustdoc-themes", ] exclude = [ - "tools/rls/test_data", + "src/tools/rls/test_data", ] # Curiously, LLVM 7.0 will segfault if compiled with opt-level=3 @@ -50,18 +50,18 @@ debug-assertions = false # so we use a `[patch]` here to override the github repository with our local # vendored copy. [patch."https://github.com/rust-lang/cargo"] -cargo = { path = "tools/cargo" } +cargo = { path = "src/tools/cargo" } [patch.crates-io] # Similar to Cargo above we want the RLS to use a vendored version of `rustfmt` # that we're shipping as well (to ensure that the rustfmt in RLS and the # `rustfmt` executable are the same exact version). -rustfmt-nightly = { path = "tools/rustfmt" } +rustfmt-nightly = { path = "src/tools/rustfmt" } -# See comments in `tools/rustc-workspace-hack/README.md` for what's going on +# See comments in `src/tools/rustc-workspace-hack/README.md` for what's going on # here -rustc-workspace-hack = { path = 'tools/rustc-workspace-hack' } +rustc-workspace-hack = { path = 'src/tools/rustc-workspace-hack' } [patch."https://github.com/rust-lang-nursery/rust-clippy"] -clippy_lints = { path = "tools/clippy/clippy_lints" } -rustc_tools_util = { path = "tools/clippy/rustc_tools_util" } +clippy_lints = { path = "src/tools/clippy/clippy_lints" } +rustc_tools_util = { path = "src/tools/clippy/rustc_tools_util" } diff --git a/RELEASES.md b/RELEASES.md index 15ab97e26fc..a455186859f 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,80 @@ +Version 1.31.0 (2018-12-06) +========================== + +Language +-------- +- 🎉 [This version marks the release of the 2018 edition of Rust.][54057] 🎉 +- [New lifetime elision rules now allow for eliding lifetimes in functions and + impl headers.][54778] E.g. `impl<'a> Reader for BufReader<'a> {}` can now be + `impl Reader for BufReader<'_> {}`. Lifetimes are still required to be defined + in structs. +- [You can now define and use `const` functions.][54835] These are currently + a strict minimal subset of the [const fn RFC][RFC-911]. Refer to the + [language reference][const-reference] for what exactly is available. +- [You can now use tool lints, which allow you to scope lints from external + tools using attributes.][54870] E.g. `#[allow(clippy::filter_map)]`. +- [`#[no_mangle]` and `#[export_name]` attributes can now be located anywhere in + a crate, not just in exported functions.][54451] +- [You can now use parentheses in pattern matches.][54497] + +Compiler +-------- +- [Updated musl to 1.1.20][54430] + +Libraries +--------- +- [You can now convert `num::NonZero*` types to their raw equivalvents using the + `From` trait.][54240] E.g. `u8` now implements `From`. +- [You can now convert a `&Option` into `Option<&T>` and `&mut Option` + into `Option<&mut T>` using the `From` trait.][53218] +- [You can now multiply (`*`) a `time::Duration` by a `u32`.][52813] + + +Stabilized APIs +--------------- +- [`slice::align_to`] +- [`slice::align_to_mut`] +- [`slice::chunks_exact`] +- [`slice::chunks_exact_mut`] +- [`slice::rchunks`] +- [`slice::rchunks_mut`] +- [`slice::rchunks_exact`] +- [`slice::rchunks_exact_mut`] +- [`Option::replace`] + +Cargo +----- +- [Cargo will now download crates in parallel using HTTP/2.][cargo/6005] +- [You can now rename packages in your Cargo.toml][cargo/6319] We have a guide + on [how to use the `package` key in your dependencies.][cargo-rename-reference] + +[52813]: https://github.com/rust-lang/rust/pull/52813/ +[53218]: https://github.com/rust-lang/rust/pull/53218/ +[53555]: https://github.com/rust-lang/rust/issues/53555/ +[54057]: https://github.com/rust-lang/rust/pull/54057/ +[54240]: https://github.com/rust-lang/rust/pull/54240/ +[54430]: https://github.com/rust-lang/rust/pull/54430/ +[54451]: https://github.com/rust-lang/rust/pull/54451/ +[54497]: https://github.com/rust-lang/rust/pull/54497/ +[54778]: https://github.com/rust-lang/rust/pull/54778/ +[54835]: https://github.com/rust-lang/rust/pull/54835/ +[54870]: https://github.com/rust-lang/rust/pull/54870/ +[RFC-911]: https://github.com/rust-lang/rfcs/pull/911 +[`Option::replace`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.replace +[`slice::align_to_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.align_to_mut +[`slice::align_to`]: https://doc.rust-lang.org/std/primitive.slice.html#method.align_to +[`slice::chunks_exact_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.chunks_exact_mut +[`slice::chunks_exact`]: https://doc.rust-lang.org/std/primitive.slice.html#method.chunks_exact +[`slice::rchunks_exact_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.rchunks_mut +[`slice::rchunks_exact`]: https://doc.rust-lang.org/std/primitive.slice.html#method.rchunks_exact +[`slice::rchunks_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.rchunks_mut +[`slice::rchunks`]: https://doc.rust-lang.org/std/primitive.slice.html#method.rchunks +[cargo/6005]: https://github.com/rust-lang/cargo/pull/6005/ +[cargo/6319]: https://github.com/rust-lang/cargo/pull/6319/ +[cargo-rename-reference]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#renaming-dependencies-in-cargotoml +[const-reference]: https://doc.rust-lang.org/reference/items/functions.html#const-functions + + Version 1.30.0 (2018-10-25) ========================== diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index cd48e6aa4c4..d143dffb24b 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -801,7 +801,7 @@ def bootstrap(help_triggered): registry = 'https://example.com' [source.vendored-sources] - directory = '{}/src/vendor' + directory = '{}/vendor' """.format(build.rust_root)) else: if os.path.exists('.cargo'): diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 0aab64465fd..cd8d5642b25 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -851,7 +851,7 @@ impl Step for Src { t!(fs::create_dir_all(&dst_src)); let src_files = [ - "src/Cargo.lock", + "Cargo.lock", ]; // This is the reduced set of paths which will become the rust-src component // (essentially libstd and all of its path dependencies) @@ -949,6 +949,8 @@ impl Step for PlainSourceTarball { "configure", "x.py", "config.toml.example", + "Cargo.toml", + "Cargo.lock", ]; let src_dirs = [ "src", @@ -992,7 +994,7 @@ impl Step for PlainSourceTarball { // Vendor all Cargo dependencies let mut cmd = Command::new(&builder.initial_cargo); cmd.arg("vendor") - .current_dir(&plain_dst_src.join("src")); + .current_dir(&plain_dst_src); builder.run(&mut cmd); } diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 7623ca1e27e..f9b19ffb10d 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -260,22 +260,31 @@ impl Step for TheBook { let compiler = self.compiler; let target = self.target; let name = self.name; - // build book first edition + + // build book builder.ensure(Rustbook { target, - name: INTERNER.intern_string(format!("{}/first-edition", name)), + name: INTERNER.intern_string(name.to_string()), }); - // build book second edition + // building older edition redirects + + let source_name = format!("{}/first-edition", name); builder.ensure(Rustbook { target, - name: INTERNER.intern_string(format!("{}/second-edition", name)), + name: INTERNER.intern_string(source_name), }); - // build book 2018 edition + let source_name = format!("{}/second-edition", name); builder.ensure(Rustbook { target, - name: INTERNER.intern_string(format!("{}/2018-edition", name)), + name: INTERNER.intern_string(source_name), + }); + + let source_name = format!("{}/2018-edition", name); + builder.ensure(Rustbook { + target, + name: INTERNER.intern_string(source_name), }); // build the version info page and CSS @@ -284,11 +293,6 @@ impl Step for TheBook { target, }); - // build the index page - let index = format!("{}/index.md", name); - builder.info(&format!("Documenting book index ({})", target)); - invoke_rustdoc(builder, compiler, target, &index); - // build the redirect pages builder.info(&format!("Documenting book redirect pages ({})", target)); for file in t!(fs::read_dir(builder.src.join("src/doc/book/redirects"))) { diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index e55773011df..c50e6a27033 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1934,6 +1934,7 @@ impl Step for Distcheck { .arg("generate-lockfile") .arg("--manifest-path") .arg(&toml) + .env("__CARGO_TEST_ROOT", &dir) .current_dir(&dir), ); } diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 978e3602e7d..4acc739db57 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -22,6 +22,7 @@ use util::{exe, add_lib_path}; use compile; use native; use channel::GitInfo; +use channel; use cache::Interned; use toolstate::ToolState; @@ -240,6 +241,7 @@ pub fn prepare_tool_cargo( cargo.env("CFG_RELEASE_CHANNEL", &builder.config.channel); cargo.env("CFG_VERSION", builder.rust_version()); + cargo.env("CFG_RELEASE_NUM", channel::CFG_RELEASE_NUM); let info = GitInfo::new(&builder.config, &dir); if let Some(sha) = info.sha() { @@ -258,8 +260,13 @@ pub fn prepare_tool_cargo( } macro_rules! tool { - ($($name:ident, $path:expr, $tool_name:expr, $mode:expr - $(,llvm_tools = $llvm:expr)* $(,is_external_tool = $external:expr)*;)+) => { + ($( + $name:ident, $path:expr, $tool_name:expr, $mode:expr + $(,llvm_tools = $llvm:expr)* + $(,is_external_tool = $external:expr)* + $(,cargo_test_root = $cargo_test_root:expr)* + ; + )+) => { #[derive(Copy, PartialEq, Eq, Clone)] pub enum Tool { $( @@ -281,6 +288,15 @@ macro_rules! tool { $(Tool::$name => false $(|| $llvm)*,)+ } } + + /// Whether this tool requires may run Cargo for test crates, + /// which currently needs setting the environment variable + /// `__CARGO_TEST_ROOT` to separate it from the workspace. + pub fn needs_cargo_test_root(&self) -> bool { + match self { + $(Tool::$name => false $(|| $cargo_test_root)*,)+ + } + } } impl<'a> Builder<'a> { @@ -356,8 +372,9 @@ tool!( UnstableBookGen, "src/tools/unstable-book-gen", "unstable-book-gen", Mode::ToolBootstrap; Tidy, "src/tools/tidy", "tidy", Mode::ToolBootstrap; Linkchecker, "src/tools/linkchecker", "linkchecker", Mode::ToolBootstrap; - CargoTest, "src/tools/cargotest", "cargotest", Mode::ToolBootstrap; - Compiletest, "src/tools/compiletest", "compiletest", Mode::ToolBootstrap, llvm_tools = true; + CargoTest, "src/tools/cargotest", "cargotest", Mode::ToolBootstrap, cargo_test_root = true; + Compiletest, "src/tools/compiletest", "compiletest", Mode::ToolBootstrap, + llvm_tools = true, cargo_test_root = 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, @@ -676,6 +693,11 @@ impl<'a> Builder<'a> { } } + // Set `__CARGO_TEST_ROOT` to the build directory if needed. + if tool.needs_cargo_test_root() { + cmd.env("__CARGO_TEST_ROOT", &self.config.out); + } + add_lib_path(lib_paths, cmd); } diff --git a/src/doc/book b/src/doc/book index e871c459892..616fe4172b6 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit e871c4598925594421d63e929fee292e6e071f97 +Subproject commit 616fe4172b688393aeee5f34935cc25733c9c062 diff --git a/src/doc/nomicon b/src/doc/nomicon index 7f7a597b47e..f8a4e96feb2 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit 7f7a597b47ed6c35c2a0f0ee6a69050fe2d5e013 +Subproject commit f8a4e96feb2e5a6ed1ef170ad40e3509a7755cb4 diff --git a/src/doc/reference b/src/doc/reference index b9fb838054b..60077efda31 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit b9fb838054b8441223c22eeae5b6d8e498071cd0 +Subproject commit 60077efda319c95a89fe39609803c5433567adbf diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index bc342a475c0..2ce92beabb9 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit bc342a475c09b6df8004d518382e6d5b6bcb49f7 +Subproject commit 2ce92beabb912d417a7314d6da83ac9b50dc2afb diff --git a/src/doc/unstable-book/src/language-features/macro-literal-matcher.md b/src/doc/unstable-book/src/language-features/macro-literal-matcher.md index 7e3638fd1cf..870158200de 100644 --- a/src/doc/unstable-book/src/language-features/macro-literal-matcher.md +++ b/src/doc/unstable-book/src/language-features/macro-literal-matcher.md @@ -4,7 +4,7 @@ The tracking issue for this feature is: [#35625] The RFC is: [rfc#1576]. -With this feature gate enabled, the [list of fragment specifiers][frags] gains one more entry: +With this feature gate enabled, the [list of designators] gains one more entry: * `literal`: a literal. Examples: 2, "string", 'c' @@ -12,6 +12,6 @@ A `literal` may be followed by anything, similarly to the `ident` specifier. [rfc#1576]: http://rust-lang.github.io/rfcs/1576-macros-literal-matcher.html [#35625]: https://github.com/rust-lang/rust/issues/35625 -[frags]: ../book/first-edition/macros.html#syntactic-requirements +[list of designators]: ../reference/macros-by-example.html ------------------------ diff --git a/src/doc/unstable-book/src/language-features/plugin.md b/src/doc/unstable-book/src/language-features/plugin.md index b408d5d0805..74bdd4dc3b5 100644 --- a/src/doc/unstable-book/src/language-features/plugin.md +++ b/src/doc/unstable-book/src/language-features/plugin.md @@ -137,8 +137,6 @@ of extensions. See `Registry::register_syntax_extension` and the ## Tips and tricks -Some of the [macro debugging tips](../book/first-edition/macros.html#debugging-macro-code) are applicable. - You can use `syntax::parse` to turn token trees into higher-level syntax elements like expressions: diff --git a/src/etc/gdb_rust_pretty_printing.py b/src/etc/gdb_rust_pretty_printing.py index e6d5ef1a23f..27275ba3795 100755 --- a/src/etc/gdb_rust_pretty_printing.py +++ b/src/etc/gdb_rust_pretty_printing.py @@ -293,15 +293,23 @@ class RustStdVecDequePrinter(object): def to_string(self): (tail, head, data_ptr, cap) = \ rustpp.extract_tail_head_ptr_and_cap_from_std_vecdeque(self.__val) + if head >= tail: + size = head - tail + else: + size = cap + head - tail return (self.__val.type.get_unqualified_type_name() + - ("(len: %i, cap: %i)" % (head - tail, cap))) + ("(len: %i, cap: %i)" % (size, cap))) def children(self): (tail, head, data_ptr, cap) = \ rustpp.extract_tail_head_ptr_and_cap_from_std_vecdeque(self.__val) gdb_ptr = data_ptr.get_wrapped_value() - for index in xrange(tail, head): - yield (str(index), (gdb_ptr + index).dereference()) + if head >= tail: + size = head - tail + else: + size = cap + head - tail + for index in xrange(0, size): + yield (str(index), (gdb_ptr + ((tail + index) % cap)).dereference()) class RustStdBTreeSetPrinter(object): diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 12c19912662..3ca6de191de 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -43,8 +43,8 @@ //! //! `Rc` automatically dereferences to `T` (via the [`Deref`] trait), //! so you can call `T`'s methods on a value of type [`Rc`][`Rc`]. To avoid name -//! clashes with `T`'s methods, the methods of [`Rc`][`Rc`] itself are [associated -//! functions][assoc], called using function-like syntax: +//! clashes with `T`'s methods, the methods of [`Rc`][`Rc`] itself are associated +//! functions, called using function-like syntax: //! //! ``` //! use std::rc::Rc; @@ -234,7 +234,6 @@ //! [downgrade]: struct.Rc.html#method.downgrade //! [upgrade]: struct.Weak.html#method.upgrade //! [`None`]: ../../std/option/enum.Option.html#variant.None -//! [assoc]: ../../book/first-edition/method-syntax.html#associated-functions //! [mutability]: ../../std/cell/index.html#introducing-mutability-inside-of-something-immutable #![stable(feature = "rust1", since = "1.0.0")] diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 1eaff7410ea..22da9dd6e96 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -213,6 +213,22 @@ impl [T] { /// /// This sort is stable (i.e. does not reorder equal elements) and `O(n log n)` worst-case. /// + /// The comparator function must define a total ordering for the elements in the slice. If + /// the ordering is not total, the order of the elements is unspecified. An order is a + /// total order if it is (for all a, b and c): + /// + /// * total and antisymmetric: exactly one of a < b, a == b or a > b is true; and + /// * transitive, a < b and b < c implies a < c. The same must hold for both == and >. + /// + /// For example, while [`f64`] doesn't implement [`Ord`] because `NaN != NaN`, we can use + /// `partial_cmp` as our sort function when we know the slice doesn't contain a `NaN`. + /// + /// ``` + /// let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0]; + /// floats.sort_by(|a, b| a.partial_cmp(b).unwrap()); + /// assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]); + /// ``` + /// /// When applicable, unstable sorting is preferred because it is generally faster than stable /// sorting and it doesn't allocate auxiliary memory. /// See [`sort_unstable_by`](#method.sort_unstable_by). diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index b63b3684964..4f4031e3c4e 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -120,8 +120,8 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize; /// /// `Arc` automatically dereferences to `T` (via the [`Deref`][deref] trait), /// so you can call `T`'s methods on a value of type `Arc`. To avoid name -/// clashes with `T`'s methods, the methods of `Arc` itself are [associated -/// functions][assoc], called using function-like syntax: +/// clashes with `T`'s methods, the methods of `Arc` itself are associated +/// functions, called using function-like syntax: /// /// ``` /// use std::sync::Arc; @@ -146,7 +146,6 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize; /// [downgrade]: struct.Arc.html#method.downgrade /// [upgrade]: struct.Weak.html#method.upgrade /// [`None`]: ../../std/option/enum.Option.html#variant.None -/// [assoc]: ../../book/first-edition/method-syntax.html#associated-functions /// [`RefCell`]: ../../std/cell/struct.RefCell.html /// [`std::sync`]: ../../std/sync/index.html /// [`Arc::clone(&from)`]: #method.clone diff --git a/src/libcore/any.rs b/src/libcore/any.rs index 6b26093439e..c2113dfd2a0 100644 --- a/src/libcore/any.rs +++ b/src/libcore/any.rs @@ -39,7 +39,7 @@ //! //! // Logger function for any type that implements Debug. //! fn log(value: &T) { -//! let value_any = value as &Any; +//! let value_any = value as &dyn Any; //! //! // try to convert our value to a String. If successful, we want to //! // output the String's length as well as its value. If not, it's a @@ -95,7 +95,7 @@ pub trait Any: 'static { /// /// use std::any::{Any, TypeId}; /// - /// fn is_string(s: &Any) -> bool { + /// fn is_string(s: &dyn Any) -> bool { /// TypeId::of::() == s.get_type_id() /// } /// @@ -151,7 +151,7 @@ impl dyn Any { /// ``` /// use std::any::Any; /// - /// fn is_string(s: &Any) { + /// fn is_string(s: &dyn Any) { /// if s.is::() { /// println!("It's a string!"); /// } else { @@ -185,7 +185,7 @@ impl dyn Any { /// ``` /// use std::any::Any; /// - /// fn print_if_string(s: &Any) { + /// fn print_if_string(s: &dyn Any) { /// if let Some(string) = s.downcast_ref::() { /// println!("It's a string({}): '{}'", string.len(), string); /// } else { @@ -218,7 +218,7 @@ impl dyn Any { /// ``` /// use std::any::Any; /// - /// fn modify_if_u32(s: &mut Any) { + /// fn modify_if_u32(s: &mut dyn Any) { /// if let Some(num) = s.downcast_mut::() { /// *num = 42; /// } @@ -256,7 +256,7 @@ impl dyn Any+Send { /// ``` /// use std::any::Any; /// - /// fn is_string(s: &(Any + Send)) { + /// fn is_string(s: &(dyn Any + Send)) { /// if s.is::() { /// println!("It's a string!"); /// } else { @@ -282,7 +282,7 @@ impl dyn Any+Send { /// ``` /// use std::any::Any; /// - /// fn print_if_string(s: &(Any + Send)) { + /// fn print_if_string(s: &(dyn Any + Send)) { /// if let Some(string) = s.downcast_ref::() { /// println!("It's a string({}): '{}'", string.len(), string); /// } else { @@ -308,7 +308,7 @@ impl dyn Any+Send { /// ``` /// use std::any::Any; /// - /// fn modify_if_u32(s: &mut (Any + Send)) { + /// fn modify_if_u32(s: &mut (dyn Any + Send)) { /// if let Some(num) = s.downcast_mut::() { /// *num = 42; /// } @@ -340,7 +340,7 @@ impl dyn Any+Send+Sync { /// ``` /// use std::any::Any; /// - /// fn is_string(s: &(Any + Send + Sync)) { + /// fn is_string(s: &(dyn Any + Send + Sync)) { /// if s.is::() { /// println!("It's a string!"); /// } else { @@ -366,7 +366,7 @@ impl dyn Any+Send+Sync { /// ``` /// use std::any::Any; /// - /// fn print_if_string(s: &(Any + Send + Sync)) { + /// fn print_if_string(s: &(dyn Any + Send + Sync)) { /// if let Some(string) = s.downcast_ref::() { /// println!("It's a string({}): '{}'", string.len(), string); /// } else { @@ -392,7 +392,7 @@ impl dyn Any+Send+Sync { /// ``` /// use std::any::Any; /// - /// fn modify_if_u32(s: &mut (Any + Send + Sync)) { + /// fn modify_if_u32(s: &mut (dyn Any + Send + Sync)) { /// if let Some(num) = s.downcast_mut::() { /// *num = 42; /// } diff --git a/src/libcore/benches/num/mod.rs b/src/libcore/benches/num/mod.rs index 55f0bdb57ec..b57e167b05d 100644 --- a/src/libcore/benches/num/mod.rs +++ b/src/libcore/benches/num/mod.rs @@ -10,3 +10,108 @@ mod flt2dec; mod dec2flt; + +use test::Bencher; +use std::str::FromStr; + +const ASCII_NUMBERS: [&str; 19] = [ + "0", + "1", + "2", + "43", + "765", + "76567", + "987245987", + "-4aa32", + "1786235", + "8723095", + "f##5s", + "83638730", + "-2345", + "562aa43", + "-1", + "-0", + "abc", + "xyz", + "c0ffee", +]; + +macro_rules! from_str_bench { + ($mac:ident, $t:ty) => ( + #[bench] + fn $mac(b: &mut Bencher) { + b.iter(|| { + ASCII_NUMBERS + .iter() + .cycle() + .take(5_000) + .filter_map(|s| <($t)>::from_str(s).ok()) + .max() + }) + } + ) +} + +macro_rules! from_str_radix_bench { + ($mac:ident, $t:ty, $radix:expr) => ( + #[bench] + fn $mac(b: &mut Bencher) { + b.iter(|| { + ASCII_NUMBERS + .iter() + .cycle() + .take(5_000) + .filter_map(|s| <($t)>::from_str_radix(s, $radix).ok()) + .max() + }) + } + ) +} + +from_str_bench!(bench_u8_from_str, u8); +from_str_radix_bench!(bench_u8_from_str_radix_2, u8, 2); +from_str_radix_bench!(bench_u8_from_str_radix_10, u8, 10); +from_str_radix_bench!(bench_u8_from_str_radix_16, u8, 16); +from_str_radix_bench!(bench_u8_from_str_radix_36, u8, 36); + +from_str_bench!(bench_u16_from_str, u16); +from_str_radix_bench!(bench_u16_from_str_radix_2, u16, 2); +from_str_radix_bench!(bench_u16_from_str_radix_10, u16, 10); +from_str_radix_bench!(bench_u16_from_str_radix_16, u16, 16); +from_str_radix_bench!(bench_u16_from_str_radix_36, u16, 36); + +from_str_bench!(bench_u32_from_str, u32); +from_str_radix_bench!(bench_u32_from_str_radix_2, u32, 2); +from_str_radix_bench!(bench_u32_from_str_radix_10, u32, 10); +from_str_radix_bench!(bench_u32_from_str_radix_16, u32, 16); +from_str_radix_bench!(bench_u32_from_str_radix_36, u32, 36); + +from_str_bench!(bench_u64_from_str, u64); +from_str_radix_bench!(bench_u64_from_str_radix_2, u64, 2); +from_str_radix_bench!(bench_u64_from_str_radix_10, u64, 10); +from_str_radix_bench!(bench_u64_from_str_radix_16, u64, 16); +from_str_radix_bench!(bench_u64_from_str_radix_36, u64, 36); + +from_str_bench!(bench_i8_from_str, i8); +from_str_radix_bench!(bench_i8_from_str_radix_2, i8, 2); +from_str_radix_bench!(bench_i8_from_str_radix_10, i8, 10); +from_str_radix_bench!(bench_i8_from_str_radix_16, i8, 16); +from_str_radix_bench!(bench_i8_from_str_radix_36, i8, 36); + +from_str_bench!(bench_i16_from_str, i16); +from_str_radix_bench!(bench_i16_from_str_radix_2, i16, 2); +from_str_radix_bench!(bench_i16_from_str_radix_10, i16, 10); +from_str_radix_bench!(bench_i16_from_str_radix_16, i16, 16); +from_str_radix_bench!(bench_i16_from_str_radix_36, i16, 36); + +from_str_bench!(bench_i32_from_str, i32); +from_str_radix_bench!(bench_i32_from_str_radix_2, i32, 2); +from_str_radix_bench!(bench_i32_from_str_radix_10, i32, 10); +from_str_radix_bench!(bench_i32_from_str_radix_16, i32, 16); +from_str_radix_bench!(bench_i32_from_str_radix_36, i32, 36); + +from_str_bench!(bench_i64_from_str, i64); +from_str_radix_bench!(bench_i64_from_str_radix_2, i64, 2); +from_str_radix_bench!(bench_i64_from_str_radix_10, i64, 10); +from_str_radix_bench!(bench_i64_from_str_radix_16, i64, 16); +from_str_radix_bench!(bench_i64_from_str_radix_36, i64, 36); diff --git a/src/libcore/char/convert.rs b/src/libcore/char/convert.rs index e9ccdd0ea3c..160728f923d 100644 --- a/src/libcore/char/convert.rs +++ b/src/libcore/char/convert.rs @@ -19,7 +19,7 @@ use super::MAX; /// Converts a `u32` to a `char`. /// /// Note that all [`char`]s are valid [`u32`]s, and can be cast to one with -/// [`as`]: +/// `as`: /// /// ``` /// let c = '💯'; @@ -34,7 +34,6 @@ use super::MAX; /// /// [`char`]: ../../std/primitive.char.html /// [`u32`]: ../../std/primitive.u32.html -/// [`as`]: ../../book/first-edition/casting-between-types.html#as /// /// For an unsafe version of this function which ignores these checks, see /// [`from_u32_unchecked`]. @@ -71,7 +70,7 @@ pub fn from_u32(i: u32) -> Option { /// Converts a `u32` to a `char`, ignoring validity. /// /// Note that all [`char`]s are valid [`u32`]s, and can be cast to one with -/// [`as`]: +/// `as`: /// /// ``` /// let c = '💯'; @@ -86,7 +85,6 @@ pub fn from_u32(i: u32) -> Option { /// /// [`char`]: ../../std/primitive.char.html /// [`u32`]: ../../std/primitive.u32.html -/// [`as`]: ../../book/first-edition/casting-between-types.html#as /// /// # Safety /// diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 2903c370df8..fd4189ef50d 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -532,7 +532,7 @@ pub trait Iterator { /// If you're doing some sort of looping for a side effect, it's considered /// more idiomatic to use [`for`] than `map()`. /// - /// [`for`]: ../../book/first-edition/loops.html#for + /// [`for`]: ../../book/ch03-05-control-flow.html#looping-through-a-collection-with-for /// /// # Examples /// @@ -580,7 +580,7 @@ pub trait Iterator { /// cases `for_each` may also be faster than a loop, because it will use /// internal iteration on adaptors like `Chain`. /// - /// [`for`]: ../../book/first-edition/loops.html#for + /// [`for`]: ../../book/ch03-05-control-flow.html#looping-through-a-collection-with-for /// /// # Examples /// @@ -1669,7 +1669,7 @@ pub trait Iterator { /// use a `for` loop with a list of things to build up a result. Those /// can be turned into `fold()`s: /// - /// [`for`]: ../../book/first-edition/loops.html#for + /// [`for`]: ../../book/ch03-05-control-flow.html#looping-through-a-collection-with-for /// /// ``` /// let numbers = [1, 2, 3, 4, 5]; diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index d8eec2bd9a6..56ba10c49f4 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -132,7 +132,6 @@ pub use intrinsics::transmute; /// [uninit]: fn.uninitialized.html /// [clone]: ../clone/trait.Clone.html /// [swap]: fn.swap.html -/// [FFI]: ../../book/first-edition/ffi.html /// [box]: ../../std/boxed/struct.Box.html /// [leak]: ../../std/boxed/struct.Box.html#method.leak /// [into_raw]: ../../std/boxed/struct.Box.html#method.into_raw @@ -479,7 +478,7 @@ pub const fn needs_drop() -> bool { /// /// This has the same effect as allocating space with /// [`mem::uninitialized`][uninit] and then zeroing it out. It is useful for -/// [FFI] sometimes, but should generally be avoided. +/// FFI sometimes, but should generally be avoided. /// /// There is no guarantee that an all-zero byte-pattern represents a valid value of /// some type `T`. If `T` has a destructor and the value is destroyed (due to @@ -490,7 +489,6 @@ pub const fn needs_drop() -> bool { /// many of the same caveats. /// /// [uninit]: fn.uninitialized.html -/// [FFI]: ../../book/first-edition/ffi.html /// [ub]: ../../reference/behavior-considered-undefined.html /// /// # Examples @@ -514,11 +512,9 @@ pub unsafe fn zeroed() -> T { /// **This is incredibly dangerous and should not be done lightly. Deeply /// consider initializing your memory with a default value instead.** /// -/// This is useful for [FFI] functions and initializing arrays sometimes, +/// This is useful for FFI functions and initializing arrays sometimes, /// but should generally be avoided. /// -/// [FFI]: ../../book/first-edition/ffi.html -/// /// # Undefined behavior /// /// It is [undefined behavior][ub] to read uninitialized memory, even just an @@ -689,10 +685,9 @@ pub fn replace(dest: &mut T, mut src: T) -> T { /// While this does call the argument's implementation of [`Drop`][drop], /// it will not release any borrows, as borrows are based on lexical scope. /// -/// This effectively does nothing for -/// [types which implement `Copy`](../../book/first-edition/ownership.html#copy-types), -/// e.g. integers. Such values are copied and _then_ moved into the function, -/// so the value persists after this function call. +/// This effectively does nothing for types which implement `Copy`, e.g. +/// integers. Such values are copied and _then_ moved into the function, so the +/// value persists after this function call. /// /// This function is not magic; it is literally defined as /// @@ -1021,7 +1016,7 @@ impl ManuallyDrop { impl Deref for ManuallyDrop { type Target = T; #[inline] - fn deref(&self) -> &Self::Target { + fn deref(&self) -> &T { &self.value } } @@ -1029,7 +1024,7 @@ impl Deref for ManuallyDrop { #[stable(feature = "manually_drop", since = "1.20.0")] impl DerefMut for ManuallyDrop { #[inline] - fn deref_mut(&mut self) -> &mut Self::Target { + fn deref_mut(&mut self) -> &mut T { &mut self.value } } diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index a7bfc3f5124..e9cf11424ca 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -58,7 +58,7 @@ //! [`NonNull::dangling`] in such cases. //! //! [aliasing]: ../../nomicon/aliasing.html -//! [book]: ../../book/second-edition/ch19-01-unsafe-rust.html#dereferencing-a-raw-pointer +//! [book]: ../../book/ch19-01-unsafe-rust.html#dereferencing-a-raw-pointer //! [ub]: ../../reference/behavior-considered-undefined.html //! [null]: ./fn.null.html //! [zst]: ../../nomicon/exotic-sizes.html#zero-sized-types-zsts diff --git a/src/libcore/raw.rs b/src/libcore/raw.rs index b7597795b5e..3d4bccb4f9d 100644 --- a/src/libcore/raw.rs +++ b/src/libcore/raw.rs @@ -21,11 +21,7 @@ /// The representation of a trait object like `&SomeTrait`. /// /// This struct has the same layout as types like `&SomeTrait` and -/// `Box`. The [Trait Objects chapter of the -/// Book][moreinfo] contains more details about the precise nature of -/// these internals. -/// -/// [moreinfo]: ../../book/first-edition/trait-objects.html#representation +/// `Box`. /// /// `TraitObject` is guaranteed to match layouts, but it is not the /// type of trait objects (e.g. the fields are not directly accessible diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index fece328f51f..8c55a16f3c8 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -1510,6 +1510,22 @@ impl [T] { /// This sort is unstable (i.e. may reorder equal elements), in-place (i.e. does not allocate), /// and `O(n log n)` worst-case. /// + /// The comparator function must define a total ordering for the elements in the slice. If + /// the ordering is not total, the order of the elements is unspecified. An order is a + /// total order if it is (for all a, b and c): + /// + /// * total and antisymmetric: exactly one of a < b, a == b or a > b is true; and + /// * transitive, a < b and b < c implies a < c. The same must hold for both == and >. + /// + /// For example, while [`f64`] doesn't implement [`Ord`] because `NaN != NaN`, we can use + /// `partial_cmp` as our sort function when we know the slice doesn't contain a `NaN`. + /// + /// ``` + /// let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0]; + /// floats.sort_by(|a, b| a.partial_cmp(b).unwrap()); + /// assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]); + /// ``` + /// /// # Current implementation /// /// The current algorithm is based on [pattern-defeating quicksort][pdqsort] by Orson Peters, diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index ddc5676c74e..63b749c548e 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -101,11 +101,11 @@ impl DepGraph { DepGraph { data: Some(Lrc::new(DepGraphData { previous_work_products: prev_work_products, - dep_node_debug: Lock::new(Default::default()), + dep_node_debug: Default::default(), current: Lock::new(CurrentDepGraph::new()), previous: prev_graph, colors: Lock::new(DepNodeColorMap::new(prev_graph_node_count)), - loaded_from_cache: Lock::new(Default::default()), + loaded_from_cache: Default::default(), })), fingerprints: Lrc::new(Lock::new(fingerprints)), } diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index ce1e6780431..b3ba2968c9f 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -244,9 +244,9 @@ pub fn lower_crate( loop_scopes: Vec::new(), is_in_loop_condition: false, anonymous_lifetime_mode: AnonymousLifetimeMode::PassThrough, - type_def_lifetime_params: DefIdMap(), + type_def_lifetime_params: Default::default(), current_hir_id_owner: vec![(CRATE_DEF_INDEX, 0)], - item_local_id_counters: NodeMap(), + item_local_id_counters: Default::default(), node_id_to_hir_id: IndexVec::new(), is_generator: false, is_in_trait_impl: false, @@ -1168,7 +1168,7 @@ impl<'a> LoweringContext<'a> { hir::TyKind::BareFn(P(hir::BareFnTy { generic_params: this.lower_generic_params( &f.generic_params, - &NodeMap(), + &NodeMap::default(), ImplTraitContext::disallowed(), ), unsafety: this.lower_unsafety(f.unsafety), @@ -1866,6 +1866,10 @@ impl<'a> LoweringContext<'a> { } else { self.lower_node_id(segment.id) }; + debug!( + "lower_path_segment: ident={:?} original-id={:?} new-id={:?}", + segment.ident, segment.id, id, + ); hir::PathSegment::new( segment.ident, @@ -2467,7 +2471,7 @@ impl<'a> LoweringContext<'a> { // FIXME: This could probably be done with less rightward drift. Also looks like two control // paths where report_error is called are also the only paths that advance to after // the match statement, so the error reporting could probably just be moved there. - let mut add_bounds: NodeMap> = NodeMap(); + let mut add_bounds: NodeMap> = Default::default(); for pred in &generics.where_clause.predicates { if let WherePredicate::BoundPredicate(ref bound_pred) = *pred { 'next_bound: for bound in &bound_pred.bounds { @@ -2552,7 +2556,7 @@ impl<'a> LoweringContext<'a> { hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate { bound_generic_params: this.lower_generic_params( bound_generic_params, - &NodeMap(), + &NodeMap::default(), ImplTraitContext::disallowed(), ), bounded_ty: this.lower_ty(bounded_ty, ImplTraitContext::disallowed()), @@ -2636,8 +2640,11 @@ impl<'a> LoweringContext<'a> { p: &PolyTraitRef, mut itctx: ImplTraitContext<'_>, ) -> hir::PolyTraitRef { - let bound_generic_params = - self.lower_generic_params(&p.bound_generic_params, &NodeMap(), itctx.reborrow()); + let bound_generic_params = self.lower_generic_params( + &p.bound_generic_params, + &NodeMap::default(), + itctx.reborrow(), + ); let trait_ref = self.with_parent_impl_lifetime_defs( &bound_generic_params, |this| this.lower_trait_ref(&p.trait_ref, itctx), @@ -2952,6 +2959,9 @@ impl<'a> LoweringContext<'a> { name: &mut Name, attrs: &hir::HirVec, ) -> hir::ItemKind { + debug!("lower_use_tree(tree={:?})", tree); + debug!("lower_use_tree: vis = {:?}", vis); + let path = &tree.prefix; let segments = prefix .segments @@ -3019,12 +3029,7 @@ impl<'a> LoweringContext<'a> { hir::VisibilityKind::Inherited => hir::VisibilityKind::Inherited, hir::VisibilityKind::Restricted { ref path, id: _, hir_id: _ } => { let id = this.next_id(); - let mut path = path.clone(); - for seg in path.segments.iter_mut() { - if seg.id.is_some() { - seg.id = Some(this.next_id().node_id); - } - } + let path = this.renumber_segment_ids(path); hir::VisibilityKind::Restricted { path, id: id.node_id, @@ -3065,7 +3070,29 @@ impl<'a> LoweringContext<'a> { hir::ItemKind::Use(path, hir::UseKind::Glob) } UseTreeKind::Nested(ref trees) => { - // Nested imports are desugared into simple imports. + // Nested imports are desugared into simple + // imports. So if we start with + // + // ``` + // pub(x) use foo::{a, b}; + // ``` + // + // we will create three items: + // + // ``` + // pub(x) use foo::a; + // pub(x) use foo::b; + // pub(x) use foo::{}; // <-- this is called the `ListStem` + // ``` + // + // The first two are produced by recursively invoking + // `lower_use_tree` (and indeed there may be things + // like `use foo::{a::{b, c}}` and so forth). They + // wind up being directly added to + // `self.items`. However, the structure of this + // function also requires us to return one item, and + // for that we return the `{}` import (called the + // "`ListStem`"). let prefix = Path { segments, @@ -3109,8 +3136,9 @@ impl<'a> LoweringContext<'a> { hir::VisibilityKind::Inherited => hir::VisibilityKind::Inherited, hir::VisibilityKind::Restricted { ref path, id: _, hir_id: _ } => { let id = this.next_id(); + let path = this.renumber_segment_ids(path); hir::VisibilityKind::Restricted { - path: path.clone(), + path: path, id: id.node_id, hir_id: id.hir_id, } @@ -3133,17 +3161,48 @@ impl<'a> LoweringContext<'a> { }); } - // Privatize the degenerate import base, used only to check - // the stability of `use a::{};`, to avoid it showing up as - // a re-export by accident when `pub`, e.g. in documentation. + // Subtle and a bit hacky: we lower the privacy level + // of the list stem to "private" most of the time, but + // not for "restricted" paths. The key thing is that + // we don't want it to stay as `pub` (with no caveats) + // because that affects rustdoc and also the lints + // about `pub` items. But we can't *always* make it + // private -- particularly not for restricted paths -- + // because it contains node-ids that would then be + // unused, failing the check that HirIds are "densely + // assigned". + match vis.node { + hir::VisibilityKind::Public | + hir::VisibilityKind::Crate(_) | + hir::VisibilityKind::Inherited => { + *vis = respan(prefix.span.shrink_to_lo(), hir::VisibilityKind::Inherited); + } + hir::VisibilityKind::Restricted { .. } => { + // do nothing here, as described in the comment on the match + } + } + let def = self.expect_full_def_from_use(id).next().unwrap_or(Def::Err); let path = P(self.lower_path_extra(def, &prefix, ParamMode::Explicit, None)); - *vis = respan(prefix.span.shrink_to_lo(), hir::VisibilityKind::Inherited); hir::ItemKind::Use(path, hir::UseKind::ListStem) } } } + /// Paths like the visibility path in `pub(super) use foo::{bar, baz}` are repeated + /// many times in the HIR tree; for each occurrence, we need to assign distinct + /// node-ids. (See e.g. #56128.) + fn renumber_segment_ids(&mut self, path: &P) -> P { + debug!("renumber_segment_ids(path = {:?})", path); + let mut path = path.clone(); + for seg in path.segments.iter_mut() { + if seg.id.is_some() { + seg.id = Some(self.next_id().node_id); + } + } + path + } + fn lower_trait_item(&mut self, i: &TraitItem) -> hir::TraitItem { let LoweredNodeId { node_id, hir_id } = self.lower_node_id(i.id); let trait_item_def_id = self.resolver.definitions().local_def_id(node_id); @@ -4537,6 +4596,7 @@ impl<'a> LoweringContext<'a> { VisibilityKind::Public => hir::VisibilityKind::Public, VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar), VisibilityKind::Restricted { ref path, id } => { + debug!("lower_visibility: restricted path id = {:?}", id); let lowered_id = if let Some(owner) = explicit_owner { self.lower_node_id_with_owner(id, owner) } else { diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index 4fbcd83adb5..2917fd7457a 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -28,6 +28,10 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHashe pub(super) struct NodeCollector<'a, 'hir> { /// The crate krate: &'hir Crate, + + /// Source map + source_map: &'a SourceMap, + /// The node map map: Vec>>, /// The parent of this node @@ -54,7 +58,8 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { pub(super) fn root(krate: &'hir Crate, dep_graph: &'a DepGraph, definitions: &'a definitions::Definitions, - hcx: StableHashingContext<'a>) + hcx: StableHashingContext<'a>, + source_map: &'a SourceMap) -> NodeCollector<'a, 'hir> { let root_mod_def_path_hash = definitions.def_path_hash(CRATE_DEF_INDEX); @@ -102,6 +107,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { let mut collector = NodeCollector { krate, + source_map, map: vec![], parent_node: CRATE_NODE_ID, current_signature_dep_index: root_mod_sig_dep_index, @@ -125,7 +131,6 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { pub(super) fn finalize_and_compute_crate_hash(mut self, crate_disambiguator: CrateDisambiguator, cstore: &dyn CrateStore, - source_map: &SourceMap, commandline_args_hash: u64) -> (Vec>>, Svh) { @@ -154,7 +159,8 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { // If we included the full mapping in the SVH, we could only have // reproducible builds by compiling from the same directory. So we just // hash the result of the mapping instead of the mapping itself. - let mut source_file_names: Vec<_> = source_map + let mut source_file_names: Vec<_> = self + .source_map .files() .iter() .filter(|source_file| CrateNum::from_u32(source_file.crate_of_origin) == LOCAL_CRATE) @@ -186,7 +192,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { self.map[id.as_usize()] = Some(entry); } - fn insert(&mut self, id: NodeId, node: Node<'hir>) { + fn insert(&mut self, span: Span, id: NodeId, node: Node<'hir>) { let entry = Entry { parent: self.parent_node, dep_node: if self.currently_in_body { @@ -216,8 +222,11 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { String::new() }; - bug!("inconsistent DepNode for `{}`: \ - current_dep_node_owner={} ({:?}), hir_id.owner={} ({:?}){}", + span_bug!( + span, + "inconsistent DepNode at `{:?}` for `{}`: \ + current_dep_node_owner={} ({:?}), hir_id.owner={} ({:?}){}", + self.source_map.span_to_string(span), node_str, self.definitions .def_path(self.current_dep_node_owner) @@ -225,7 +234,8 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { self.current_dep_node_owner, self.definitions.def_path(hir_id.owner).to_string_no_crate(), hir_id.owner, - forgot_str) + forgot_str, + ) } } @@ -309,12 +319,12 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { debug_assert_eq!(i.hir_id.owner, self.definitions.opt_def_index(i.id).unwrap()); self.with_dep_node_owner(i.hir_id.owner, i, |this| { - this.insert(i.id, Node::Item(i)); + this.insert(i.span, i.id, Node::Item(i)); this.with_parent(i.id, |this| { if let ItemKind::Struct(ref struct_def, _) = i.node { // If this is a tuple-like struct, register the constructor. if !struct_def.is_struct() { - this.insert(struct_def.id(), Node::StructCtor(struct_def)); + this.insert(i.span, struct_def.id(), Node::StructCtor(struct_def)); } } intravisit::walk_item(this, i); @@ -323,7 +333,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { } fn visit_foreign_item(&mut self, foreign_item: &'hir ForeignItem) { - self.insert(foreign_item.id, Node::ForeignItem(foreign_item)); + self.insert(foreign_item.span, foreign_item.id, Node::ForeignItem(foreign_item)); self.with_parent(foreign_item.id, |this| { intravisit::walk_foreign_item(this, foreign_item); @@ -331,7 +341,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { } fn visit_generic_param(&mut self, param: &'hir GenericParam) { - self.insert(param.id, Node::GenericParam(param)); + self.insert(param.span, param.id, Node::GenericParam(param)); intravisit::walk_generic_param(self, param); } @@ -339,7 +349,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { debug_assert_eq!(ti.hir_id.owner, self.definitions.opt_def_index(ti.id).unwrap()); self.with_dep_node_owner(ti.hir_id.owner, ti, |this| { - this.insert(ti.id, Node::TraitItem(ti)); + this.insert(ti.span, ti.id, Node::TraitItem(ti)); this.with_parent(ti.id, |this| { intravisit::walk_trait_item(this, ti); @@ -351,7 +361,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { debug_assert_eq!(ii.hir_id.owner, self.definitions.opt_def_index(ii.id).unwrap()); self.with_dep_node_owner(ii.hir_id.owner, ii, |this| { - this.insert(ii.id, Node::ImplItem(ii)); + this.insert(ii.span, ii.id, Node::ImplItem(ii)); this.with_parent(ii.id, |this| { intravisit::walk_impl_item(this, ii); @@ -365,7 +375,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { } else { Node::Pat(pat) }; - self.insert(pat.id, node); + self.insert(pat.span, pat.id, node); self.with_parent(pat.id, |this| { intravisit::walk_pat(this, pat); @@ -373,7 +383,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { } fn visit_anon_const(&mut self, constant: &'hir AnonConst) { - self.insert(constant.id, Node::AnonConst(constant)); + self.insert(DUMMY_SP, constant.id, Node::AnonConst(constant)); self.with_parent(constant.id, |this| { intravisit::walk_anon_const(this, constant); @@ -381,7 +391,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { } fn visit_expr(&mut self, expr: &'hir Expr) { - self.insert(expr.id, Node::Expr(expr)); + self.insert(expr.span, expr.id, Node::Expr(expr)); self.with_parent(expr.id, |this| { intravisit::walk_expr(this, expr); @@ -390,7 +400,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { fn visit_stmt(&mut self, stmt: &'hir Stmt) { let id = stmt.node.id(); - self.insert(id, Node::Stmt(stmt)); + self.insert(stmt.span, id, Node::Stmt(stmt)); self.with_parent(id, |this| { intravisit::walk_stmt(this, stmt); @@ -399,13 +409,13 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { fn visit_path_segment(&mut self, path_span: Span, path_segment: &'hir PathSegment) { if let Some(id) = path_segment.id { - self.insert(id, Node::PathSegment(path_segment)); + self.insert(path_span, id, Node::PathSegment(path_segment)); } intravisit::walk_path_segment(self, path_span, path_segment); } fn visit_ty(&mut self, ty: &'hir Ty) { - self.insert(ty.id, Node::Ty(ty)); + self.insert(ty.span, ty.id, Node::Ty(ty)); self.with_parent(ty.id, |this| { intravisit::walk_ty(this, ty); @@ -413,7 +423,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { } fn visit_trait_ref(&mut self, tr: &'hir TraitRef) { - self.insert(tr.ref_id, Node::TraitRef(tr)); + self.insert(tr.path.span, tr.ref_id, Node::TraitRef(tr)); self.with_parent(tr.ref_id, |this| { intravisit::walk_trait_ref(this, tr); @@ -427,21 +437,21 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { } fn visit_block(&mut self, block: &'hir Block) { - self.insert(block.id, Node::Block(block)); + self.insert(block.span, block.id, Node::Block(block)); self.with_parent(block.id, |this| { intravisit::walk_block(this, block); }); } fn visit_local(&mut self, l: &'hir Local) { - self.insert(l.id, Node::Local(l)); + self.insert(l.span, l.id, Node::Local(l)); self.with_parent(l.id, |this| { intravisit::walk_local(this, l) }) } fn visit_lifetime(&mut self, lifetime: &'hir Lifetime) { - self.insert(lifetime.id, Node::Lifetime(lifetime)); + self.insert(lifetime.span, lifetime.id, Node::Lifetime(lifetime)); } fn visit_vis(&mut self, visibility: &'hir Visibility) { @@ -450,7 +460,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { VisibilityKind::Crate(_) | VisibilityKind::Inherited => {} VisibilityKind::Restricted { id, .. } => { - self.insert(id, Node::Visibility(visibility)); + self.insert(visibility.span, id, Node::Visibility(visibility)); self.with_parent(id, |this| { intravisit::walk_vis(this, visibility); }); @@ -462,20 +472,20 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { let def_index = self.definitions.opt_def_index(macro_def.id).unwrap(); self.with_dep_node_owner(def_index, macro_def, |this| { - this.insert(macro_def.id, Node::MacroDef(macro_def)); + this.insert(macro_def.span, macro_def.id, Node::MacroDef(macro_def)); }); } fn visit_variant(&mut self, v: &'hir Variant, g: &'hir Generics, item_id: NodeId) { let id = v.node.data.id(); - self.insert(id, Node::Variant(v)); + self.insert(v.span, id, Node::Variant(v)); self.with_parent(id, |this| { intravisit::walk_variant(this, v, g, item_id); }); } fn visit_struct_field(&mut self, field: &'hir StructField) { - self.insert(field.id, Node::Field(field)); + self.insert(field.span, field.id, Node::Field(field)); self.with_parent(field.id, |this| { intravisit::walk_struct_field(this, field); }); diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index dd689154086..eb9bd183fd9 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -36,6 +36,7 @@ use util::nodemap::NodeMap; /// Internally the DefPathTable holds a tree of DefKeys, where each DefKey /// stores the DefIndex of its parent. /// There is one DefPathTable for each crate. +#[derive(Default)] pub struct DefPathTable { index_to_key: [Vec; 2], def_path_hashes: [Vec; 2], @@ -153,7 +154,7 @@ impl Decodable for DefPathTable { /// The definition table containing node definitions. /// It holds the DefPathTable for local DefIds/DefPaths and it also stores a /// mapping from NodeIds to local DefIds. -#[derive(Clone)] +#[derive(Clone, Default)] pub struct Definitions { table: DefPathTable, node_to_def_index: NodeMap, @@ -412,20 +413,8 @@ impl Definitions { /// ascending order. /// /// FIXME: there is probably a better place to put this comment. - pub fn new() -> Definitions { - Definitions { - table: DefPathTable { - index_to_key: [vec![], vec![]], - def_path_hashes: [vec![], vec![]], - }, - node_to_def_index: NodeMap(), - def_index_to_node: [vec![], vec![]], - node_to_hir_id: IndexVec::new(), - parent_modules_of_macro_defs: Default::default(), - expansions_that_defined: Default::default(), - next_disambiguator: Default::default(), - def_index_to_span: Default::default(), - } + pub fn new() -> Self { + Self::default() } pub fn def_path_table(&self) -> &DefPathTable { diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index cf7a7abf95a..ef777abfbc4 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -1032,14 +1032,14 @@ pub fn map_crate<'hir>(sess: &::session::Session, let mut collector = NodeCollector::root(&forest.krate, &forest.dep_graph, &definitions, - hcx); + hcx, + sess.source_map()); intravisit::walk_crate(&mut collector, &forest.krate); let crate_disambiguator = sess.local_crate_disambiguator(); let cmdline_args = sess.opts.dep_tracking_hash(); collector.finalize_and_compute_crate_hash(crate_disambiguator, cstore, - sess.source_map(), cmdline_args) }; diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs index 1c7c1b854da..7c623a1874e 100644 --- a/src/librustc/ich/hcx.rs +++ b/src/librustc/ich/hcx.rs @@ -369,8 +369,7 @@ impl<'a> HashStable> for Span { // times, we cache a stable hash of it and hash that instead of // recursing every time. thread_local! { - static CACHE: RefCell> = - RefCell::new(Default::default()); + static CACHE: RefCell> = Default::default(); } let sub_hash: u64 = CACHE.with(|cache| { diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 64685446e8f..679107160a6 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -317,6 +317,10 @@ impl_stable_hash_for!( ByRef(id, alloc, offset), } ); +impl_stable_hash_for!(struct ::mir::interpret::RawConst<'tcx> { + alloc_id, + ty, +}); impl_stable_hash_for! { impl for struct mir::interpret::Pointer { diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs index cc73dd63816..fda9817cc88 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -121,7 +121,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { parent_def_id, body_id, param_env, - opaque_types: DefIdMap(), + opaque_types: Default::default(), obligations: vec![], }; let value = instantiator.instantiate_opaque_types_in_map(value); diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index 46b12d01829..391bfc428c3 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -29,6 +29,7 @@ use std::{cmp, fmt, mem, u32}; mod taint; +#[derive(Default)] pub struct RegionConstraintCollector<'tcx> { /// For each `RegionVid`, the corresponding `RegionVariableOrigin`. var_infos: IndexVec, @@ -341,17 +342,8 @@ impl TaintDirections { } impl<'tcx> RegionConstraintCollector<'tcx> { - pub fn new() -> RegionConstraintCollector<'tcx> { - RegionConstraintCollector { - var_infos: VarInfos::default(), - data: RegionConstraintData::default(), - lubs: Default::default(), - glbs: Default::default(), - bound_count: 0, - undo_log: Vec::new(), - unification_table: ut::UnificationTable::new(), - any_unifications: false, - } + pub fn new() -> Self { + Self::default() } pub fn num_region_vars(&self) -> usize { diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 01d87bdbf63..22f2023eefb 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -318,6 +318,12 @@ declare_lint! { "warn about missing code example in an item's documentation" } +declare_lint! { + pub PRIVATE_DOC_TESTS, + Allow, + "warn about doc test in private item" +} + declare_lint! { pub WHERE_CLAUSES_OBJECT_SAFETY, Warn, @@ -415,6 +421,7 @@ impl LintPass for HardwiredLints { DUPLICATE_MACRO_EXPORTS, INTRA_DOC_LINK_RESOLUTION_FAILURE, MISSING_DOC_CODE_EXAMPLES, + PRIVATE_DOC_TESTS, WHERE_CLAUSES_OBJECT_SAFETY, PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, MACRO_USE_EXTERN_CRATE, diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 8acbaaa844d..469d77403a3 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -1233,7 +1233,7 @@ pub fn check_ast_crate( let (passes, buffered) = if pre_expansion { ( sess.lint_store.borrow_mut().pre_expansion_passes.take(), - LintBuffer::new(), + LintBuffer::default(), ) } else { ( diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 18922ec5d17..4b878b86252 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -490,15 +490,12 @@ mod levels; pub use self::levels::{LintLevelSets, LintLevelMap}; +#[derive(Default)] pub struct LintBuffer { map: NodeMap>, } impl LintBuffer { - pub fn new() -> LintBuffer { - LintBuffer { map: NodeMap() } - } - pub fn add_lint(&mut self, lint: &'static Lint, id: ast::NodeId, diff --git a/src/librustc/middle/borrowck.rs b/src/librustc/middle/borrowck.rs index c8d513a59f0..633c5841378 100644 --- a/src/librustc/middle/borrowck.rs +++ b/src/librustc/middle/borrowck.rs @@ -18,9 +18,15 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher, #[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)] pub enum SignalledError { SawSomeError, NoErrorsSeen } +impl Default for SignalledError { + fn default() -> SignalledError { + SignalledError::NoErrorsSeen + } +} + impl_stable_hash_for!(enum self::SignalledError { SawSomeError, NoErrorsSeen }); -#[derive(Debug, RustcEncodable, RustcDecodable)] +#[derive(Debug, Default, RustcEncodable, RustcDecodable)] pub struct BorrowCheckResult { pub used_mut_nodes: FxHashSet, pub signalled_any_error: SignalledError, diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 1b258a23462..54a0192d2e8 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -272,9 +272,9 @@ impl<'a, 'tcx> IrMaps<'a, 'tcx> { tcx, num_live_nodes: 0, num_vars: 0, - live_node_map: HirIdMap(), - variable_map: HirIdMap(), - capture_info_map: NodeMap(), + live_node_map: HirIdMap::default(), + variable_map: HirIdMap::default(), + capture_info_map: Default::default(), var_kinds: Vec::new(), lnks: Vec::new(), } @@ -397,7 +397,7 @@ fn visit_fn<'a, 'tcx: 'a>(ir: &mut IrMaps<'a, 'tcx>, fn add_from_pat<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, pat: &P) { // For struct patterns, take note of which fields used shorthand // (`x` rather than `x: x`). - let mut shorthand_field_ids = HirIdSet(); + let mut shorthand_field_ids = HirIdSet::default(); let mut pats = VecDeque::new(); pats.push_back(pat); while let Some(pat) = pats.pop_front() { @@ -691,8 +691,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { s: specials, successors: vec![invalid_node(); num_live_nodes], rwu_table: RWUTable::new(num_live_nodes * num_vars), - break_ln: NodeMap(), - cont_ln: NodeMap(), + break_ln: Default::default(), + cont_ln: Default::default(), } } diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 8c3a3fb6dc1..0009a517dd1 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -408,7 +408,7 @@ fn reachable_set<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) -> let mut reachable_context = ReachableContext { tcx, tables: &ty::TypeckTables::empty(None), - reachable_symbols: NodeSet(), + reachable_symbols: Default::default(), worklist: Vec::new(), any_library, }; diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 79cd8b21f1b..6ff450508d1 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -425,8 +425,8 @@ fn resolve_lifetimes<'tcx>( fn krate<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) -> NamedRegionMap { let krate = tcx.hir.krate(); let mut map = NamedRegionMap { - defs: NodeMap(), - late_bound: NodeSet(), + defs: Default::default(), + late_bound: Default::default(), object_lifetime_defaults: compute_object_lifetime_defaults(tcx), }; { @@ -437,8 +437,8 @@ fn krate<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) -> NamedRegionMap { trait_ref_hack: false, is_in_fn_syntax: false, labels_in_fn: vec![], - xcrate_object_lifetime_defaults: DefIdMap(), - lifetime_uses: &mut DefIdMap(), + xcrate_object_lifetime_defaults: Default::default(), + lifetime_uses: &mut Default::default(), }; for (_, item) in &krate.items { visitor.visit_item(item); @@ -1278,7 +1278,7 @@ fn extract_labels(ctxt: &mut LifetimeContext<'_, '_>, body: &hir::Body) { fn compute_object_lifetime_defaults( tcx: TyCtxt<'_, '_, '_>, ) -> NodeMap> { - let mut map = NodeMap(); + let mut map = NodeMap::default(); for item in tcx.hir.krate().items.values() { match item.node { hir::ItemKind::Struct(_, ref generics) @@ -1432,7 +1432,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } = self; let labels_in_fn = replace(&mut self.labels_in_fn, vec![]); let xcrate_object_lifetime_defaults = - replace(&mut self.xcrate_object_lifetime_defaults, DefIdMap()); + replace(&mut self.xcrate_object_lifetime_defaults, DefIdMap::default()); let mut this = LifetimeContext { tcx: *tcx, map: map, @@ -2741,9 +2741,7 @@ fn insert_late_bound_lifetimes( constrained_by_input.visit_ty(arg_ty); } - let mut appears_in_output = AllCollector { - regions: Default::default(), - }; + let mut appears_in_output = AllCollector::default(); intravisit::walk_fn_ret_ty(&mut appears_in_output, &decl.output); debug!( @@ -2755,9 +2753,7 @@ fn insert_late_bound_lifetimes( // // Subtle point: because we disallow nested bindings, we can just // ignore binders here and scrape up all names we see. - let mut appears_in_where_clause = AllCollector { - regions: Default::default(), - }; + let mut appears_in_where_clause = AllCollector::default(); appears_in_where_clause.visit_generics(generics); for param in &generics.params { @@ -2854,6 +2850,7 @@ fn insert_late_bound_lifetimes( } } + #[derive(Default)] struct AllCollector { regions: FxHashSet, } diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs index 02c0ebcec4f..3250ea266a5 100644 --- a/src/librustc/mir/interpret/allocation.rs +++ b/src/librustc/mir/interpret/allocation.rs @@ -104,7 +104,7 @@ impl Allocation { } pub fn from_byte_aligned_bytes(slice: &[u8]) -> Self { - Allocation::from_bytes(slice, Align::from_bytes(1, 1).unwrap()) + Allocation::from_bytes(slice, Align::from_bytes(1).unwrap()) } pub fn undef(size: Size, align: Align) -> Self { diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index f1c95e0f000..7477343891e 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -16,7 +16,7 @@ use ty::{self, Ty, layout}; use ty::layout::{Size, Align, LayoutError}; use rustc_target::spec::abi::Abi; -use super::{Pointer, InboundsCheck, ScalarMaybeUndef}; +use super::{RawConst, Pointer, InboundsCheck, ScalarMaybeUndef}; use backtrace::Backtrace; @@ -46,6 +46,7 @@ impl ErrorHandled { } } +pub type ConstEvalRawResult<'tcx> = Result, ErrorHandled>; pub type ConstEvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ErrorHandled>; #[derive(Clone, Debug, RustcEncodable, RustcDecodable)] @@ -526,7 +527,7 @@ impl<'tcx, O: fmt::Debug> fmt::Debug for EvalErrorKind<'tcx, O> { write!(f, "tried to interpret an invalid 32-bit value as a char: {}", c), AlignmentCheckFailed { required, has } => write!(f, "tried to access memory with alignment {}, but alignment {} is required", - has.abi(), required.abi()), + has.bytes(), required.bytes()), TypeNotPrimitive(ty) => write!(f, "expected primitive type, got {}", ty), Layout(ref err) => @@ -536,8 +537,9 @@ impl<'tcx, O: fmt::Debug> fmt::Debug for EvalErrorKind<'tcx, O> { MachineError(ref inner) => write!(f, "{}", inner), IncorrectAllocationInformation(size, size2, align, align2) => - write!(f, "incorrect alloc info: expected size {} and align {}, got size {} and \ - align {}", size.bytes(), align.abi(), size2.bytes(), align2.abi()), + write!(f, "incorrect alloc info: expected size {} and align {}, \ + got size {} and align {}", + size.bytes(), align.bytes(), size2.bytes(), align2.bytes()), Panic { ref msg, line, col, ref file } => write!(f, "the evaluated program panicked at '{}', {}:{}:{}", msg, file, line, col), InvalidDiscriminant(val) => diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index ec25431bd1f..9369b6e56f1 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -22,10 +22,10 @@ mod pointer; pub use self::error::{ EvalError, EvalResult, EvalErrorKind, AssertMessage, ConstEvalErr, struct_error, - FrameInfo, ConstEvalResult, ErrorHandled, + FrameInfo, ConstEvalRawResult, ConstEvalResult, ErrorHandled, }; -pub use self::value::{Scalar, ConstValue, ScalarMaybeUndef}; +pub use self::value::{Scalar, ScalarMaybeUndef, RawConst, ConstValue}; pub use self::allocation::{ InboundsCheck, Allocation, AllocationExtra, diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index 47c42c9431a..4bcba9d5467 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -10,12 +10,20 @@ use std::fmt; -use ty::layout::{HasDataLayout, Size}; -use ty::subst::Substs; -use hir::def_id::DefId; +use crate::ty::{Ty, subst::Substs, layout::{HasDataLayout, Size}}; +use crate::hir::def_id::DefId; use super::{EvalResult, Pointer, PointerArithmetic, Allocation, AllocId, sign_extend, truncate}; +/// Represents the result of a raw const operation, pre-validation. +#[derive(Copy, Clone, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, Hash)] +pub struct RawConst<'tcx> { + // the value lives here, at offset 0, and that allocation definitely is a `AllocType::Memory` + // (so you can use `AllocMap::unwrap_memory`). + pub alloc_id: AllocId, + pub ty: Ty<'tcx>, +} + /// Represents a constant value in Rust. Scalar and ScalarPair are optimizations which /// matches the LocalValue optimizations for easy conversions between Value and ConstValue. #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash)] @@ -23,6 +31,7 @@ pub enum ConstValue<'tcx> { /// Never returned from the `const_eval` query, but the HIR contains these frequently in order /// to allow HIR creation to happen for everything before needing to be able to run constant /// evaluation + /// FIXME: The query should then return a type that does not even have this variant. Unevaluated(DefId, &'tcx Substs<'tcx>), /// Used only for types with layout::abi::Scalar ABI and ZSTs diff --git a/src/librustc/session/code_stats.rs b/src/librustc/session/code_stats.rs index b1dcfdfcda0..b8f5ce3cdbc 100644 --- a/src/librustc/session/code_stats.rs +++ b/src/librustc/session/code_stats.rs @@ -71,7 +71,7 @@ impl CodeStats { let info = TypeSizeInfo { kind, type_description: type_desc.to_string(), - align: align.abi(), + align: align.bytes(), overall_size: overall_size.bytes(), packed: packed, opt_discr_size: opt_discr_size.map(|s| s.bytes()), diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index ee6d970750a..c620e092f36 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -802,7 +802,7 @@ macro_rules! options { pub const parse_opt_uint: Option<&'static str> = Some("a number"); pub const parse_panic_strategy: Option<&'static str> = - Some("either `panic` or `abort`"); + Some("either `unwind` or `abort`"); pub const parse_relro_level: Option<&'static str> = Some("one of: `full`, `partial`, or `off`"); pub const parse_sanitizer: Option<&'static str> = diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 8582900b72c..d688d93b808 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -1149,7 +1149,7 @@ pub fn build_session_( local_crate_source_file, working_dir, lint_store: RwLock::new(lint::LintStore::new()), - buffered_lints: Lock::new(Some(lint::LintBuffer::new())), + buffered_lints: Lock::new(Some(Default::default())), one_time_diagnostics: Default::default(), plugin_llvm_passes: OneThread::new(RefCell::new(Vec::new())), plugin_attributes: OneThread::new(RefCell::new(Vec::new())), diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 2761a954cea..48b2b25d6ad 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -1092,13 +1092,27 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { if let Some(found_span) = found_span { err.span_label(found_span, format!("takes {}", found_str)); + // move |_| { ... } + // ^^^^^^^^-- def_span + // + // move |_| { ... } + // ^^^^^-- prefix + let prefix_span = self.tcx.sess.source_map().span_until_non_whitespace(found_span); + // move |_| { ... } + // ^^^-- pipe_span + let pipe_span = if let Some(span) = found_span.trim_start(prefix_span) { + span + } else { + found_span + }; + // Suggest to take and ignore the arguments with expected_args_length `_`s if // found arguments is empty (assume the user just wants to ignore args in this case). // For example, if `expected_args_length` is 2, suggest `|_, _|`. if found_args.is_empty() && is_closure { let underscores = vec!["_"; expected_args.len()].join(", "); err.span_suggestion_with_applicability( - found_span, + pipe_span, &format!( "consider changing the closure to take and ignore the expected argument{}", if expected_args.len() < 2 { diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 923d362c234..a8ce52a8e15 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -446,22 +446,22 @@ impl<'tcx> TypeckTables<'tcx> { pub fn empty(local_id_root: Option) -> TypeckTables<'tcx> { TypeckTables { local_id_root, - type_dependent_defs: ItemLocalMap(), - field_indices: ItemLocalMap(), - user_provided_tys: ItemLocalMap(), + type_dependent_defs: Default::default(), + field_indices: Default::default(), + user_provided_tys: Default::default(), user_provided_sigs: Default::default(), - node_types: ItemLocalMap(), - node_substs: ItemLocalMap(), - user_substs: ItemLocalMap(), - adjustments: ItemLocalMap(), - pat_binding_modes: ItemLocalMap(), - pat_adjustments: ItemLocalMap(), + node_types: Default::default(), + node_substs: Default::default(), + user_substs: Default::default(), + adjustments: Default::default(), + pat_binding_modes: Default::default(), + pat_adjustments: Default::default(), upvar_capture_map: Default::default(), - closure_kind_origins: ItemLocalMap(), - liberated_fn_sigs: ItemLocalMap(), - fru_field_types: ItemLocalMap(), - cast_kinds: ItemLocalMap(), - used_trait_imports: Lrc::new(DefIdSet()), + closure_kind_origins: Default::default(), + liberated_fn_sigs: Default::default(), + fru_field_types: Default::default(), + cast_kinds: Default::default(), + used_trait_imports: Lrc::new(Default::default()), tainted_by_errors: false, free_region_map: Default::default(), concrete_existential_types: Default::default(), diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index d7fb8da7acd..da0a9acede2 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -226,9 +226,10 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { tcx.intern_layout(LayoutDetails::scalar(self, scalar_unit(value))) }; let scalar_pair = |a: Scalar, b: Scalar| { - let align = a.value.align(dl).max(b.value.align(dl)).max(dl.aggregate_align); - let b_offset = a.value.size(dl).abi_align(b.value.align(dl)); - let size = (b_offset + b.value.size(dl)).abi_align(align); + let b_align = b.value.align(dl); + let align = a.value.align(dl).max(b_align).max(dl.aggregate_align); + let b_offset = a.value.size(dl).align_to(b_align.abi); + let size = (b_offset + b.value.size(dl)).align_to(align.abi); LayoutDetails { variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldPlacement::Arbitrary { @@ -257,10 +258,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { bug!("struct cannot be packed and aligned"); } - let pack = { - let pack = repr.pack as u64; - Align::from_bytes(pack, pack).unwrap() - }; + let pack = Align::from_bytes(repr.pack as u64).unwrap(); let mut align = if packed { dl.i8_align @@ -274,7 +272,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { let mut optimize = !repr.inhibit_struct_field_reordering_opt(); if let StructKind::Prefixed(_, align) = kind { - optimize &= align.abi() == 1; + optimize &= align.bytes() == 1; } if optimize { @@ -285,7 +283,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { }; let optimizing = &mut inverse_memory_index[..end]; let field_align = |f: &TyLayout<'_>| { - if packed { f.align.min(pack).abi() } else { f.align.abi() } + if packed { f.align.abi.min(pack) } else { f.align.abi } }; match kind { StructKind::AlwaysSized | @@ -312,13 +310,13 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { let mut offset = Size::ZERO; if let StructKind::Prefixed(prefix_size, prefix_align) = kind { - if packed { - let prefix_align = prefix_align.min(pack); - align = align.max(prefix_align); + let prefix_align = if packed { + prefix_align.min(pack) } else { - align = align.max(prefix_align); - } - offset = prefix_size.abi_align(prefix_align); + prefix_align + }; + align = align.max(AbiAndPrefAlign::new(prefix_align)); + offset = prefix_size.align_to(prefix_align); } for &i in &inverse_memory_index { @@ -333,15 +331,13 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { } // Invariant: offset < dl.obj_size_bound() <= 1<<61 - if packed { - let field_pack = field.align.min(pack); - offset = offset.abi_align(field_pack); - align = align.max(field_pack); - } - else { - offset = offset.abi_align(field.align); - align = align.max(field.align); - } + let field_align = if packed { + field.align.min(AbiAndPrefAlign::new(pack)) + } else { + field.align + }; + offset = offset.align_to(field_align.abi); + align = align.max(field_align); debug!("univariant offset: {:?} field: {:#?}", offset, field); offsets[i as usize] = offset; @@ -352,7 +348,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { if repr.align > 0 { let repr_align = repr.align as u64; - align = align.max(Align::from_bytes(repr_align, repr_align).unwrap()); + align = align.max(AbiAndPrefAlign::new(Align::from_bytes(repr_align).unwrap())); debug!("univariant repr_align: {:?}", repr_align); } @@ -377,7 +373,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { memory_index = inverse_memory_index; } - let size = min_size.abi_align(align); + let size = min_size.align_to(align.abi); let mut abi = Abi::Aggregate { sized }; // Unpack newtype ABIs and find scalar pairs. @@ -394,7 +390,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { (Some((i, field)), None, None) => { // Field fills the struct and it has a scalar or scalar pair ABI. if offsets[i].bytes() == 0 && - align.abi() == field.align.abi() && + align.abi == field.align.abi && size == field.size { match field.abi { // For plain scalars, or vectors of them, we can't unpack @@ -648,7 +644,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { let size = element.size.checked_mul(count, dl) .ok_or(LayoutError::SizeOverflow(ty))?; let align = dl.vector_align(size); - let size = size.abi_align(align); + let size = size.align_to(align.abi); tcx.intern_layout(LayoutDetails { variants: Variants::Single { index: VariantIdx::new(0) }, @@ -680,10 +676,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { bug!("Union cannot be packed and aligned"); } - let pack = { - let pack = def.repr.pack as u64; - Align::from_bytes(pack, pack).unwrap() - }; + let pack = Align::from_bytes(def.repr.pack as u64).unwrap(); let mut align = if packed { dl.i8_align @@ -694,7 +687,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { if def.repr.align > 0 { let repr_align = def.repr.align as u64; align = align.max( - Align::from_bytes(repr_align, repr_align).unwrap()); + AbiAndPrefAlign::new(Align::from_bytes(repr_align).unwrap())); } let optimize = !def.repr.inhibit_union_abi_opt(); @@ -704,12 +697,12 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { for field in &variants[index] { assert!(!field.is_unsized()); - if packed { - let field_pack = field.align.min(pack); - align = align.max(field_pack); + let field_align = if packed { + field.align.min(AbiAndPrefAlign::new(pack)) } else { - align = align.max(field.align); - } + field.align + }; + align = align.max(field_align); // If all non-ZST fields have the same ABI, forward this ABI if optimize && !field.is_zst() { @@ -749,7 +742,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { fields: FieldPlacement::Union(variants[index].len()), abi, align, - size: size.abi_align(align) + size: size.align_to(align.abi) })); } @@ -964,19 +957,19 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { let mut size = Size::ZERO; // We're interested in the smallest alignment, so start large. - let mut start_align = Align::from_bytes(256, 256).unwrap(); - assert_eq!(Integer::for_abi_align(dl, start_align), None); + let mut start_align = Align::from_bytes(256).unwrap(); + assert_eq!(Integer::for_align(dl, start_align), None); // repr(C) on an enum tells us to make a (tag, union) layout, // so we need to grow the prefix alignment to be at least // the alignment of the union. (This value is used both for // determining the alignment of the overall enum, and the // determining the alignment of the payload after the tag.) - let mut prefix_align = min_ity.align(dl); + let mut prefix_align = min_ity.align(dl).abi; if def.repr.c() { for fields in &variants { for field in fields { - prefix_align = prefix_align.max(field.align); + prefix_align = prefix_align.max(field.align.abi); } } } @@ -989,8 +982,8 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { // Find the first field we can't move later // to make room for a larger discriminant. for field in st.fields.index_by_increasing_offset().map(|j| field_layouts[j]) { - if !field.is_zst() || field.align.abi() != 1 { - start_align = start_align.min(field.align); + if !field.is_zst() || field.align.abi.bytes() != 1 { + start_align = start_align.min(field.align.abi); break; } } @@ -1000,7 +993,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { }).collect::, _>>()?; // Align the maximum variant size to the largest alignment. - size = size.abi_align(align); + size = size.align_to(align.abi); if size.bytes() >= dl.obj_size_bound() { return Err(LayoutError::SizeOverflow(ty)); @@ -1036,7 +1029,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { let mut ity = if def.repr.c() || def.repr.int.is_some() { min_ity } else { - Integer::for_abi_align(dl, start_align).unwrap_or(min_ity) + Integer::for_align(dl, start_align).unwrap_or(min_ity) }; // If the alignment is not larger than the chosen discriminant size, @@ -1204,7 +1197,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { let type_desc = format!("{:?}", layout.ty); self.tcx.sess.code_stats.borrow_mut().record_type_size(kind, type_desc, - layout.align, + layout.align.abi, layout.size, packed, opt_discr_size, @@ -1251,7 +1244,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { name: name.to_string(), offset: offset.bytes(), size: field_layout.size.bytes(), - align: field_layout.align.abi(), + align: field_layout.align.abi.bytes(), } } } @@ -1264,7 +1257,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { } else { session::SizeKind::Exact }, - align: layout.align.abi(), + align: layout.align.abi.bytes(), size: if min_size.bytes() == 0 { layout.size.bytes() } else { @@ -1823,7 +1816,9 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { Abi::ScalarPair(ref a, ref b) => { // HACK(nox): We iter on `b` and then `a` because `max_by_key` // returns the last maximum. - let niche = iter::once((b, a.value.size(self).abi_align(b.value.align(self)))) + let niche = iter::once( + (b, a.value.size(self).align_to(b.value.align(self).abi)) + ) .chain(iter::once((a, Size::ZERO))) .filter_map(|(scalar, offset)| scalar_niche(scalar, offset)) .max_by_key(|niche| niche.available); @@ -1994,12 +1989,16 @@ impl_stable_hash_for!(enum ::ty::layout::Primitive { Pointer }); +impl_stable_hash_for!(struct ::ty::layout::AbiAndPrefAlign { + abi, + pref +}); + impl<'gcx> HashStable> for Align { fn hash_stable(&self, hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher) { - self.abi().hash_stable(hcx, hasher); - self.pref().hash_stable(hcx, hasher); + self.bytes().hash_stable(hcx, hasher); } } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index dfdffa2d547..ad200449f89 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -3183,7 +3183,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { /// rather, you should request the vector for a specific type via /// `tcx.inherent_impls(def_id)` so as to minimize your dependencies /// (constructing this map requires touching the entire crate). -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub struct CrateInherentImpls { pub inherent_impls: DefIdMap>>, } diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 89e7f4db502..22bd1e26ba3 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -27,7 +27,7 @@ use middle::stability::{self, DeprecationEntry}; use middle::lib_features::LibFeatures; use middle::lang_items::{LanguageItems, LangItem}; use middle::exported_symbols::{SymbolExportLevel, ExportedSymbol}; -use mir::interpret::ConstEvalResult; +use mir::interpret::{ConstEvalRawResult, ConstEvalResult}; use mir::mono::CodegenUnit; use mir; use mir::interpret::GlobalId; @@ -309,7 +309,7 @@ define_queries! { <'tcx> /// validation. Please add a comment to every use site explaining why using `const_eval` /// isn't sufficient [] fn const_eval_raw: const_eval_raw_dep_node(ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) - -> ConstEvalResult<'tcx>, + -> ConstEvalRawResult<'tcx>, /// Results of evaluating const items or constants embedded in /// other items (such as enum variant explicit discriminants). diff --git a/src/librustc/util/nodemap.rs b/src/librustc/util/nodemap.rs index dbd3e00d9fd..6adfe2cde6c 100644 --- a/src/librustc/util/nodemap.rs +++ b/src/librustc/util/nodemap.rs @@ -10,8 +10,6 @@ //! An efficient hash map for node IDs -#![allow(non_snake_case)] - use hir::def_id::DefId; use hir::{HirId, ItemLocalId}; use syntax::ast; @@ -22,9 +20,7 @@ pub use rustc_data_structures::fx::FxHashSet; macro_rules! define_id_collections { ($map_name:ident, $set_name:ident, $key:ty) => { pub type $map_name = FxHashMap<$key, T>; - pub fn $map_name() -> $map_name { Default::default() } pub type $set_name = FxHashSet<$key>; - pub fn $set_name() -> $set_name { Default::default() } } } diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs index 76fc5a6eeec..3470d6fd0e7 100644 --- a/src/librustc_codegen_llvm/abi.rs +++ b/src/librustc_codegen_llvm/abi.rs @@ -73,7 +73,7 @@ impl ArgAttributesExt for ArgAttributes { if let Some(align) = self.pointee_align { llvm::LLVMRustAddAlignmentAttr(llfn, idx.as_uint(), - align.abi() as u32); + align.bytes() as u32); } regular.for_each_kind(|attr| attr.apply_llfn(idx, llfn)); } @@ -98,7 +98,7 @@ impl ArgAttributesExt for ArgAttributes { if let Some(align) = self.pointee_align { llvm::LLVMRustAddAlignmentCallSiteAttr(callsite, idx.as_uint(), - align.abi() as u32); + align.bytes() as u32); } regular.for_each_kind(|attr| attr.apply_callsite(idx, callsite)); } @@ -204,7 +204,7 @@ impl ArgTypeExt<'ll, 'tcx> for ArgType<'tcx, Ty<'tcx>> { return; } if self.is_sized_indirect() { - OperandValue::Ref(val, None, self.layout.align).store(bx, dst) + OperandValue::Ref(val, None, self.layout.align.abi).store(bx, dst) } else if self.is_unsized_indirect() { bug!("unsized ArgType must be handled through store_fn_arg"); } else if let PassMode::Cast(cast) = self.mode { @@ -214,7 +214,7 @@ impl ArgTypeExt<'ll, 'tcx> for ArgType<'tcx, Ty<'tcx>> { if can_store_through_cast_ptr { let cast_ptr_llty = bx.cx().type_ptr_to(cast.llvm_type(bx.cx())); let cast_dst = bx.pointercast(dst.llval, cast_ptr_llty); - bx.store(val, cast_dst, self.layout.align); + bx.store(val, cast_dst, self.layout.align.abi); } else { // The actual return type is a struct, but the ABI // adaptation code has cast it into some scalar type. The @@ -242,7 +242,7 @@ impl ArgTypeExt<'ll, 'tcx> for ArgType<'tcx, Ty<'tcx>> { // ...and then memcpy it to the intended destination. bx.memcpy( dst.llval, - self.layout.align, + self.layout.align.abi, llscratch, scratch_align, bx.cx().const_usize(self.layout.size.bytes()), @@ -273,7 +273,7 @@ impl ArgTypeExt<'ll, 'tcx> for ArgType<'tcx, Ty<'tcx>> { OperandValue::Pair(next(), next()).store(bx, dst); } PassMode::Indirect(_, Some(_)) => { - OperandValue::Ref(next(), Some(next()), self.layout.align).store(bx, dst); + OperandValue::Ref(next(), Some(next()), self.layout.align.abi).store(bx, dst); } PassMode::Direct(_) | PassMode::Indirect(_, None) | PassMode::Cast(_) => { self.store(bx, next(), dst); @@ -545,7 +545,7 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> { adjust_for_rust_scalar(&mut b_attrs, b, arg.layout, - a.value.size(cx).abi_align(b.value.align(cx)), + a.value.size(cx).align_to(b.value.align(cx).abi), false); arg.mode = PassMode::Pair(a_attrs, b_attrs); return arg; diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index 34e4f4d7e18..d2a99eae340 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -475,7 +475,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { llvm::LLVMBuildAlloca(self.llbuilder, ty, name.as_ptr()) }; - llvm::LLVMSetAlignment(alloca, align.abi() as c_uint); + llvm::LLVMSetAlignment(alloca, align.bytes() as c_uint); alloca } } @@ -494,7 +494,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { llvm::LLVMBuildArrayAlloca(self.llbuilder, ty, len, name.as_ptr()) }; - llvm::LLVMSetAlignment(alloca, align.abi() as c_uint); + llvm::LLVMSetAlignment(alloca, align.bytes() as c_uint); alloca } } @@ -503,7 +503,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { self.count_insn("load"); unsafe { let load = llvm::LLVMBuildLoad(self.llbuilder, ptr, noname()); - llvm::LLVMSetAlignment(load, align.abi() as c_uint); + llvm::LLVMSetAlignment(load, align.bytes() as c_uint); load } } @@ -658,7 +658,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { let align = if flags.contains(MemFlags::UNALIGNED) { 1 } else { - align.abi() as c_uint + align.bytes() as c_uint }; llvm::LLVMSetAlignment(store, align); if flags.contains(MemFlags::VOLATILE) { @@ -893,8 +893,8 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { let dst = self.pointercast(dst, self.cx().type_i8p()); let src = self.pointercast(src, self.cx().type_i8p()); unsafe { - llvm::LLVMRustBuildMemCpy(self.llbuilder, dst, dst_align.abi() as c_uint, - src, src_align.abi() as c_uint, size, is_volatile); + llvm::LLVMRustBuildMemCpy(self.llbuilder, dst, dst_align.bytes() as c_uint, + src, src_align.bytes() as c_uint, size, is_volatile); } } @@ -913,8 +913,8 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { let dst = self.pointercast(dst, self.cx().type_i8p()); let src = self.pointercast(src, self.cx().type_i8p()); unsafe { - llvm::LLVMRustBuildMemMove(self.llbuilder, dst, dst_align.abi() as c_uint, - src, src_align.abi() as c_uint, size, is_volatile); + llvm::LLVMRustBuildMemMove(self.llbuilder, dst, dst_align.bytes() as c_uint, + src, src_align.bytes() as c_uint, size, is_volatile); } } @@ -930,7 +930,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { let intrinsic_key = format!("llvm.memset.p0i8.i{}", ptr_width); let llintrinsicfn = self.cx().get_intrinsic(&intrinsic_key); let ptr = self.pointercast(ptr, self.cx().type_i8p()); - let align = self.cx().const_u32(align.abi() as u32); + let align = self.cx().const_u32(align.bytes() as u32); let volatile = self.cx().const_bool(flags.contains(MemFlags::VOLATILE)); self.call(llintrinsicfn, &[ptr, fill_byte, size, align, volatile], None); } diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs index 2fc505d42db..cd74a5854a9 100644 --- a/src/librustc_codegen_llvm/common.rs +++ b/src/librustc_codegen_llvm/common.rs @@ -357,7 +357,7 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { offset: Size, ) -> PlaceRef<'tcx, &'ll Value> { let init = const_alloc_to_llvm(self, alloc); - let base_addr = self.static_addr_of(init, layout.align, None); + let base_addr = self.static_addr_of(init, layout.align.abi, None); let llval = unsafe { llvm::LLVMConstInBoundsGEP( self.static_bitcast(base_addr, self.type_i8p()), diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs index 821ac931aac..07dde2d0301 100644 --- a/src/librustc_codegen_llvm/consts.rs +++ b/src/librustc_codegen_llvm/consts.rs @@ -94,7 +94,7 @@ fn set_global_alignment(cx: &CodegenCx<'ll, '_>, // Note: GCC and Clang also allow `__attribute__((aligned))` on variables, // which can force it to be smaller. Rust doesn't support this yet. if let Some(min) = cx.sess().target.target.options.min_global_align { - match ty::layout::Align::from_bits(min, min) { + match Align::from_bits(min) { Ok(min) => align = align.max(min), Err(err) => { cx.sess().err(&format!("invalid minimum global alignment: {}", err)); @@ -102,7 +102,7 @@ fn set_global_alignment(cx: &CodegenCx<'ll, '_>, } } unsafe { - llvm::LLVMSetAlignment(gv, align.abi() as u32); + llvm::LLVMSetAlignment(gv, align.bytes() as u32); } } @@ -219,7 +219,7 @@ impl StaticMethods<'tcx> for CodegenCx<'ll, 'tcx> { unsafe { // Upgrade the alignment in cases where the same constant is used with different // alignment requirements - let llalign = align.abi() as u32; + let llalign = align.bytes() as u32; if llalign > llvm::LLVMGetAlignment(gv) { llvm::LLVMSetAlignment(gv, llalign); } diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 1c787a96932..81f2769800d 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -323,7 +323,7 @@ fn fixed_vec_metadata( llvm::LLVMRustDIBuilderCreateArrayType( DIB(cx), size.bits(), - align.abi_bits() as u32, + align.bits() as u32, element_type_metadata, subscripts) }; @@ -465,7 +465,7 @@ fn trait_pointer_metadata( syntax_pos::DUMMY_SP), offset: layout.fields.offset(0), size: data_ptr_field.size, - align: data_ptr_field.align, + align: data_ptr_field.align.abi, flags: DIFlags::FlagArtificial, discriminant: None, }, @@ -474,7 +474,7 @@ fn trait_pointer_metadata( type_metadata: type_metadata(cx, vtable_field.ty, syntax_pos::DUMMY_SP), offset: layout.fields.offset(1), size: vtable_field.size, - align: vtable_field.align, + align: vtable_field.align.abi, flags: DIFlags::FlagArtificial, discriminant: None, }, @@ -787,7 +787,7 @@ fn basic_type_metadata(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType { DIB(cx), name.as_ptr(), size.bits(), - align.abi_bits() as u32, + align.bits() as u32, encoding) }; @@ -818,7 +818,7 @@ fn pointer_type_metadata( DIB(cx), pointee_type_metadata, pointer_size.bits(), - pointer_align.abi_bits() as u32, + pointer_align.bits() as u32, name.as_ptr()) } } @@ -985,13 +985,12 @@ impl<'tcx> StructMemberDescriptionFactory<'tcx> { f.ident.to_string() }; let field = layout.field(cx, i); - let (size, align) = field.size_and_align(); MemberDescription { name, type_metadata: type_metadata(cx, field.ty, self.span), offset: layout.fields.offset(i), - size, - align, + size: field.size, + align: field.align.abi, flags: DIFlags::FlagZero, discriminant: None, } @@ -1109,13 +1108,12 @@ impl<'tcx> UnionMemberDescriptionFactory<'tcx> { -> Vec> { self.variant.fields.iter().enumerate().map(|(i, f)| { let field = self.layout.field(cx, i); - let (size, align) = field.size_and_align(); MemberDescription { name: f.ident.to_string(), type_metadata: type_metadata(cx, field.ty, self.span), offset: Size::ZERO, - size, - align, + size: field.size, + align: field.align.abi, flags: DIFlags::FlagZero, discriminant: None, } @@ -1228,7 +1226,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { type_metadata: variant_type_metadata, offset: Size::ZERO, size: self.layout.size, - align: self.layout.align, + align: self.layout.align.abi, flags: DIFlags::FlagZero, discriminant: None, } @@ -1267,7 +1265,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { type_metadata: variant_type_metadata, offset: Size::ZERO, size: self.layout.size, - align: self.layout.align, + align: self.layout.align.abi, flags: DIFlags::FlagZero, discriminant: Some(self.layout.ty.ty_adt_def().unwrap() .discriminant_for_variant(cx.tcx, i) @@ -1336,7 +1334,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { type_metadata: variant_type_metadata, offset: Size::ZERO, size: variant.size, - align: variant.align, + align: variant.align.abi, flags: DIFlags::FlagZero, discriminant: None, } @@ -1374,7 +1372,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { type_metadata: variant_type_metadata, offset: Size::ZERO, size: self.layout.size, - align: self.layout.align, + align: self.layout.align.abi, flags: DIFlags::FlagZero, discriminant: niche_value, } @@ -1565,7 +1563,7 @@ fn prepare_enum_metadata( file_metadata, UNKNOWN_LINE_NUMBER, discriminant_size.bits(), - discriminant_align.abi_bits() as u32, + discriminant_align.abi.bits() as u32, create_DIArray(DIB(cx), &enumerators_metadata), discriminant_base_type_metadata, true) }; @@ -1587,8 +1585,6 @@ fn prepare_enum_metadata( _ => {} } - let (enum_type_size, enum_type_align) = layout.size_and_align(); - let enum_name = SmallCStr::new(&enum_name); let unique_type_id_str = SmallCStr::new( debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id) @@ -1610,8 +1606,8 @@ fn prepare_enum_metadata( enum_name.as_ptr(), file_metadata, UNKNOWN_LINE_NUMBER, - enum_type_size.bits(), - enum_type_align.abi_bits() as u32, + layout.size.bits(), + layout.align.abi.bits() as u32, DIFlags::FlagZero, None, 0, // RuntimeLang @@ -1659,7 +1655,7 @@ fn prepare_enum_metadata( file_metadata, UNKNOWN_LINE_NUMBER, size.bits(), - align.abi_bits() as u32, + align.abi.bits() as u32, layout.fields.offset(0).bits(), DIFlags::FlagArtificial, discr_metadata)) @@ -1679,7 +1675,7 @@ fn prepare_enum_metadata( file_metadata, UNKNOWN_LINE_NUMBER, size.bits(), - align.abi_bits() as u32, + align.bits() as u32, layout.fields.offset(0).bits(), DIFlags::FlagArtificial, discr_metadata)) @@ -1695,8 +1691,8 @@ fn prepare_enum_metadata( ptr::null_mut(), file_metadata, UNKNOWN_LINE_NUMBER, - enum_type_size.bits(), - enum_type_align.abi_bits() as u32, + layout.size.bits(), + layout.align.abi.bits() as u32, DIFlags::FlagZero, discriminator_metadata, empty_array, @@ -1712,8 +1708,8 @@ fn prepare_enum_metadata( enum_name.as_ptr(), file_metadata, UNKNOWN_LINE_NUMBER, - enum_type_size.bits(), - enum_type_align.abi_bits() as u32, + layout.size.bits(), + layout.align.abi.bits() as u32, DIFlags::FlagZero, None, type_array, @@ -1807,7 +1803,7 @@ fn set_members_of_composite_type(cx: &CodegenCx<'ll, '_>, unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER, member_description.size.bits(), - member_description.align.abi_bits() as u32, + member_description.align.bits() as u32, member_description.offset.bits(), match member_description.discriminant { None => None, @@ -1855,7 +1851,7 @@ fn create_struct_stub( unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER, struct_size.bits(), - struct_align.abi_bits() as u32, + struct_align.bits() as u32, DIFlags::FlagZero, None, empty_array, @@ -1893,7 +1889,7 @@ fn create_union_stub( unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER, union_size.bits(), - union_align.abi_bits() as u32, + union_align.bits() as u32, DIFlags::FlagZero, Some(empty_array), 0, // RuntimeLang @@ -1962,7 +1958,7 @@ pub fn create_global_var_metadata( is_local_to_unit, global, None, - global_align.abi() as u32, + global_align.bytes() as u32, ); } } @@ -2000,7 +1996,7 @@ pub fn create_vtable_metadata( unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER, Size::ZERO.bits(), - cx.tcx.data_layout.pointer_align.abi_bits() as u32, + cx.tcx.data_layout.pointer_align.abi.bits() as u32, DIFlags::FlagArtificial, None, empty_array, diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index 9784cc6cf9c..78bdf678f67 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -106,7 +106,7 @@ impl<'a, 'tcx> CrateDebugContext<'a, 'tcx> { created_files: Default::default(), created_enum_disr_types: Default::default(), type_map: Default::default(), - namespace_map: RefCell::new(DefIdMap()), + namespace_map: RefCell::new(Default::default()), composite_types_completed: Default::default(), } } @@ -201,7 +201,7 @@ impl DebugInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { cx.sess().opts.optimize != config::OptLevel::No, DIFlags::FlagZero, argument_index, - align.abi() as u32, + align.bytes() as u32, ) }; source_loc::set_debug_location(self, diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index b2f1f933da4..3548ccfd5a5 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -110,7 +110,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { let name = &*tcx.item_name(def_id).as_str(); let llret_ty = self.cx().layout_of(ret_ty).llvm_type(self.cx()); - let result = PlaceRef::new_sized(llresult, fn_ty.ret.layout, fn_ty.ret.layout.align); + let result = PlaceRef::new_sized(llresult, fn_ty.ret.layout, fn_ty.ret.layout.align.abi); let simple = get_simple_intrinsic(self.cx(), name); let llval = match name { @@ -158,7 +158,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { } "min_align_of" => { let tp_ty = substs.type_at(0); - self.cx().const_usize(self.cx().align_of(tp_ty).abi()) + self.cx().const_usize(self.cx().align_of(tp_ty).bytes()) } "min_align_of_val" => { let tp_ty = substs.type_at(0); @@ -167,12 +167,12 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { glue::size_and_align_of_dst(self, tp_ty, Some(meta)); llalign } else { - self.cx().const_usize(self.cx().align_of(tp_ty).abi()) + self.cx().const_usize(self.cx().align_of(tp_ty).bytes()) } } "pref_align_of" => { let tp_ty = substs.type_at(0); - self.cx().const_usize(self.cx().align_of(tp_ty).pref()) + self.cx().const_usize(self.cx().layout_of(tp_ty).align.pref.bytes()) } "type_name" => { let tp_ty = substs.type_at(0); @@ -261,7 +261,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { let align = if name == "unaligned_volatile_load" { 1 } else { - self.cx().align_of(tp_ty).abi() as u32 + self.cx().align_of(tp_ty).bytes() as u32 }; unsafe { llvm::LLVMSetAlignment(load, align); @@ -815,7 +815,7 @@ fn try_intrinsic( ) { if bx.cx().sess().no_landing_pads() { bx.call(func, &[data], None); - let ptr_align = bx.tcx().data_layout.pointer_align; + let ptr_align = bx.tcx().data_layout.pointer_align.abi; bx.store(bx.cx().const_null(bx.cx().type_i8p()), dest, ptr_align); } else if wants_msvc_seh(bx.cx().sess()) { codegen_msvc_try(bx, func, data, local_ptr, dest); @@ -890,7 +890,7 @@ fn codegen_msvc_try( // // More information can be found in libstd's seh.rs implementation. let i64p = bx.cx().type_ptr_to(bx.cx().type_i64()); - let ptr_align = bx.tcx().data_layout.pointer_align; + let ptr_align = bx.tcx().data_layout.pointer_align.abi; let slot = bx.alloca(i64p, "slot", ptr_align); bx.invoke(func, &[data], normal.llbb(), catchswitch.llbb(), None); @@ -906,7 +906,7 @@ fn codegen_msvc_try( let funclet = catchpad.catch_pad(cs, &[tydesc, bx.cx().const_i32(0), slot]); let addr = catchpad.load(slot, ptr_align); - let i64_align = bx.tcx().data_layout.i64_align; + let i64_align = bx.tcx().data_layout.i64_align.abi; let arg1 = catchpad.load(addr, i64_align); let val1 = bx.cx().const_i32(1); let gep1 = catchpad.inbounds_gep(addr, &[val1]); @@ -923,7 +923,7 @@ fn codegen_msvc_try( // Note that no invoke is used here because by definition this function // can't panic (that's what it's catching). let ret = bx.call(llfn, &[func, data, local_ptr], None); - let i32_align = bx.tcx().data_layout.i32_align; + let i32_align = bx.tcx().data_layout.i32_align.abi; bx.store(ret, dest, i32_align); } @@ -982,7 +982,7 @@ fn codegen_gnu_try( let vals = catch.landing_pad(lpad_ty, bx.cx().eh_personality(), 1); catch.add_clause(vals, bx.cx().const_null(bx.cx().type_i8p())); let ptr = catch.extract_value(vals, 0); - let ptr_align = bx.tcx().data_layout.pointer_align; + let ptr_align = bx.tcx().data_layout.pointer_align.abi; let bitcast = catch.bitcast(local_ptr, bx.cx().type_ptr_to(bx.cx().type_i8p())); catch.store(ptr, bitcast, ptr_align); catch.ret(bx.cx().const_i32(1)); @@ -991,7 +991,7 @@ fn codegen_gnu_try( // Note that no invoke is used here because by definition this function // can't panic (that's what it's catching). let ret = bx.call(llfn, &[func, data, local_ptr], None); - let i32_align = bx.tcx().data_layout.i32_align; + let i32_align = bx.tcx().data_layout.i32_align.abi; bx.store(ret, dest, i32_align); } @@ -1436,7 +1436,7 @@ fn generic_simd_intrinsic( // Alignment of T, must be a constant integer value: let alignment_ty = bx.cx().type_i32(); - let alignment = bx.cx().const_i32(bx.cx().align_of(in_elem).abi() as i32); + let alignment = bx.cx().const_i32(bx.cx().align_of(in_elem).bytes() as i32); // Truncate the mask vector to a vector of i1s: let (mask, mask_ty) = { @@ -1536,7 +1536,7 @@ fn generic_simd_intrinsic( // Alignment of T, must be a constant integer value: let alignment_ty = bx.cx().type_i32(); - let alignment = bx.cx().const_i32(bx.cx().align_of(in_elem).abi() as i32); + let alignment = bx.cx().const_i32(bx.cx().align_of(in_elem).bytes() as i32); // Truncate the mask vector to a vector of i1s: let (mask, mask_ty) = { diff --git a/src/librustc_codegen_llvm/type_of.rs b/src/librustc_codegen_llvm/type_of.rs index 90c02cddb2b..15b5bdeb44d 100644 --- a/src/librustc_codegen_llvm/type_of.rs +++ b/src/librustc_codegen_llvm/type_of.rs @@ -80,7 +80,7 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, match layout.fields { layout::FieldPlacement::Union(_) => { - let fill = cx.type_padding_filler( layout.size, layout.align); + let fill = cx.type_padding_filler(layout.size, layout.align.abi); let packed = false; match name { None => { @@ -120,23 +120,23 @@ fn struct_llfields<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, let mut packed = false; let mut offset = Size::ZERO; - let mut prev_effective_align = layout.align; + let mut prev_effective_align = layout.align.abi; let mut result: Vec<_> = Vec::with_capacity(1 + field_count * 2); for i in layout.fields.index_by_increasing_offset() { let target_offset = layout.fields.offset(i as usize); let field = layout.field(cx, i); - let effective_field_align = layout.align - .min(field.align) + let effective_field_align = layout.align.abi + .min(field.align.abi) .restrict_for_offset(target_offset); - packed |= effective_field_align.abi() < field.align.abi(); + packed |= effective_field_align < field.align.abi; debug!("struct_llfields: {}: {:?} offset: {:?} target_offset: {:?} \ effective_field_align: {}", - i, field, offset, target_offset, effective_field_align.abi()); + i, field, offset, target_offset, effective_field_align.bytes()); assert!(target_offset >= offset); let padding = target_offset - offset; let padding_align = prev_effective_align.min(effective_field_align); - assert_eq!(offset.abi_align(padding_align) + padding, target_offset); + assert_eq!(offset.align_to(padding_align) + padding, target_offset); result.push(cx.type_padding_filler( padding, padding_align)); debug!(" padding before: {:?}", padding); @@ -151,7 +151,7 @@ fn struct_llfields<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, } let padding = layout.size - offset; let padding_align = prev_effective_align; - assert_eq!(offset.abi_align(padding_align) + padding, layout.size); + assert_eq!(offset.align_to(padding_align) + padding, layout.size); debug!("struct_llfields: pad_bytes: {:?} offset: {:?} stride: {:?}", padding, offset, layout.size); result.push(cx.type_padding_filler(padding, padding_align)); @@ -166,7 +166,7 @@ fn struct_llfields<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, impl<'a, 'tcx> CodegenCx<'a, 'tcx> { pub fn align_of(&self, ty: Ty<'tcx>) -> Align { - self.layout_of(ty).align + self.layout_of(ty).align.abi } pub fn size_of(&self, ty: Ty<'tcx>) -> Size { @@ -174,7 +174,8 @@ impl<'a, 'tcx> CodegenCx<'a, 'tcx> { } pub fn size_and_align_of(&self, ty: Ty<'tcx>) -> (Size, Align) { - self.layout_of(ty).size_and_align() + let layout = self.layout_of(ty); + (layout.size, layout.align.abi) } } @@ -332,7 +333,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> { layout::Pointer => { // If we know the alignment, pick something better than i8. let pointee = if let Some(pointee) = self.pointee_info_at(cx, offset) { - cx.type_pointee_for_abi_align( pointee.align) + cx.type_pointee_for_align(pointee.align) } else { cx.type_i8() }; @@ -376,7 +377,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> { let offset = if index == 0 { Size::ZERO } else { - a.value.size(cx).abi_align(b.value.align(cx)) + a.value.size(cx).align_to(b.value.align(cx).abi) }; self.scalar_llvm_type_at(cx, scalar, offset) } diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index da9cfbb94d1..ec5ca580104 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -1050,6 +1050,10 @@ impl<'a> Linker for WasmLd<'a> { } fn exported_symbols(tcx: TyCtxt, crate_type: CrateType) -> Vec { + if let Some(ref exports) = tcx.sess.target.target.options.override_export_symbols { + return exports.clone() + } + let mut symbols = Vec::new(); let export_threshold = symbol_export::crates_export_threshold(&[crate_type]); diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index dff7e518630..0463da00c89 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -64,7 +64,7 @@ fn reachable_non_generics_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, assert_eq!(cnum, LOCAL_CRATE); if !tcx.sess.opts.output_types.should_codegen() { - return Lrc::new(DefIdMap()) + return Default::default(); } // Check to see if this crate is a "special runtime crate". These @@ -299,7 +299,7 @@ fn upstream_monomorphizations_provider<'a, 'tcx>( let cnums = tcx.all_crate_nums(LOCAL_CRATE); - let mut instances: DefIdMap> = DefIdMap(); + let mut instances: DefIdMap> = Default::default(); let cnum_stable_ids: IndexVec = { let mut cnum_stable_ids = IndexVec::from_elem_n(Fingerprint::ZERO, diff --git a/src/librustc_codegen_ssa/glue.rs b/src/librustc_codegen_ssa/glue.rs index 515f36b5c65..bb28ea74dc0 100644 --- a/src/librustc_codegen_ssa/glue.rs +++ b/src/librustc_codegen_ssa/glue.rs @@ -25,14 +25,12 @@ pub fn size_and_align_of_dst<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( t: Ty<'tcx>, info: Option ) -> (Bx::Value, Bx::Value) { - debug!("calculate size of DST: {}; with lost info: {:?}", - t, info); - if bx.cx().type_is_sized(t) { - let (size, align) = bx.cx().layout_of(t).size_and_align(); - debug!("size_and_align_of_dst t={} info={:?} size: {:?} align: {:?}", - t, info, size, align); - let size = bx.cx().const_usize(size.bytes()); - let align = bx.cx().const_usize(align.abi()); + let layout = bx.cx().layout_of(t); + debug!("size_and_align_of_dst(ty={}, info={:?}): layout: {:?}", + t, info, layout); + if !layout.is_unsized() { + let size = bx.cx().const_usize(layout.size.bytes()); + let align = bx.cx().const_usize(layout.align.abi.bytes()); return (size, align); } match t.sty { @@ -42,24 +40,22 @@ pub fn size_and_align_of_dst<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( (meth::SIZE.get_usize(bx, vtable), meth::ALIGN.get_usize(bx, vtable)) } ty::Slice(_) | ty::Str => { - let unit = t.sequence_element_type(bx.tcx()); + let unit = layout.field(bx.cx(), 0); // The info in this case is the length of the str, so the size is that // times the unit size. - let (size, align) = bx.cx().layout_of(unit).size_and_align(); - (bx.mul(info.unwrap(), bx.cx().const_usize(size.bytes())), - bx.cx().const_usize(align.abi())) + (bx.mul(info.unwrap(), bx.cx().const_usize(unit.size.bytes())), + bx.cx().const_usize(unit.align.abi.bytes())) } _ => { // First get the size of all statically known fields. // Don't use size_of because it also rounds up to alignment, which we // want to avoid, as the unsized field's alignment could be smaller. assert!(!t.is_simd()); - let layout = bx.cx().layout_of(t); debug!("DST {} layout: {:?}", t, layout); let i = layout.fields.count() - 1; let sized_size = layout.fields.offset(i).bytes(); - let sized_align = layout.align.abi(); + let sized_align = layout.align.abi.bytes(); debug!("DST {} statically sized prefix size: {} align: {}", t, sized_size, sized_align); let sized_size = bx.cx().const_usize(sized_size); diff --git a/src/librustc_codegen_ssa/meth.rs b/src/librustc_codegen_ssa/meth.rs index 24be932141c..d70fcf60fdf 100644 --- a/src/librustc_codegen_ssa/meth.rs +++ b/src/librustc_codegen_ssa/meth.rs @@ -41,7 +41,7 @@ impl<'a, 'tcx: 'a> VirtualIndex { llvtable, bx.cx().type_ptr_to(bx.cx().fn_ptr_backend_type(fn_ty)) ); - let ptr_align = bx.tcx().data_layout.pointer_align; + let ptr_align = bx.tcx().data_layout.pointer_align.abi; let gep = bx.inbounds_gep(llvtable, &[bx.cx().const_usize(self.0)]); let ptr = bx.load(gep, ptr_align); bx.nonnull_metadata(ptr); @@ -59,7 +59,7 @@ impl<'a, 'tcx: 'a> VirtualIndex { debug!("get_int({:?}, {:?})", llvtable, self); let llvtable = bx.pointercast(llvtable, bx.cx().type_ptr_to(bx.cx().type_isize())); - let usize_align = bx.tcx().data_layout.pointer_align; + let usize_align = bx.tcx().data_layout.pointer_align.abi; let gep = bx.inbounds_gep(llvtable, &[bx.cx().const_usize(self.0)]); let ptr = bx.load(gep, usize_align); // Vtable loads are invariant @@ -100,19 +100,19 @@ pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>( }) }); - let (size, align) = cx.layout_of(ty).size_and_align(); + let layout = cx.layout_of(ty); // ///////////////////////////////////////////////////////////////////////////////////////////// // If you touch this code, be sure to also make the corresponding changes to // `get_vtable` in rust_mir/interpret/traits.rs // ///////////////////////////////////////////////////////////////////////////////////////////// let components: Vec<_> = [ cx.get_fn(monomorphize::resolve_drop_in_place(cx.tcx(), ty)), - cx.const_usize(size.bytes()), - cx.const_usize(align.abi()) + cx.const_usize(layout.size.bytes()), + cx.const_usize(layout.align.abi.bytes()) ].iter().cloned().chain(methods).collect(); let vtable_const = cx.const_struct(&components, false); - let align = cx.data_layout().pointer_align; + let align = cx.data_layout().pointer_align.abi; let vtable = cx.static_addr_of(vtable_const, align, Some("vtable")); cx.create_vtable_metadata(ty, vtable); diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index 1702ad19b76..75a6f07124a 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -280,7 +280,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { scratch.llval } Ref(llval, _, align) => { - assert_eq!(align.abi(), op.layout.align.abi(), + assert_eq!(align, op.layout.align.abi, "return place is unaligned!"); llval } @@ -288,7 +288,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let addr = bx.pointercast(llslot, bx.cx().type_ptr_to( bx.cx().cast_backend_type(&cast_ty) )); - bx.load(addr, self.fn_ty.ret.layout.align) + bx.load(addr, self.fn_ty.ret.layout.align.abi) } }; bx.ret(llval); @@ -386,9 +386,9 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let filename = bx.cx().const_str_slice(filename); let line = bx.cx().const_u32(loc.line as u32); let col = bx.cx().const_u32(loc.col.to_usize() as u32 + 1); - let align = tcx.data_layout.aggregate_align - .max(tcx.data_layout.i32_align) - .max(tcx.data_layout.pointer_align); + let align = tcx.data_layout.aggregate_align.abi + .max(tcx.data_layout.i32_align.abi) + .max(tcx.data_layout.pointer_align.abi); // Put together the arguments to the panic entry point. let (lang_item, args) = match *msg { @@ -522,9 +522,9 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let filename = bx.cx().const_str_slice(filename); let line = bx.cx().const_u32(loc.line as u32); let col = bx.cx().const_u32(loc.col.to_usize() as u32 + 1); - let align = tcx.data_layout.aggregate_align - .max(tcx.data_layout.i32_align) - .max(tcx.data_layout.pointer_align); + let align = tcx.data_layout.aggregate_align.abi + .max(tcx.data_layout.i32_align.abi) + .max(tcx.data_layout.pointer_align.abi); let str = format!( "Attempted to instantiate uninhabited type {} using mem::{}", @@ -800,12 +800,12 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { (scratch.llval, scratch.align, true) } _ => { - (op.immediate_or_packed_pair(bx), arg.layout.align, false) + (op.immediate_or_packed_pair(bx), arg.layout.align.abi, false) } } } Ref(llval, _, align) => { - if arg.is_indirect() && align.abi() < arg.layout.align.abi() { + if arg.is_indirect() && align < arg.layout.align.abi { // `foo(packed.large_field)`. We can't pass the (unaligned) field directly. I // think that ATM (Rust 1.16) we only pass temporaries, but we shouldn't // have scary latent bugs around. @@ -826,7 +826,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let addr = bx.pointercast(llval, bx.cx().type_ptr_to( bx.cx().cast_backend_type(&ty)) ); - llval = bx.load(addr, align.min(arg.layout.align)); + llval = bx.load(addr, align.min(arg.layout.align.abi)); } else { // We can't use `PlaceRef::load` here because the argument // may have a type we don't treat as immediate, but the ABI @@ -1006,7 +1006,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.codegen_place(bx, dest) }; if fn_ret.is_indirect() { - if dest.align.abi() < dest.layout.align.abi() { + if dest.align < dest.layout.align.abi { // Currently, MIR code generation does not create calls // that store directly to fields of packed structs (in // fact, the calls it creates write only to temps), @@ -1062,7 +1062,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let src = self.codegen_operand(bx, src); let llty = bx.cx().backend_type(src.layout); let cast_ptr = bx.pointercast(dst.llval, bx.cx().type_ptr_to(llty)); - let align = src.layout.align.min(dst.layout.align); + let align = src.layout.align.abi.min(dst.align); src.val.store(bx, PlaceRef::new_sized(cast_ptr, src.layout, align)); } diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs index 0579afe1d49..fdc9a37a9eb 100644 --- a/src/librustc_codegen_ssa/mir/mod.rs +++ b/src/librustc_codegen_ssa/mir/mod.rs @@ -304,7 +304,7 @@ pub fn codegen_mir<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( if local == mir::RETURN_PLACE && fx.fn_ty.ret.is_indirect() { debug!("alloc: {:?} (return place) -> place", local); let llretptr = fx.cx.get_param(llfn, 0); - LocalRef::Place(PlaceRef::new_sized(llretptr, layout, layout.align)) + LocalRef::Place(PlaceRef::new_sized(llretptr, layout, layout.align.abi)) } else if memory_locals.contains(local) { debug!("alloc: {:?} -> place", local); if layout.is_unsized() { @@ -555,7 +555,7 @@ fn arg_local_refs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( let llarg = bx.cx().get_param(bx.llfn(), llarg_idx as c_uint); bx.set_value_name(llarg, &name); llarg_idx += 1; - PlaceRef::new_sized(llarg, arg.layout, arg.layout.align) + PlaceRef::new_sized(llarg, arg.layout, arg.layout.align.abi) } else if arg.is_unsized_indirect() { // As the storage for the indirect argument lives during // the whole function call, we just copy the fat pointer. diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs index d574d89d67e..f6917906d4a 100644 --- a/src/librustc_codegen_ssa/mir/operand.rs +++ b/src/librustc_codegen_ssa/mir/operand.rs @@ -152,7 +152,7 @@ impl<'a, 'tcx: 'a, V: CodegenObject> OperandRef<'tcx, V> { llval: llptr, llextra, layout, - align: layout.align, + align: layout.align.abi, } } @@ -228,7 +228,7 @@ impl<'a, 'tcx: 'a, V: CodegenObject> OperandRef<'tcx, V> { OperandValue::Immediate(a_llval) } else { assert_eq!(offset, a.value.size(bx.cx()) - .abi_align(b.value.align(bx.cx()))); + .align_to(b.value.align(bx.cx()).abi)); assert_eq!(field.size, b.value.size(bx.cx())); OperandValue::Immediate(b_llval) } @@ -348,8 +348,8 @@ impl<'a, 'tcx: 'a, V: CodegenObject> OperandValue { }; // FIXME: choose an appropriate alignment, or use dynamic align somehow - let max_align = Align::from_bits(128, 128).unwrap(); - let min_align = Align::from_bits(8, 8).unwrap(); + let max_align = Align::from_bits(128).unwrap(); + let min_align = Align::from_bits(8).unwrap(); // Allocate an appropriate region on the stack, and copy the value into it let (llsize, _) = glue::size_and_align_of_dst(bx, unsized_ty, Some(llextra)); @@ -470,7 +470,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.load_operand(PlaceRef::new_sized( bx.cx().const_undef(bx.cx().type_ptr_to(bx.cx().backend_type(layout))), layout, - layout.align, + layout.align.abi, )) }) } diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs index 5b36ee8fd18..e6fd6dfca73 100644 --- a/src/librustc_codegen_ssa/mir/place.rs +++ b/src/librustc_codegen_ssa/mir/place.rs @@ -58,8 +58,8 @@ impl<'a, 'tcx: 'a, V: CodegenObject> PlaceRef<'tcx, V> { ) -> Self { debug!("alloca({:?}: {:?})", name, layout); assert!(!layout.is_unsized(), "tried to statically allocate unsized place"); - let tmp = bx.alloca(bx.cx().backend_type(layout), name, layout.align); - Self::new_sized(tmp, layout, layout.align) + let tmp = bx.alloca(bx.cx().backend_type(layout), name, layout.align.abi); + Self::new_sized(tmp, layout, layout.align.abi) } /// Returns a place for an indirect reference to an unsized place. @@ -109,7 +109,7 @@ impl<'a, 'tcx: 'a, V: CodegenObject> PlaceRef<'tcx, V> { self.llval } else if let layout::Abi::ScalarPair(ref a, ref b) = self.layout.abi { // Offsets have to match either first or second field. - assert_eq!(offset, a.value.size(bx.cx()).abi_align(b.value.align(bx.cx()))); + assert_eq!(offset, a.value.size(bx.cx()).align_to(b.value.align(bx.cx()).abi)); bx.struct_gep(self.llval, 1) } else { bx.struct_gep(self.llval, bx.cx().backend_field_index(self.layout, ix)) @@ -143,7 +143,7 @@ impl<'a, 'tcx: 'a, V: CodegenObject> PlaceRef<'tcx, V> { if def.repr.packed() { // FIXME(eddyb) generalize the adjustment when we // start supporting packing to larger alignments. - assert_eq!(self.layout.align.abi(), 1); + assert_eq!(self.layout.align.abi.bytes(), 1); return simple(); } } @@ -308,9 +308,8 @@ impl<'a, 'tcx: 'a, V: CodegenObject> PlaceRef<'tcx, V> { // Issue #34427: As workaround for LLVM bug on ARM, // use memset of 0 before assigning niche value. let fill_byte = bx.cx().const_u8(0); - let (size, align) = self.layout.size_and_align(); - let size = bx.cx().const_usize(size.bytes()); - bx.memset(self.llval, fill_byte, size, align, MemFlags::empty()); + let size = bx.cx().const_usize(self.layout.size.bytes()); + bx.memset(self.llval, fill_byte, size, self.align, MemFlags::empty()); } let niche = self.project_field(bx, 0); @@ -419,13 +418,13 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let llval = bx.cx().const_undef( bx.cx().type_ptr_to(bx.cx().backend_type(layout)) ); - PlaceRef::new_sized(llval, layout, layout.align) + PlaceRef::new_sized(llval, layout, layout.align.abi) } } } mir::Place::Static(box mir::Static { def_id, ty }) => { let layout = cx.layout_of(self.monomorphize(&ty)); - PlaceRef::new_sized(cx.get_static(def_id), layout, layout.align) + PlaceRef::new_sized(cx.get_static(def_id), layout, layout.align.abi) }, mir::Place::Projection(box mir::Projection { ref base, diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs index 6b1efa060fd..805c1a343d0 100644 --- a/src/librustc_codegen_ssa/mir/rvalue.rs +++ b/src/librustc_codegen_ssa/mir/rvalue.rs @@ -496,10 +496,10 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } mir::Rvalue::NullaryOp(mir::NullOp::Box, content_ty) => { - let content_ty: Ty<'tcx> = self.monomorphize(&content_ty); - let (size, align) = bx.cx().layout_of(content_ty).size_and_align(); - let llsize = bx.cx().const_usize(size.bytes()); - let llalign = bx.cx().const_usize(align.abi()); + let content_ty = self.monomorphize(&content_ty); + let content_layout = bx.cx().layout_of(content_ty); + let llsize = bx.cx().const_usize(content_layout.size.bytes()); + let llalign = bx.cx().const_usize(content_layout.align.abi.bytes()); let box_layout = bx.cx().layout_of(bx.tcx().mk_box(content_ty)); let llty_ptr = bx.cx().backend_type(box_layout); diff --git a/src/librustc_codegen_ssa/mono_item.rs b/src/librustc_codegen_ssa/mono_item.rs index 53acb3e376c..8fe89791969 100644 --- a/src/librustc_codegen_ssa/mono_item.rs +++ b/src/librustc_codegen_ssa/mono_item.rs @@ -8,12 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Walks the crate looking for items/impl-items/trait-items that have -//! either a `rustc_symbol_name` or `rustc_item_path` attribute and -//! generates an error giving, respectively, the symbol name or -//! item-path. This is used for unit testing the code that generates -//! paths etc in all kinds of annoying scenarios. - use base; use rustc::hir; use rustc::hir::def::Def; diff --git a/src/librustc_codegen_ssa/traits/builder.rs b/src/librustc_codegen_ssa/traits/builder.rs index 3757c514d2c..0b3066f561c 100644 --- a/src/librustc_codegen_ssa/traits/builder.rs +++ b/src/librustc_codegen_ssa/traits/builder.rs @@ -15,10 +15,10 @@ use super::intrinsic::IntrinsicCallMethods; use super::type_::ArgTypeMethods; use super::HasCodegen; use common::{AtomicOrdering, AtomicRmwBinOp, IntPredicate, RealPredicate, SynchronizationScope}; -use std::ffi::CStr; use mir::operand::OperandRef; use mir::place::PlaceRef; use rustc::ty::layout::{Align, Size}; +use std::ffi::CStr; use MemFlags; use std::borrow::Cow; diff --git a/src/librustc_codegen_ssa/traits/type_.rs b/src/librustc_codegen_ssa/traits/type_.rs index 1aa1f45f517..15976ac516d 100644 --- a/src/librustc_codegen_ssa/traits/type_.rs +++ b/src/librustc_codegen_ssa/traits/type_.rs @@ -120,16 +120,16 @@ pub trait DerivedTypeMethods<'tcx>: BaseTypeMethods<'tcx> + MiscMethods<'tcx> { } } - fn type_pointee_for_abi_align(&self, align: Align) -> Self::Type { + fn type_pointee_for_align(&self, align: Align) -> Self::Type { // FIXME(eddyb) We could find a better approximation if ity.align < align. - let ity = layout::Integer::approximate_abi_align(self, align); + let ity = layout::Integer::approximate_align(self, align); self.type_from_integer(ity) } /// Return a LLVM type that has at most the required alignment, /// and exactly the required size, as a best-effort padding array. fn type_padding_filler(&self, size: Size, align: Align) -> Self::Type { - let unit = layout::Integer::approximate_abi_align(self, align); + let unit = layout::Integer::approximate_align(self, align); let size = size.bytes(); let unit_size = unit.size().bytes(); assert_eq!(size % unit_size, 0); diff --git a/src/librustc_data_structures/Cargo.toml b/src/librustc_data_structures/Cargo.toml index 79f073d643d..5b3dd38adf2 100644 --- a/src/librustc_data_structures/Cargo.toml +++ b/src/librustc_data_structures/Cargo.toml @@ -9,7 +9,7 @@ path = "lib.rs" crate-type = ["dylib"] [dependencies] -ena = "0.9.3" +ena = "0.10.1" log = "0.4" rustc_cratesio_shim = { path = "../librustc_cratesio_shim" } serialize = { path = "../libserialize" } diff --git a/src/librustc_data_structures/fx.rs b/src/librustc_data_structures/fx.rs index bce21f5085c..7c7fc3a9346 100644 --- a/src/librustc_data_structures/fx.rs +++ b/src/librustc_data_structures/fx.rs @@ -8,6 +8,4 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub use rustc_hash::FxHashMap; -pub use rustc_hash::FxHashSet; -pub use rustc_hash::FxHasher; +pub use rustc_hash::{FxHasher, FxHashMap, FxHashSet}; diff --git a/src/librustc_data_structures/snapshot_map/mod.rs b/src/librustc_data_structures/snapshot_map/mod.rs index f8663cd4fd4..0b42cb1eddd 100644 --- a/src/librustc_data_structures/snapshot_map/mod.rs +++ b/src/librustc_data_structures/snapshot_map/mod.rs @@ -23,6 +23,18 @@ pub struct SnapshotMap undo_log: Vec>, } +// HACK(eddyb) manual impl avoids `Default` bounds on `K` and `V`. +impl Default for SnapshotMap + where K: Hash + Clone + Eq +{ + fn default() -> Self { + SnapshotMap { + map: Default::default(), + undo_log: Default::default(), + } + } +} + pub struct Snapshot { len: usize, } @@ -35,17 +47,6 @@ enum UndoLog { Noop, } -impl Default for SnapshotMap - where K: Hash + Clone + Eq -{ - fn default() -> Self { - SnapshotMap { - map: FxHashMap::default(), - undo_log: vec![], - } - } -} - impl SnapshotMap where K: Hash + Clone + Eq { diff --git a/src/librustc_data_structures/transitive_relation.rs b/src/librustc_data_structures/transitive_relation.rs index e1318eb54d5..fd5dfab9e61 100644 --- a/src/librustc_data_structures/transitive_relation.rs +++ b/src/librustc_data_structures/transitive_relation.rs @@ -42,6 +42,18 @@ pub struct TransitiveRelation { closure: Lock>>, } +// HACK(eddyb) manual impl avoids `Default` bound on `T`. +impl Default for TransitiveRelation { + fn default() -> Self { + TransitiveRelation { + elements: Default::default(), + map: Default::default(), + edges: Default::default(), + closure: Default::default(), + } + } +} + #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Debug)] struct Index(usize); @@ -51,17 +63,6 @@ struct Edge { target: Index, } -impl Default for TransitiveRelation { - fn default() -> TransitiveRelation { - TransitiveRelation { - elements: vec![], - map: FxHashMap::default(), - edges: vec![], - closure: Lock::new(None), - } - } -} - impl TransitiveRelation { pub fn is_empty(&self) -> bool { self.edges.is_empty() diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index bef7b364d84..7dd1ca3493e 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -603,7 +603,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDebugImplementations { }; if self.impling_types.is_none() { - let mut impls = NodeSet(); + let mut impls = NodeSet::default(); cx.tcx.for_each_impl(debug, |d| { if let Some(ty_def) = cx.tcx.type_of(d).ty_adt_def() { if let Some(node_id) = cx.tcx.hir.as_local_node_id(ty_def.did) { diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 7eab7d21002..fab618d9c8e 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -60,18 +60,39 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { } let t = cx.tables.expr_ty(&expr); - // FIXME(varkor): replace with `t.is_unit() || t.conservative_is_uninhabited()`. - let type_permits_no_use = match t.sty { - ty::Tuple(ref tys) if tys.is_empty() => true, - ty::Never => true, - ty::Adt(def, _) => { - if def.variants.is_empty() { - true - } else { - check_must_use(cx, def.did, s.span, "") + let type_permits_lack_of_use = if t.is_unit() + || cx.tcx.is_ty_uninhabited_from(cx.tcx.hir.get_module_parent(expr.id), t) { + true + } else { + match t.sty { + ty::Adt(def, _) => check_must_use(cx, def.did, s.span, "", ""), + ty::Opaque(def, _) => { + let mut must_use = false; + for (predicate, _) in &cx.tcx.predicates_of(def).predicates { + if let ty::Predicate::Trait(ref poly_trait_predicate) = predicate { + let trait_ref = poly_trait_predicate.skip_binder().trait_ref; + if check_must_use(cx, trait_ref.def_id, s.span, "implementer of ", "") { + must_use = true; + break; + } + } + } + must_use } + ty::Dynamic(binder, _) => { + let mut must_use = false; + for predicate in binder.skip_binder().iter() { + if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate { + if check_must_use(cx, trait_ref.def_id, s.span, "", " trait object") { + must_use = true; + break; + } + } + } + must_use + } + _ => false, } - _ => false, }; let mut fn_warned = false; @@ -98,8 +119,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { }; if let Some(def) = maybe_def { let def_id = def.def_id(); - fn_warned = check_must_use(cx, def_id, s.span, "return value of "); - } else if type_permits_no_use { + fn_warned = check_must_use(cx, def_id, s.span, "return value of ", ""); + } else if type_permits_lack_of_use { // We don't warn about unused unit or uninhabited types. // (See https://github.com/rust-lang/rust/issues/43806 for details.) return; @@ -148,15 +169,21 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { op_warned = true; } - if !(type_permits_no_use || fn_warned || op_warned) { + if !(type_permits_lack_of_use || fn_warned || op_warned) { cx.span_lint(UNUSED_RESULTS, s.span, "unused result"); } - fn check_must_use(cx: &LateContext, def_id: DefId, sp: Span, describe_path: &str) -> bool { + fn check_must_use( + cx: &LateContext, + def_id: DefId, + sp: Span, + descr_pre_path: &str, + descr_post_path: &str, + ) -> bool { for attr in cx.tcx.get_attrs(def_id).iter() { if attr.check_name("must_use") { - let msg = format!("unused {}`{}` that must be used", - describe_path, cx.tcx.item_path_str(def_id)); + let msg = format!("unused {}`{}`{} that must be used", + descr_pre_path, cx.tcx.item_path_str(def_id), descr_post_path); let mut err = cx.struct_span_lint(UNUSED_MUST_USE, sp, &msg); // check for #[must_use = "..."] if let Some(note) = attr.value_str() { diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index e1d9ca5339e..c7bd1744a3d 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -316,7 +316,7 @@ pub fn provide<'tcx>(providers: &mut Providers<'tcx>) { use std::collections::hash_map::Entry; assert_eq!(cnum, LOCAL_CRATE); - let mut visible_parent_map: DefIdMap = DefIdMap(); + let mut visible_parent_map: DefIdMap = Default::default(); // Issue 46112: We want the map to prefer the shortest // paths when reporting the path to an item. Therefore we diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 0aa1924c0e5..d95a74be776 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -829,7 +829,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { 1, ), upvar_decls, - var_indices: NodeMap(), + var_indices: Default::default(), unit_temp: None, cached_resume_block: None, cached_return_block: None, diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 51046399ec2..1bc3b322717 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -31,8 +31,8 @@ use rustc::util::common::ErrorReported; use syntax::ast::Mutability; use syntax::source_map::{Span, DUMMY_SP}; -use interpret::{self, - PlaceTy, MemPlace, OpTy, Operand, Immediate, Scalar, ConstValue, Pointer, +use crate::interpret::{self, + PlaceTy, MPlaceTy, MemPlace, OpTy, Operand, Immediate, Scalar, RawConst, ConstValue, Pointer, EvalResult, EvalError, EvalErrorKind, GlobalId, EvalContext, StackPopCleanup, Allocation, AllocId, MemoryKind, snapshot, RefTracking, @@ -94,11 +94,12 @@ pub(crate) fn eval_promoted<'a, 'mir, 'tcx>( cid: GlobalId<'tcx>, mir: &'mir mir::Mir<'tcx>, param_env: ty::ParamEnv<'tcx>, -) -> EvalResult<'tcx, OpTy<'tcx>> { +) -> EvalResult<'tcx, MPlaceTy<'tcx>> { let mut ecx = mk_borrowck_eval_cx(tcx, cid.instance, mir, DUMMY_SP).unwrap(); eval_body_using_ecx(&mut ecx, cid, Some(mir), param_env) } +// FIXME: These two conversion functions are bad hacks. We should just always use allocations. pub fn op_to_const<'tcx>( ecx: &CompileTimeEvalContext<'_, '_, 'tcx>, op: OpTy<'tcx>, @@ -128,7 +129,7 @@ pub fn op_to_const<'tcx>( assert!(meta.is_none()); let ptr = ptr.to_ptr()?; let alloc = ecx.memory.get(ptr.alloc_id)?; - assert!(alloc.align.abi() >= align.abi()); + assert!(alloc.align >= align); assert!(alloc.bytes.len() as u64 - ptr.offset.bytes() >= op.layout.size.bytes()); let mut alloc = alloc.clone(); alloc.align = align; @@ -144,13 +145,20 @@ pub fn op_to_const<'tcx>( }; Ok(ty::Const::from_const_value(ecx.tcx.tcx, val, op.layout.ty)) } +pub fn const_to_op<'tcx>( + ecx: &CompileTimeEvalContext<'_, '_, 'tcx>, + cnst: &ty::Const<'tcx>, +) -> EvalResult<'tcx, OpTy<'tcx>> { + let op = ecx.const_value_to_op(cnst.val)?; + Ok(OpTy { op, layout: ecx.layout_of(cnst.ty)? }) +} fn eval_body_and_ecx<'a, 'mir, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, cid: GlobalId<'tcx>, mir: Option<&'mir mir::Mir<'tcx>>, param_env: ty::ParamEnv<'tcx>, -) -> (EvalResult<'tcx, OpTy<'tcx>>, CompileTimeEvalContext<'a, 'mir, 'tcx>) { +) -> (EvalResult<'tcx, MPlaceTy<'tcx>>, CompileTimeEvalContext<'a, 'mir, 'tcx>) { // we start out with the best span we have // and try improving it down the road when more information is available let span = tcx.def_span(cid.instance.def_id()); @@ -166,7 +174,7 @@ fn eval_body_using_ecx<'mir, 'tcx>( cid: GlobalId<'tcx>, mir: Option<&'mir mir::Mir<'tcx>>, param_env: ty::ParamEnv<'tcx>, -) -> EvalResult<'tcx, OpTy<'tcx>> { +) -> EvalResult<'tcx, MPlaceTy<'tcx>> { debug!("eval_body_using_ecx: {:?}, {:?}", cid, param_env); let tcx = ecx.tcx.tcx; let mut mir = match mir { @@ -206,7 +214,7 @@ fn eval_body_using_ecx<'mir, 'tcx>( ecx.memory.intern_static(ret.ptr.to_ptr()?.alloc_id, mutability)?; debug!("eval_body_using_ecx done: {:?}", *ret); - Ok(ret.into()) + Ok(ret) } impl<'tcx> Into> for ConstEvalError { @@ -494,7 +502,7 @@ pub fn const_field<'a, 'tcx>( let ecx = mk_eval_cx(tcx, instance, param_env).unwrap(); let result = (|| { // get the operand again - let op = ecx.const_to_op(value)?; + let op = const_to_op(&ecx, value)?; // downcast let down = match variant { None => op, @@ -521,7 +529,7 @@ pub fn const_variant_index<'a, 'tcx>( ) -> EvalResult<'tcx, VariantIdx> { trace!("const_variant_index: {:?}, {:?}", instance, val); let ecx = mk_eval_cx(tcx, instance, param_env).unwrap(); - let op = ecx.const_to_op(val)?; + let op = const_to_op(&ecx, val)?; Ok(ecx.read_discriminant(op)?.1) } @@ -534,15 +542,17 @@ pub fn error_to_const_error<'a, 'mir, 'tcx>( ConstEvalErr { error: error.kind, stacktrace, span: ecx.tcx.span } } -fn validate_const<'a, 'tcx>( +fn validate_and_turn_into_const<'a, 'tcx>( tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, - constant: &'tcx ty::Const<'tcx>, + constant: RawConst<'tcx>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, ) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> { let cid = key.value; let ecx = mk_eval_cx(tcx, cid.instance, key.param_env).unwrap(); let val = (|| { - let op = ecx.const_to_op(constant)?; + let op = ecx.raw_const_to_mplace(constant)?.into(); + // FIXME: Once the visitor infrastructure landed, change validation to + // work directly on `MPlaceTy`. let mut ref_tracking = RefTracking::new(op); while let Some((op, path)) = ref_tracking.todo.pop() { ecx.validate_operand( @@ -552,7 +562,10 @@ fn validate_const<'a, 'tcx>( /* const_mode */ true, )?; } - Ok(constant) + // Now that we validated, turn this into a proper constant + let def_id = cid.instance.def.def_id(); + let normalize = tcx.is_static(def_id).is_none() && cid.promoted.is_none(); + op_to_const(&ecx, op, normalize) })(); val.map_err(|error| { @@ -591,14 +604,14 @@ pub fn const_eval_provider<'a, 'tcx>( } } tcx.const_eval_raw(key).and_then(|val| { - validate_const(tcx, val, key) + validate_and_turn_into_const(tcx, val, key) }) } pub fn const_eval_raw_provider<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, -) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> { +) -> ::rustc::mir::interpret::ConstEvalRawResult<'tcx> { // Because the constant is computed twice (once per value of `Reveal`), we are at risk of // reporting the same error twice here. To resolve this, we check whether we can evaluate the // constant in the more restrictive `Reveal::UserFacing`, which most likely already was @@ -648,16 +661,11 @@ pub fn const_eval_raw_provider<'a, 'tcx>( }; let (res, ecx) = eval_body_and_ecx(tcx, cid, None, key.param_env); - res.and_then(|op| { - let normalize = tcx.is_static(def_id).is_none() && cid.promoted.is_none(); - if !normalize { - // Sanity check: These must always be a MemPlace - match op.op { - Operand::Indirect(_) => { /* all is good */ }, - Operand::Immediate(_) => bug!("const eval gave us an Immediate"), - } - } - op_to_const(&ecx, op, normalize) + res.and_then(|place| { + Ok(RawConst { + alloc_id: place.to_ptr().expect("we allocated this ptr!").alloc_id, + ty: place.layout.ty + }) }).map_err(|error| { let err = error_to_const_error(&ecx, error); // errors in statics are always emitted as fatal errors diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index ce7269d1e78..936b476df39 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -316,7 +316,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc layout: TyLayout<'tcx>, ) -> EvalResult<'tcx, Option<(Size, Align)>> { if !layout.is_unsized() { - return Ok(Some(layout.size_and_align())); + return Ok(Some((layout.size, layout.align.abi))); } match layout.ty.sty { ty::Adt(..) | ty::Tuple(..) => { @@ -328,7 +328,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc trace!("DST layout: {:?}", layout); let sized_size = layout.fields.offset(layout.fields.count() - 1); - let sized_align = layout.align; + let sized_align = layout.align.abi; trace!( "DST {} statically sized prefix size: {:?} align: {:?}", layout.ty, @@ -381,7 +381,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc // // `(size + (align-1)) & -align` - Ok(Some((size.abi_align(align), align))) + Ok(Some((size.align_to(align), align))) } ty::Dynamic(..) => { let vtable = metadata.expect("dyn trait fat ptr must have vtable").to_ptr()?; @@ -391,8 +391,8 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc ty::Slice(_) | ty::Str => { let len = metadata.expect("slice fat ptr must have vtable").to_usize(self)?; - let (elem_size, align) = layout.field(self, 0)?.size_and_align(); - Ok(Some((elem_size * len, align))) + let elem = layout.field(self, 0)?; + Ok(Some((elem.size * len, elem.align.abi))) } ty::Foreign(_) => { @@ -588,18 +588,26 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc Ok(()) } - pub fn const_eval(&self, gid: GlobalId<'tcx>) -> EvalResult<'tcx, &'tcx ty::Const<'tcx>> { + pub fn const_eval_raw( + &self, + gid: GlobalId<'tcx>, + ) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> { let param_env = if self.tcx.is_static(gid.instance.def_id()).is_some() { ty::ParamEnv::reveal_all() } else { self.param_env }; - self.tcx.const_eval(param_env.and(gid)).map_err(|err| { + // We use `const_eval_raw` here, and get an unvalidated result. That is okay: + // Our result will later be validated anyway, and there seems no good reason + // to have to fail early here. This is also more consistent with + // `Memory::get_static_alloc` which has to use `const_eval_raw` to avoid cycles. + let val = self.tcx.const_eval_raw(param_env.and(gid)).map_err(|err| { match err { - ErrorHandled::Reported => EvalErrorKind::ReferencedConstant.into(), - ErrorHandled::TooGeneric => EvalErrorKind::TooGeneric.into(), + ErrorHandled::Reported => EvalErrorKind::ReferencedConstant, + ErrorHandled::TooGeneric => EvalErrorKind::TooGeneric, } - }) + })?; + self.raw_const_to_mplace(val) } pub fn dump_place(&self, place: Place) { @@ -628,7 +636,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc let (ptr, align) = mplace.to_scalar_ptr_align(); match ptr { Scalar::Ptr(ptr) => { - write!(msg, " by align({}) ref:", align.abi()).unwrap(); + write!(msg, " by align({}) ref:", align.bytes()).unwrap(); allocs.push(ptr.alloc_id); } ptr => write!(msg, " by integral ref: {:?}", ptr).unwrap(), @@ -657,7 +665,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc Place::Ptr(mplace) => { match mplace.ptr { Scalar::Ptr(ptr) => { - trace!("by align({}) ref:", mplace.align.abi()); + trace!("by align({}) ref:", mplace.align.bytes()); self.memory.dump_alloc(ptr.alloc_id); } ptr => trace!(" integral by ref: {:?}", ptr), diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index 7ef94005970..bbee6e0b49a 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -60,7 +60,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> match intrinsic_name { "min_align_of" => { let elem_ty = substs.type_at(0); - let elem_align = self.layout_of(elem_ty)?.align.abi(); + let elem_align = self.layout_of(elem_ty)?.align.abi.bytes(); let align_val = Scalar::from_uint(elem_align, dest.layout.size); self.write_scalar(align_val, dest)?; } diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index c5a242f334c..898600d8322 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -28,7 +28,7 @@ use rustc_data_structures::fx::{FxHashSet, FxHashMap}; use syntax::ast::Mutability; use super::{ - Pointer, AllocId, Allocation, ConstValue, GlobalId, AllocationExtra, InboundsCheck, + Pointer, AllocId, Allocation, GlobalId, AllocationExtra, InboundsCheck, EvalResult, Scalar, EvalErrorKind, AllocType, PointerArithmetic, Machine, AllocMap, MayLeak, ScalarMaybeUndef, ErrorHandled, }; @@ -268,18 +268,18 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { } }; // Check alignment - if alloc_align.abi() < required_align.abi() { + if alloc_align.bytes() < required_align.bytes() { return err!(AlignmentCheckFailed { has: alloc_align, required: required_align, }); } - if offset % required_align.abi() == 0 { + if offset % required_align.bytes() == 0 { Ok(()) } else { - let has = offset % required_align.abi(); + let has = offset % required_align.bytes(); err!(AlignmentCheckFailed { - has: Align::from_bytes(has, has).unwrap(), + has: Align::from_bytes(has).unwrap(), required: required_align, }) } @@ -374,14 +374,11 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { ErrorHandled::Reported => EvalErrorKind::ReferencedConstant.into(), ErrorHandled::TooGeneric => EvalErrorKind::TooGeneric.into(), } - }).map(|const_val| { - if let ConstValue::ByRef(_, allocation, _) = const_val.val { - // We got tcx memory. Let the machine figure out whether and how to - // turn that into memory with the right pointer tag. - M::adjust_static_allocation(allocation) - } else { - bug!("Matching on non-ByRef static") - } + }).map(|raw_const| { + let allocation = tcx.alloc_map.lock().unwrap_memory(raw_const.alloc_id); + // We got tcx memory. Let the machine figure out whether and how to + // turn that into memory with the right pointer tag. + M::adjust_static_allocation(allocation) }) } @@ -452,14 +449,14 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { } // Could also be a fn ptr or extern static match self.tcx.alloc_map.lock().get(id) { - Some(AllocType::Function(..)) => (Size::ZERO, Align::from_bytes(1, 1).unwrap()), + Some(AllocType::Function(..)) => (Size::ZERO, Align::from_bytes(1).unwrap()), Some(AllocType::Static(did)) => { // The only way `get` couldn't have worked here is if this is an extern static assert!(self.tcx.is_foreign_item(did)); // Use size and align of the type let ty = self.tcx.type_of(did); let layout = self.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap(); - (layout.size, layout.align) + (layout.size, layout.align.abi) } _ => { // Must be a deallocated pointer @@ -524,7 +521,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { "{}({} bytes, alignment {}){}", msg, alloc.bytes.len(), - alloc.align.abi(), + alloc.align.bytes(), extra ); @@ -866,7 +863,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { allow_ptr_and_undef: bool, ) -> EvalResult<'tcx> { // Empty accesses don't need to be valid pointers, but they should still be non-NULL - let align = Align::from_bytes(1, 1).unwrap(); + let align = Align::from_bytes(1).unwrap(); if size.bytes() == 0 { self.check_align(ptr, align)?; return Ok(()); @@ -884,7 +881,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { pub fn read_bytes(&self, ptr: Scalar, size: Size) -> EvalResult<'tcx, &[u8]> { // Empty accesses don't need to be valid pointers, but they should still be non-NULL - let align = Align::from_bytes(1, 1).unwrap(); + let align = Align::from_bytes(1).unwrap(); if size.bytes() == 0 { self.check_align(ptr, align)?; return Ok(&[]); @@ -894,7 +891,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { pub fn write_bytes(&mut self, ptr: Scalar, src: &[u8]) -> EvalResult<'tcx> { // Empty accesses don't need to be valid pointers, but they should still be non-NULL - let align = Align::from_bytes(1, 1).unwrap(); + let align = Align::from_bytes(1).unwrap(); if src.is_empty() { self.check_align(ptr, align)?; return Ok(()); @@ -911,7 +908,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { count: Size ) -> EvalResult<'tcx> { // Empty accesses don't need to be valid pointers, but they should still be non-NULL - let align = Align::from_bytes(1, 1).unwrap(); + let align = Align::from_bytes(1).unwrap(); if count.bytes() == 0 { self.check_align(ptr, align)?; return Ok(()); @@ -1038,7 +1035,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { 16 => layout::I128, _ => bug!("bad integer size: {}", size.bytes()), }; - ity.align(self) + ity.align(self).abi } } diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index b7910ad3bce..8238d580022 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -13,7 +13,7 @@ use std::convert::TryInto; -use rustc::{mir, ty}; +use rustc::mir; use rustc::ty::layout::{self, Size, LayoutOf, TyLayout, HasDataLayout, IntegerExt, VariantIdx}; use rustc::mir::interpret::{ @@ -285,7 +285,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> let (a, b) = (&a.value, &b.value); let (a_size, b_size) = (a.size(self), b.size(self)); let a_ptr = ptr; - let b_offset = a_size.abi_align(b.align(self)); + let b_offset = a_size.align_to(b.align(self).abi); assert!(b_offset.bytes() > 0); // we later use the offset to test which field to use let b_ptr = ptr.offset(b_offset, self)?.into(); let a_val = self.memory.read_scalar(a_ptr, ptr_align, a_size)?; @@ -535,8 +535,10 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> .collect() } - // Also used e.g. when miri runs into a constant. - pub(super) fn const_value_to_op( + // Used when miri runs into a constant, and by CTFE. + // FIXME: CTFE should use allocations, then we can make this private (embed it into + // `eval_operand`, ideally). + pub(crate) fn const_value_to_op( &self, val: ConstValue<'tcx>, ) -> EvalResult<'tcx, Operand> { @@ -544,10 +546,10 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> match val { ConstValue::Unevaluated(def_id, substs) => { let instance = self.resolve(def_id, substs)?; - self.global_to_op(GlobalId { + Ok(*OpTy::from(self.const_eval_raw(GlobalId { instance, promoted: None, - }) + })?)) } ConstValue::ByRef(id, alloc, offset) => { // We rely on mutability being set correctly in that allocation to prevent writes @@ -565,21 +567,6 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> Ok(Operand::Immediate(Immediate::Scalar(x.into())).with_default_tag()), } } - pub fn const_to_op( - &self, - cnst: &ty::Const<'tcx>, - ) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> { - let op = self.const_value_to_op(cnst.val)?; - Ok(OpTy { op, layout: self.layout_of(cnst.ty)? }) - } - - pub(super) fn global_to_op( - &self, - gid: GlobalId<'tcx> - ) -> EvalResult<'tcx, Operand> { - let cv = self.const_eval(gid)?; - self.const_value_to_op(cv.val) - } /// Read discriminant, return the runtime value as well as the variant index. pub fn read_discriminant( diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index fa76eeb2fed..7ef3dd5f720 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -20,12 +20,10 @@ use rustc::mir; use rustc::ty::{self, Ty}; use rustc::ty::layout::{self, Size, Align, LayoutOf, TyLayout, HasDataLayout, VariantIdx}; -use rustc::mir::interpret::{ - GlobalId, AllocId, Allocation, Scalar, EvalResult, Pointer, PointerArithmetic -}; use super::{ + GlobalId, AllocId, Allocation, Scalar, EvalResult, Pointer, PointerArithmetic, EvalContext, Machine, AllocMap, AllocationExtra, - Immediate, ImmTy, ScalarMaybeUndef, Operand, OpTy, MemoryKind + RawConst, Immediate, ImmTy, ScalarMaybeUndef, Operand, OpTy, MemoryKind }; #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] @@ -129,7 +127,7 @@ impl MemPlace { /// Produces a Place that will error if attempted to be read from or written to #[inline(always)] pub fn null(cx: &impl HasDataLayout) -> Self { - Self::from_scalar_ptr(Scalar::ptr_null(cx), Align::from_bytes(1, 1).unwrap()) + Self::from_scalar_ptr(Scalar::ptr_null(cx), Align::from_bytes(1).unwrap()) } #[inline(always)] @@ -169,8 +167,8 @@ impl<'tcx, Tag> MPlaceTy<'tcx, Tag> { pub fn dangling(layout: TyLayout<'tcx>, cx: &impl HasDataLayout) -> Self { MPlaceTy { mplace: MemPlace::from_scalar_ptr( - Scalar::from_uint(layout.align.abi(), cx.pointer_size()), - layout.align + Scalar::from_uint(layout.align.abi.bytes(), cx.pointer_size()), + layout.align.abi ), layout } @@ -178,7 +176,7 @@ impl<'tcx, Tag> MPlaceTy<'tcx, Tag> { #[inline] fn from_aligned_ptr(ptr: Pointer, layout: TyLayout<'tcx>) -> Self { - MPlaceTy { mplace: MemPlace::from_ptr(ptr, layout.align), layout } + MPlaceTy { mplace: MemPlace::from_ptr(ptr, layout.align.abi), layout } } #[inline] @@ -289,7 +287,7 @@ where let mplace = MemPlace { ptr: val.to_scalar_ptr()?, - align: layout.align, + align: layout.align.abi, meta: val.to_meta()?, }; Ok(MPlaceTy { mplace, layout }) @@ -358,11 +356,11 @@ where // FIXME: Once we have made decisions for how to handle size and alignment // of `extern type`, this should be adapted. It is just a temporary hack // to get some code to work that probably ought to work. - field_layout.align, + field_layout.align.abi, None => bug!("Cannot compute offset for extern type field at non-0 offset"), }; - (base.meta, offset.abi_align(align)) + (base.meta, offset.align_to(align)) } else { // base.meta could be present; we might be accessing a sized field of an unsized // struct. @@ -555,16 +553,10 @@ where Ok(match *mir_place { Promoted(ref promoted) => { let instance = self.frame().instance; - let op = self.global_to_op(GlobalId { + self.const_eval_raw(GlobalId { instance, promoted: Some(promoted.0), - })?; - let mplace = op.to_mem_place(); // these are always in memory - let ty = self.monomorphize(promoted.1, self.substs()); - MPlaceTy { - mplace, - layout: self.layout_of(ty)?, - } + })? } Static(ref static_) => { @@ -738,7 +730,7 @@ where } self.memory.write_scalar( - ptr, ptr_align.min(dest.layout.align), scalar, dest.layout.size + ptr, ptr_align.min(dest.layout.align.abi), scalar, dest.layout.size ) } Immediate::ScalarPair(a_val, b_val) => { @@ -748,8 +740,8 @@ where dest.layout) }; let (a_size, b_size) = (a.size(self), b.size(self)); - let (a_align, b_align) = (a.align(self), b.align(self)); - let b_offset = a_size.abi_align(b_align); + let (a_align, b_align) = (a.align(self).abi, b.align(self).abi); + let b_offset = a_size.align_to(b_align); let b_ptr = ptr.offset(b_offset, self)?.into(); // It is tempting to verify `b_offset` against `layout.fields.offset(1)`, @@ -907,7 +899,7 @@ where // FIXME: What should we do here? We should definitely also tag! Ok(MPlaceTy::dangling(layout, self)) } else { - let ptr = self.memory.allocate(layout.size, layout.align, kind)?; + let ptr = self.memory.allocate(layout.size, layout.align.abi, kind)?; let ptr = M::tag_new_allocation(self, ptr, kind)?; Ok(MPlaceTy::from_aligned_ptr(ptr, layout)) } @@ -981,6 +973,19 @@ where Ok(OpTy { op, layout: place.layout }) } + pub fn raw_const_to_mplace( + &self, + raw: RawConst<'tcx>, + ) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> { + // This must be an allocation in `tcx` + assert!(self.tcx.alloc_map.lock().get(raw.alloc_id).is_some()); + let layout = self.layout_of(raw.ty)?; + Ok(MPlaceTy::from_aligned_ptr( + Pointer::new(raw.alloc_id, Size::ZERO).with_default_tag(), + layout, + )) + } + /// Turn a place with a `dyn Trait` type into a place with the actual dynamic type. /// Also return some more information so drop doesn't have to run the same code twice. pub(super) fn unpack_dyn_trait(&self, mplace: MPlaceTy<'tcx, M::PointerTag>) @@ -993,7 +998,8 @@ where if cfg!(debug_assertions) { let (size, align) = self.read_size_and_align_from_vtable(vtable)?; assert_eq!(size, layout.size); - assert_eq!(align.abi(), layout.align.abi()); // only ABI alignment is preserved + // only ABI alignment is preserved + assert_eq!(align, layout.align.abi); } let mplace = MPlaceTy { diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index 6070b31d3e7..fd17a4a7129 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -401,7 +401,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> // cannot use the shim here, because that will only result in infinite recursion ty::InstanceDef::Virtual(_, idx) => { let ptr_size = self.pointer_size(); - let ptr_align = self.tcx.data_layout.pointer_align; + let ptr_align = self.tcx.data_layout.pointer_align.abi; let ptr = self.deref_operand(args[0])?; let vtable = ptr.vtable()?; let fn_ptr = self.memory.read_ptr_sized( diff --git a/src/librustc_mir/interpret/traits.rs b/src/librustc_mir/interpret/traits.rs index c5366a5ce6a..f11fd45b753 100644 --- a/src/librustc_mir/interpret/traits.rs +++ b/src/librustc_mir/interpret/traits.rs @@ -42,10 +42,10 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> let layout = self.layout_of(ty)?; assert!(!layout.is_unsized(), "can't create a vtable for an unsized type"); let size = layout.size.bytes(); - let align = layout.align.abi(); + let align = layout.align.abi.bytes(); let ptr_size = self.pointer_size(); - let ptr_align = self.tcx.data_layout.pointer_align; + let ptr_align = self.tcx.data_layout.pointer_align.abi; // ///////////////////////////////////////////////////////////////////////////////////////// // If you touch this code, be sure to also make the corresponding changes to // `get_vtable` in rust_codegen_llvm/meth.rs @@ -87,7 +87,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> vtable: Pointer, ) -> EvalResult<'tcx, (ty::Instance<'tcx>, ty::Ty<'tcx>)> { // we don't care about the pointee type, we just want a pointer - let pointer_align = self.tcx.data_layout.pointer_align; + let pointer_align = self.tcx.data_layout.pointer_align.abi; let drop_fn = self.memory.read_ptr_sized(vtable, pointer_align)?.to_ptr()?; let drop_instance = self.memory.get_fn(drop_fn)?; trace!("Found drop fn: {:?}", drop_instance); @@ -103,13 +103,13 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> vtable: Pointer, ) -> EvalResult<'tcx, (Size, Align)> { let pointer_size = self.pointer_size(); - let pointer_align = self.tcx.data_layout.pointer_align; + let pointer_align = self.tcx.data_layout.pointer_align.abi; let size = self.memory.read_ptr_sized(vtable.offset(pointer_size, self)?,pointer_align)? .to_bits(pointer_size)? as u64; let align = self.memory.read_ptr_sized( vtable.offset(pointer_size * 2, self)?, pointer_align )?.to_bits(pointer_size)? as u64; - Ok((Size::from_bytes(size), Align::from_bytes(align, align).unwrap())) + Ok((Size::from_bytes(size), Align::from_bytes(align).unwrap())) } } diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index ad7ffd291be..6d1cacfa147 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -355,7 +355,7 @@ impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> // for the purpose of validity, consider foreign types to have // alignment and size determined by the layout (size will be 0, // alignment should take attributes into account). - .unwrap_or_else(|| layout.size_and_align()); + .unwrap_or_else(|| (layout.size, layout.align.abi)); match self.ecx.memory.check_align(ptr, align) { Ok(_) => {}, Err(err) => { @@ -463,7 +463,7 @@ impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> // for function pointers. let non_null = self.ecx.memory.check_align( - Scalar::Ptr(ptr), Align::from_bytes(1, 1).unwrap() + Scalar::Ptr(ptr), Align::from_bytes(1).unwrap() ).is_ok() || self.ecx.memory.get_fn(ptr).is_ok(); if !non_null { diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 8e27635dee8..b4ffb39a2eb 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -314,7 +314,7 @@ pub fn collect_crate_mono_items<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, time(tcx.sess, "collecting mono items", || { par_iter(roots).for_each(|root| { - let mut recursion_depths = DefIdMap(); + let mut recursion_depths = DefIdMap::default(); collect_items_rec(tcx, root, visited, diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index 9d69a5669b1..9c90e5ffd3c 100644 --- a/src/librustc_mir/monomorphize/item.rs +++ b/src/librustc_mir/monomorphize/item.rs @@ -8,12 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Walks the crate looking for items/impl-items/trait-items that have -//! either a `rustc_symbol_name` or `rustc_item_path` attribute and -//! generates an error giving, respectively, the symbol name or -//! item-path. This is used for unit testing the code that generates -//! paths etc in all kinds of annoying scenarios. - use monomorphize::Instance; use rustc::hir; use rustc::hir::def_id::DefId; diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 885d70dc430..661ca4773b4 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -29,7 +29,9 @@ use rustc::ty::layout::{ }; use interpret::{self, EvalContext, ScalarMaybeUndef, Immediate, OpTy, MemoryKind}; -use const_eval::{CompileTimeInterpreter, error_to_const_error, eval_promoted, mk_borrowck_eval_cx}; +use const_eval::{ + CompileTimeInterpreter, const_to_op, error_to_const_error, eval_promoted, mk_borrowck_eval_cx +}; use transform::{MirPass, MirSource}; pub struct ConstProp; @@ -262,7 +264,7 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> { source_info: SourceInfo, ) -> Option> { self.ecx.tcx.span = source_info.span; - match self.ecx.const_to_op(c.literal) { + match const_to_op(&self.ecx, c.literal) { Ok(op) => { Some((op, c.span)) }, @@ -309,7 +311,7 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> { eval_promoted(this.tcx, cid, this.mir, this.param_env) })?; trace!("evaluated promoted {:?} to {:?}", promoted, res); - Some((res, source_info.span)) + Some((res.into(), source_info.span)) }, _ => None, } diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 92cfcb3fd56..8d3a04f9f3c 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -72,7 +72,7 @@ fn mir_keys<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, krate: CrateNum) -> Lrc { assert_eq!(krate, LOCAL_CRATE); - let mut set = DefIdSet(); + let mut set = DefIdSet::default(); // All body-owners have MIR associated with them. set.extend(tcx.body_owners()); diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index ed13063cfdf..958e5efe3ec 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -365,10 +365,8 @@ fn check_terminator( cleanup: _, } => check_operand(tcx, mir, cond, span), - | TerminatorKind::FalseUnwind { .. } => span_bug!( - terminator.source_info.span, - "min_const_fn encountered `{:#?}`", - terminator - ), + TerminatorKind::FalseUnwind { .. } => { + Err((span, "loops are not allowed in const fn".into())) + }, } } diff --git a/src/librustc_mir/util/alignment.rs b/src/librustc_mir/util/alignment.rs index 8717bd08ae4..a96c5dd6870 100644 --- a/src/librustc_mir/util/alignment.rs +++ b/src/librustc_mir/util/alignment.rs @@ -30,7 +30,7 @@ pub fn is_disaligned<'a, 'tcx, L>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let ty = place.ty(local_decls, tcx).to_ty(tcx); match tcx.layout_raw(param_env.and(ty)) { - Ok(layout) if layout.align.abi() == 1 => { + Ok(layout) if layout.align.abi.bytes() == 1 => { // if the alignment is 1, the type can't be further // disaligned. debug!("is_disaligned({:?}) - align = 1", place); diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs index a90cccfa7a7..099c6df32ad 100644 --- a/src/librustc_passes/rvalue_promotion.rs +++ b/src/librustc_passes/rvalue_promotion.rs @@ -84,10 +84,10 @@ fn rvalue_promotable_map<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, tables: &ty::TypeckTables::empty(None), in_fn: false, in_static: false, - mut_rvalue_borrows: NodeSet(), + mut_rvalue_borrows: Default::default(), param_env: ty::ParamEnv::empty(), identity_substs: Substs::empty(), - result: ItemLocalSet(), + result: ItemLocalSet::default(), }; // `def_id` should be a `Body` owner diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 5f8c7daea6e..fbd6f6edd31 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1761,7 +1761,7 @@ fn privacy_access_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx, access_levels: &visitor.access_levels, in_variant: false, - old_error_set: NodeSet(), + old_error_set: Default::default(), }; intravisit::walk_crate(&mut visitor, krate); diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs index ddcaf128bf5..659ca1f5b9f 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/src/librustc_resolve/check_unused.rs @@ -162,7 +162,7 @@ pub fn check_crate(resolver: &mut Resolver, krate: &ast::Crate) { let mut visitor = UnusedImportCheckVisitor { resolver, - unused_imports: NodeMap(), + unused_imports: Default::default(), base_id: ast::DUMMY_NODE_ID, item_span: DUMMY_SP, }; diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 7b2d1d4a3d5..12dabd2a31d 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -58,7 +58,6 @@ use syntax::ast::{self, Name, NodeId, Ident, FloatTy, IntTy, UintTy}; use syntax::ext::base::SyntaxExtension; use syntax::ext::base::Determinacy::{self, Determined, Undetermined}; use syntax::ext::base::MacroKind; -use syntax::feature_gate::{emit_feature_err, GateIssue}; use syntax::symbol::{Symbol, keywords}; use syntax::util::lev_distance::find_best_match_for_name; @@ -1862,22 +1861,22 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { primitive_type_table: PrimitiveTypeTable::new(), - def_map: NodeMap(), - import_map: NodeMap(), - freevars: NodeMap(), - freevars_seen: NodeMap(), + def_map: Default::default(), + import_map: Default::default(), + freevars: Default::default(), + freevars_seen: Default::default(), export_map: FxHashMap::default(), - trait_map: NodeMap(), + trait_map: Default::default(), module_map, - block_map: NodeMap(), + block_map: Default::default(), extern_module_map: FxHashMap::default(), binding_parent_modules: FxHashMap::default(), make_glob_map: make_glob_map == MakeGlobMap::Yes, - glob_map: NodeMap(), + glob_map: Default::default(), used_imports: FxHashSet::default(), - maybe_unused_trait_imports: NodeSet(), + maybe_unused_trait_imports: Default::default(), maybe_unused_extern_crates: Vec::new(), unused_labels: FxHashMap::default(), @@ -1907,7 +1906,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { name_already_seen: FxHashMap::default(), whitelisted_legacy_custom_derives: Vec::new(), potentially_unused_imports: Vec::new(), - struct_constructors: DefIdMap(), + struct_constructors: Default::default(), found_unresolved_macro: false, unused_macros: FxHashSet::default(), current_type_ascription: Vec::new(), @@ -2115,7 +2114,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { if !module.no_implicit_prelude { if ns == TypeNS { - if let Some(binding) = self.extern_prelude_get(ident, !record_used, false) { + if let Some(binding) = self.extern_prelude_get(ident, !record_used) { return Some(LexicalScopeBinding::Item(binding)); } } @@ -5022,7 +5021,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { self.name_already_seen.insert(name, span); } - fn extern_prelude_get(&mut self, ident: Ident, speculative: bool, skip_feature_gate: bool) + fn extern_prelude_get(&mut self, ident: Ident, speculative: bool) -> Option<&'a NameBinding<'a>> { if ident.is_path_segment_keyword() { // Make sure `self`, `super` etc produce an error when passed to here. @@ -5030,13 +5029,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { } self.extern_prelude.get(&ident.modern()).cloned().and_then(|entry| { if let Some(binding) = entry.extern_crate_item { - if !speculative && !skip_feature_gate && entry.introduced_by_item && - !self.session.features_untracked().extern_crate_item_prelude { - emit_feature_err(&self.session.parse_sess, "extern_crate_item_prelude", - ident.span, GateIssue::Language, - "use of extern prelude names introduced \ - with `extern crate` items is unstable"); - } Some(binding) } else { let crate_id = if !speculative { diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 921f7568b52..581756dc6bf 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -738,8 +738,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } WhereToResolve::ExternPrelude => { if use_prelude { - match self.extern_prelude_get(ident, !record_used, - innermost_result.is_some()) { + match self.extern_prelude_get(ident, !record_used) { Some(binding) => Ok((binding, Flags::PRELUDE)), None => Err(Determinacy::determined( self.graph_root.unresolved_invocations.borrow().is_empty() @@ -906,7 +905,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { // but its `Def` should coincide with a crate passed with `--extern` // (otherwise there would be ambiguity) and we can skip feature error in this case. if ns != TypeNS || !use_prelude || - self.extern_prelude_get(ident, true, false).is_none() { + self.extern_prelude_get(ident, true).is_none() { let msg = "imports can only refer to extern crate names \ passed with `--extern` on stable channel"; let mut err = feature_err(&self.session.parse_sess, "uniform_paths", diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 9e5036b6e50..616cc9d2fc5 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -166,8 +166,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { assert!(!restricted_shadowing); match uniform_root_kind { UniformRootKind::ExternPrelude => { - return if let Some(binding) = - self.extern_prelude_get(ident, !record_used, false) { + return if let Some(binding) = self.extern_prelude_get(ident, !record_used) { Ok(binding) } else if !self.graph_root.unresolved_invocations.borrow().is_empty() { // Macro-expanded `extern crate` items can add names to extern prelude. @@ -843,12 +842,14 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { module } PathResult::Failed(span, msg, false) => { - assert!(directive.imported_module.get().is_none()); + assert!(!self.ambiguity_errors.is_empty() || + directive.imported_module.get().is_none()); resolve_error(self, span, ResolutionError::FailedToResolve(&msg)); return None; } PathResult::Failed(span, msg, true) => { - assert!(directive.imported_module.get().is_none()); + assert!(!self.ambiguity_errors.is_empty() || + directive.imported_module.get().is_none()); return if let Some((suggested_path, note)) = self.make_path_suggestion( span, directive.module_path.clone(), &directive.parent_scope ) { @@ -1164,7 +1165,10 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { None => continue, }; - if binding.is_import() || binding.is_macro_def() { + // Filter away "empty import canaries". + let is_non_canary_import = + binding.is_import() && binding.vis != ty::Visibility::Invisible; + if is_non_canary_import || binding.is_macro_def() { let def = binding.def(); if def != Def::Err { if let Some(def_id) = def.opt_def_id() { diff --git a/src/librustc_target/abi/call/arm.rs b/src/librustc_target/abi/call/arm.rs index b4ffae7385a..bf497c09bdc 100644 --- a/src/librustc_target/abi/call/arm.rs +++ b/src/librustc_target/abi/call/arm.rs @@ -93,7 +93,7 @@ fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>, vfp: bool) } } - let align = arg.layout.align.abi(); + let align = arg.layout.align.abi.bytes(); let total = arg.layout.size; arg.cast_to(Uniform { unit: if align <= 4 { Reg::i32() } else { Reg::i64() }, diff --git a/src/librustc_target/abi/call/mips.rs b/src/librustc_target/abi/call/mips.rs index a40cb6c76f0..abe0bd07892 100644 --- a/src/librustc_target/abi/call/mips.rs +++ b/src/librustc_target/abi/call/mips.rs @@ -27,21 +27,21 @@ fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType, offset: &mut Size) { let dl = cx.data_layout(); let size = arg.layout.size; - let align = arg.layout.align.max(dl.i32_align).min(dl.i64_align); + let align = arg.layout.align.max(dl.i32_align).min(dl.i64_align).abi; if arg.layout.is_aggregate() { arg.cast_to(Uniform { unit: Reg::i32(), total: size }); - if !offset.is_abi_aligned(align) { + if !offset.is_aligned(align) { arg.pad_with(Reg::i32()); } } else { arg.extend_integer_width_to(32); } - *offset = offset.abi_align(align) + size.abi_align(align); + *offset = offset.align_to(align) + size.align_to(align); } pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType) diff --git a/src/librustc_target/abi/call/mips64.rs b/src/librustc_target/abi/call/mips64.rs index adf5a3c94ea..d375b163164 100644 --- a/src/librustc_target/abi/call/mips64.rs +++ b/src/librustc_target/abi/call/mips64.rs @@ -118,9 +118,9 @@ fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>) // We only care about aligned doubles if let abi::Abi::Scalar(ref scalar) = field.abi { if let abi::Float(abi::FloatTy::F64) = scalar.value { - if offset.is_abi_aligned(dl.f64_align) { + if offset.is_aligned(dl.f64_align.abi) { // Insert enough integers to cover [last_offset, offset) - assert!(last_offset.is_abi_aligned(dl.f64_align)); + assert!(last_offset.is_aligned(dl.f64_align.abi)); for _ in 0..((offset - last_offset).bits() / 64) .min((prefix.len() - prefix_index) as u64) { diff --git a/src/librustc_target/abi/call/mod.rs b/src/librustc_target/abi/call/mod.rs index 8f9ef2544e6..489bb37fc26 100644 --- a/src/librustc_target/abi/call/mod.rs +++ b/src/librustc_target/abi/call/mod.rs @@ -142,23 +142,23 @@ impl Reg { match self.kind { RegKind::Integer => { match self.size.bits() { - 1 => dl.i1_align, - 2..=8 => dl.i8_align, - 9..=16 => dl.i16_align, - 17..=32 => dl.i32_align, - 33..=64 => dl.i64_align, - 65..=128 => dl.i128_align, + 1 => dl.i1_align.abi, + 2..=8 => dl.i8_align.abi, + 9..=16 => dl.i16_align.abi, + 17..=32 => dl.i32_align.abi, + 33..=64 => dl.i64_align.abi, + 65..=128 => dl.i128_align.abi, _ => panic!("unsupported integer: {:?}", self) } } RegKind::Float => { match self.size.bits() { - 32 => dl.f32_align, - 64 => dl.f64_align, + 32 => dl.f32_align.abi, + 64 => dl.f64_align.abi, _ => panic!("unsupported float: {:?}", self) } } - RegKind::Vector => dl.vector_align(self.size) + RegKind::Vector => dl.vector_align(self.size).abi, } } } @@ -227,13 +227,13 @@ impl CastTarget { pub fn size(&self, cx: &C) -> Size { (self.prefix_chunk * self.prefix.iter().filter(|x| x.is_some()).count() as u64) - .abi_align(self.rest.align(cx)) + self.rest.total + .align_to(self.rest.align(cx)) + self.rest.total } pub fn align(&self, cx: &C) -> Align { self.prefix.iter() .filter_map(|x| x.map(|kind| Reg { kind, size: self.prefix_chunk }.align(cx))) - .fold(cx.data_layout().aggregate_align.max(self.rest.align(cx)), + .fold(cx.data_layout().aggregate_align.abi.max(self.rest.align(cx)), |acc, align| acc.max(align)) } } @@ -369,7 +369,7 @@ impl<'a, Ty> ArgType<'a, Ty> { attrs.pointee_size = self.layout.size; // FIXME(eddyb) We should be doing this, but at least on // i686-pc-windows-msvc, it results in wrong stack offsets. - // attrs.pointee_align = Some(self.layout.align); + // attrs.pointee_align = Some(self.layout.align.abi); let extra_attrs = if self.layout.is_unsized() { Some(ArgAttributes::new()) diff --git a/src/librustc_target/abi/call/powerpc.rs b/src/librustc_target/abi/call/powerpc.rs index b9b012020b7..a71f3226320 100644 --- a/src/librustc_target/abi/call/powerpc.rs +++ b/src/librustc_target/abi/call/powerpc.rs @@ -27,21 +27,21 @@ fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType, offset: &mut Size) { let dl = cx.data_layout(); let size = arg.layout.size; - let align = arg.layout.align.max(dl.i32_align).min(dl.i64_align); + let align = arg.layout.align.max(dl.i32_align).min(dl.i64_align).abi; if arg.layout.is_aggregate() { arg.cast_to(Uniform { unit: Reg::i32(), total: size }); - if !offset.is_abi_aligned(align) { + if !offset.is_aligned(align) { arg.pad_with(Reg::i32()); } } else { arg.extend_integer_width_to(32); } - *offset = offset.abi_align(align) + size.abi_align(align); + *offset = offset.align_to(align) + size.align_to(align); } pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType) diff --git a/src/librustc_target/abi/call/powerpc64.rs b/src/librustc_target/abi/call/powerpc64.rs index f7ef1390f14..99f07c5702a 100644 --- a/src/librustc_target/abi/call/powerpc64.rs +++ b/src/librustc_target/abi/call/powerpc64.rs @@ -13,7 +13,7 @@ // need to be fixed when PowerPC vector support is added. use abi::call::{FnType, ArgType, Reg, RegKind, Uniform}; -use abi::{Align, Endian, HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; +use abi::{Endian, HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; use spec::HasTargetSpec; #[derive(Debug, Clone, Copy, PartialEq)] @@ -120,8 +120,8 @@ fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>, abi: ABI) } else { // Aggregates larger than a doubleword should be padded // at the tail to fill out a whole number of doublewords. - let align = Align::from_bits(64, 64).unwrap(); - (Reg::i64(), size.abi_align(align)) + let reg_i64 = Reg::i64(); + (reg_i64, size.align_to(reg_i64.align(cx))) }; arg.cast_to(Uniform { diff --git a/src/librustc_target/abi/call/sparc.rs b/src/librustc_target/abi/call/sparc.rs index a40cb6c76f0..abe0bd07892 100644 --- a/src/librustc_target/abi/call/sparc.rs +++ b/src/librustc_target/abi/call/sparc.rs @@ -27,21 +27,21 @@ fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType, offset: &mut Size) { let dl = cx.data_layout(); let size = arg.layout.size; - let align = arg.layout.align.max(dl.i32_align).min(dl.i64_align); + let align = arg.layout.align.max(dl.i32_align).min(dl.i64_align).abi; if arg.layout.is_aggregate() { arg.cast_to(Uniform { unit: Reg::i32(), total: size }); - if !offset.is_abi_aligned(align) { + if !offset.is_aligned(align) { arg.pad_with(Reg::i32()); } } else { arg.extend_integer_width_to(32); } - *offset = offset.abi_align(align) + size.abi_align(align); + *offset = offset.align_to(align) + size.align_to(align); } pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType) diff --git a/src/librustc_target/abi/call/x86_64.rs b/src/librustc_target/abi/call/x86_64.rs index 4c944650893..f091f80924d 100644 --- a/src/librustc_target/abi/call/x86_64.rs +++ b/src/librustc_target/abi/call/x86_64.rs @@ -41,7 +41,7 @@ fn classify_arg<'a, Ty, C>(cx: &C, arg: &ArgType<'a, Ty>) where Ty: TyLayoutMethods<'a, C> + Copy, C: LayoutOf> + HasDataLayout { - if !off.is_abi_aligned(layout.align) { + if !off.is_aligned(layout.align.abi) { if !layout.is_zst() { return Err(Memory); } diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs index 22afb0da05b..50ce0ad6915 100644 --- a/src/librustc_target/abi/mod.rs +++ b/src/librustc_target/abi/mod.rs @@ -13,7 +13,7 @@ pub use self::Primitive::*; use spec::Target; -use std::{cmp, fmt}; +use std::fmt; use std::ops::{Add, Deref, Sub, Mul, AddAssign, Range, RangeInclusive}; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; @@ -24,42 +24,44 @@ pub mod call; /// for a target, which contains everything needed to compute layouts. pub struct TargetDataLayout { pub endian: Endian, - pub i1_align: Align, - pub i8_align: Align, - pub i16_align: Align, - pub i32_align: Align, - pub i64_align: Align, - pub i128_align: Align, - pub f32_align: Align, - pub f64_align: Align, + pub i1_align: AbiAndPrefAlign, + pub i8_align: AbiAndPrefAlign, + pub i16_align: AbiAndPrefAlign, + pub i32_align: AbiAndPrefAlign, + pub i64_align: AbiAndPrefAlign, + pub i128_align: AbiAndPrefAlign, + pub f32_align: AbiAndPrefAlign, + pub f64_align: AbiAndPrefAlign, pub pointer_size: Size, - pub pointer_align: Align, - pub aggregate_align: Align, + pub pointer_align: AbiAndPrefAlign, + pub aggregate_align: AbiAndPrefAlign, /// Alignments for vector types. - pub vector_align: Vec<(Size, Align)>, + pub vector_align: Vec<(Size, AbiAndPrefAlign)>, + pub instruction_address_space: u32, } impl Default for TargetDataLayout { /// Creates an instance of `TargetDataLayout`. fn default() -> TargetDataLayout { + let align = |bits| Align::from_bits(bits).unwrap(); TargetDataLayout { endian: Endian::Big, - i1_align: Align::from_bits(8, 8).unwrap(), - i8_align: Align::from_bits(8, 8).unwrap(), - i16_align: Align::from_bits(16, 16).unwrap(), - i32_align: Align::from_bits(32, 32).unwrap(), - i64_align: Align::from_bits(32, 64).unwrap(), - i128_align: Align::from_bits(32, 64).unwrap(), - f32_align: Align::from_bits(32, 32).unwrap(), - f64_align: Align::from_bits(64, 64).unwrap(), + i1_align: AbiAndPrefAlign::new(align(8)), + i8_align: AbiAndPrefAlign::new(align(8)), + i16_align: AbiAndPrefAlign::new(align(16)), + i32_align: AbiAndPrefAlign::new(align(32)), + i64_align: AbiAndPrefAlign { abi: align(32), pref: align(64) }, + i128_align: AbiAndPrefAlign { abi: align(32), pref: align(64) }, + f32_align: AbiAndPrefAlign::new(align(32)), + f64_align: AbiAndPrefAlign::new(align(64)), pointer_size: Size::from_bits(64), - pointer_align: Align::from_bits(64, 64).unwrap(), - aggregate_align: Align::from_bits(0, 64).unwrap(), + pointer_align: AbiAndPrefAlign::new(align(64)), + aggregate_align: AbiAndPrefAlign { abi: align(0), pref: align(64) }, vector_align: vec![ - (Size::from_bits(64), Align::from_bits(64, 64).unwrap()), - (Size::from_bits(128), Align::from_bits(128, 128).unwrap()) + (Size::from_bits(64), AbiAndPrefAlign::new(align(64))), + (Size::from_bits(128), AbiAndPrefAlign::new(align(128))), ], instruction_address_space: 0, } @@ -94,11 +96,17 @@ impl TargetDataLayout { if s.is_empty() { return Err(format!("missing alignment for `{}` in \"data-layout\"", cause)); } + let align_from_bits = |bits| { + Align::from_bits(bits).map_err(|err| { + format!("invalid alignment for `{}` in \"data-layout\": {}", + cause, err) + }) + }; let abi = parse_bits(s[0], "alignment", cause)?; let pref = s.get(1).map_or(Ok(abi), |pref| parse_bits(pref, "alignment", cause))?; - Align::from_bits(abi, pref).map_err(|err| { - format!("invalid alignment for `{}` in \"data-layout\": {}", - cause, err) + Ok(AbiAndPrefAlign { + abi: align_from_bits(abi)?, + pref: align_from_bits(pref)?, }) }; @@ -205,7 +213,7 @@ impl TargetDataLayout { } } - pub fn vector_align(&self, vec_size: Size) -> Align { + pub fn vector_align(&self, vec_size: Size) -> AbiAndPrefAlign { for &(size, align) in &self.vector_align { if size == vec_size { return align; @@ -213,8 +221,7 @@ impl TargetDataLayout { } // Default to natural alignment, which is what LLVM does. // That is, use the size, rounded up to a power of 2. - let align = vec_size.bytes().next_power_of_two(); - Align::from_bytes(align, align).unwrap() + AbiAndPrefAlign::new(Align::from_bytes(vec_size.bytes().next_power_of_two()).unwrap()) } } @@ -270,14 +277,14 @@ impl Size { } #[inline] - pub fn abi_align(self, align: Align) -> Size { - let mask = align.abi() - 1; + pub fn align_to(self, align: Align) -> Size { + let mask = align.bytes() - 1; Size::from_bytes((self.bytes() + mask) & !mask) } #[inline] - pub fn is_abi_aligned(self, align: Align) -> bool { - let mask = align.abi() - 1; + pub fn is_aligned(self, align: Align) -> bool { + let mask = align.bytes() - 1; self.bytes() & mask == 0 } @@ -358,78 +365,45 @@ impl AddAssign for Size { } } -/// Alignment of a type in bytes, both ABI-mandated and preferred. -/// Each field is a power of two, giving the alignment a maximum value -/// of 2(28 - 1), which is limited by LLVM to a -/// maximum capacity of 229 or 536870912. -#[derive(Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash, Debug, RustcEncodable, RustcDecodable)] +/// Alignment of a type in bytes (always a power of two). +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)] pub struct Align { - abi_pow2: u8, - pref_pow2: u8, + pow2: u8, } impl Align { - pub fn from_bits(abi: u64, pref: u64) -> Result { - Align::from_bytes(Size::from_bits(abi).bytes(), - Size::from_bits(pref).bytes()) + pub fn from_bits(bits: u64) -> Result { + Align::from_bytes(Size::from_bits(bits).bytes()) } - pub fn from_bytes(abi: u64, pref: u64) -> Result { - let log2 = |align: u64| { - // Treat an alignment of 0 bytes like 1-byte alignment. - if align == 0 { - return Ok(0); - } - - let mut bytes = align; - let mut pow: u8 = 0; - while (bytes & 1) == 0 { - pow += 1; - bytes >>= 1; - } - if bytes != 1 { - Err(format!("`{}` is not a power of 2", align)) - } else if pow > 29 { - Err(format!("`{}` is too large", align)) - } else { - Ok(pow) - } - }; - - Ok(Align { - abi_pow2: log2(abi)?, - pref_pow2: log2(pref)?, - }) - } - - pub fn abi(self) -> u64 { - 1 << self.abi_pow2 - } - - pub fn pref(self) -> u64 { - 1 << self.pref_pow2 - } - - pub fn abi_bits(self) -> u64 { - self.abi() * 8 - } - - pub fn pref_bits(self) -> u64 { - self.pref() * 8 - } - - pub fn min(self, other: Align) -> Align { - Align { - abi_pow2: cmp::min(self.abi_pow2, other.abi_pow2), - pref_pow2: cmp::min(self.pref_pow2, other.pref_pow2), + pub fn from_bytes(align: u64) -> Result { + // Treat an alignment of 0 bytes like 1-byte alignment. + if align == 0 { + return Ok(Align { pow2: 0 }); } + + let mut bytes = align; + let mut pow2: u8 = 0; + while (bytes & 1) == 0 { + pow2 += 1; + bytes >>= 1; + } + if bytes != 1 { + return Err(format!("`{}` is not a power of 2", align)); + } + if pow2 > 29 { + return Err(format!("`{}` is too large", align)); + } + + Ok(Align { pow2 }) } - pub fn max(self, other: Align) -> Align { - Align { - abi_pow2: cmp::max(self.abi_pow2, other.abi_pow2), - pref_pow2: cmp::max(self.pref_pow2, other.pref_pow2), - } + pub fn bytes(self) -> u64 { + 1 << self.pow2 + } + + pub fn bits(self) -> u64 { + self.bytes() * 8 } /// Compute the best alignment possible for the given offset @@ -437,10 +411,8 @@ impl Align { /// /// NB: for an offset of `0`, this happens to return `2^64`. pub fn max_for_offset(offset: Size) -> Align { - let pow2 = offset.bytes().trailing_zeros() as u8; Align { - abi_pow2: pow2, - pref_pow2: pow2, + pow2: offset.bytes().trailing_zeros() as u8, } } @@ -451,6 +423,36 @@ impl Align { } } +/// A pair of aligments, ABI-mandated and preferred. +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)] +pub struct AbiAndPrefAlign { + pub abi: Align, + pub pref: Align, +} + +impl AbiAndPrefAlign { + pub fn new(align: Align) -> AbiAndPrefAlign { + AbiAndPrefAlign { + abi: align, + pref: align, + } + } + + pub fn min(self, other: AbiAndPrefAlign) -> AbiAndPrefAlign { + AbiAndPrefAlign { + abi: self.abi.min(other.abi), + pref: self.pref.min(other.pref), + } + } + + pub fn max(self, other: AbiAndPrefAlign) -> AbiAndPrefAlign { + AbiAndPrefAlign { + abi: self.abi.max(other.abi), + pref: self.pref.max(other.pref), + } + } +} + /// Integers, also used for enum discriminants. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] pub enum Integer { @@ -472,7 +474,7 @@ impl Integer { } } - pub fn align(self, cx: &C) -> Align { + pub fn align(self, cx: &C) -> AbiAndPrefAlign { let dl = cx.data_layout(); match self { @@ -507,12 +509,11 @@ impl Integer { } /// Find the smallest integer with the given alignment. - pub fn for_abi_align(cx: &C, align: Align) -> Option { + pub fn for_align(cx: &C, wanted: Align) -> Option { let dl = cx.data_layout(); - let wanted = align.abi(); for &candidate in &[I8, I16, I32, I64, I128] { - if wanted == candidate.align(dl).abi() && wanted == candidate.size().bytes() { + if wanted == candidate.align(dl).abi && wanted.bytes() == candidate.size().bytes() { return Some(candidate); } } @@ -520,13 +521,12 @@ impl Integer { } /// Find the largest integer with the given alignment or less. - pub fn approximate_abi_align(cx: &C, align: Align) -> Integer { + pub fn approximate_align(cx: &C, wanted: Align) -> Integer { let dl = cx.data_layout(); - let wanted = align.abi(); // FIXME(eddyb) maybe include I128 in the future, when it works everywhere. for &candidate in &[I64, I32, I16] { - if wanted >= candidate.align(dl).abi() && wanted >= candidate.size().bytes() { + if wanted >= candidate.align(dl).abi && wanted.bytes() >= candidate.size().bytes() { return candidate; } } @@ -597,7 +597,7 @@ impl<'a, 'tcx> Primitive { } } - pub fn align(self, cx: &C) -> Align { + pub fn align(self, cx: &C) -> AbiAndPrefAlign { let dl = cx.data_layout(); match self { @@ -868,7 +868,7 @@ pub struct LayoutDetails { pub variants: Variants, pub fields: FieldPlacement, pub abi: Abi, - pub align: Align, + pub align: AbiAndPrefAlign, pub size: Size } @@ -949,8 +949,4 @@ impl<'a, Ty> TyLayout<'a, Ty> { Abi::Aggregate { sized } => sized && self.size.bytes() == 0 } } - - pub fn size_and_align(&self) -> (Size, Align) { - (self.size, self.align) - } } diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index f67152ee90b..75ba4d9bd11 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -414,6 +414,8 @@ supported_targets! { ("riscv32imac-unknown-none-elf", riscv32imac_unknown_none_elf), ("aarch64-unknown-none", aarch64_unknown_none), + + ("x86_64-fortanix-unknown-sgx", x86_64_fortanix_unknown_sgx), } /// Everything `rustc` knows about how to compile for a specific target. @@ -685,6 +687,10 @@ pub struct TargetOptions { /// target features. This is `true` by default, and `false` for targets like /// wasm32 where the whole program either has simd or not. pub simd_types_indirect: bool, + + /// If set, have the linker export exactly these symbols, instead of using + /// the usual logic to figure this out from the crate itself. + pub override_export_symbols: Option> } impl Default for TargetOptions { @@ -765,6 +771,7 @@ impl Default for TargetOptions { emit_debug_gdb_scripts: true, requires_uwtable: false, simd_types_indirect: true, + override_export_symbols: None, } } } @@ -900,6 +907,14 @@ impl Target { ) ); } ); + ($key_name:ident, opt_list) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + obj.find(&name[..]).map(|o| o.as_array() + .map(|v| base.options.$key_name = Some(v.iter() + .map(|a| a.as_string().unwrap().to_string()).collect()) + ) + ); + } ); ($key_name:ident, optional) => ( { let name = (stringify!($key_name)).replace("_", "-"); if let Some(o) = obj.find(&name[..]) { @@ -1046,6 +1061,7 @@ impl Target { key!(emit_debug_gdb_scripts, bool); key!(requires_uwtable, bool); key!(simd_types_indirect, bool); + key!(override_export_symbols, opt_list); if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) { for name in array.iter().filter_map(|abi| abi.as_string()) { @@ -1255,6 +1271,7 @@ impl ToJson for Target { target_option_val!(emit_debug_gdb_scripts); target_option_val!(requires_uwtable); target_option_val!(simd_types_indirect); + target_option_val!(override_export_symbols); if default.abi_blacklist != self.options.abi_blacklist { d.insert("abi-blacklist".to_string(), self.options.abi_blacklist.iter() diff --git a/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs b/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs new file mode 100644 index 00000000000..07383b3d648 --- /dev/null +++ b/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs @@ -0,0 +1,72 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::iter; + +use super::{LinkerFlavor, Target, TargetOptions, PanicStrategy}; + +pub fn target() -> Result { + const PRE_LINK_ARGS: &[&str] = &[ + "-Wl,--as-needed", + "-Wl,-z,noexecstack", + "-m64", + "-fuse-ld=gold", + "-nostdlib", + "-shared", + "-Wl,-e,sgx_entry", + "-Wl,-Bstatic", + "-Wl,--gc-sections", + "-Wl,-z,text", + "-Wl,-z,norelro", + "-Wl,--rosegment", + "-Wl,--no-undefined", + "-Wl,--error-unresolved-symbols", + "-Wl,--no-undefined-version", + "-Wl,-Bsymbolic", + "-Wl,--export-dynamic", + ]; + const EXPORT_SYMBOLS: &[&str] = &[ + "sgx_entry", + "HEAP_BASE", + "HEAP_SIZE", + "RELA", + "RELACOUNT", + "ENCLAVE_SIZE", + "CFGDATA_BASE", + "DEBUG", + ]; + let opts = TargetOptions { + dynamic_linking: false, + executables: true, + linker_is_gnu: true, + max_atomic_width: Some(64), + panic_strategy: PanicStrategy::Abort, + cpu: "x86-64".into(), + position_independent_executables: true, + pre_link_args: iter::once( + (LinkerFlavor::Gcc, PRE_LINK_ARGS.iter().cloned().map(String::from).collect()) + ).collect(), + override_export_symbols: Some(EXPORT_SYMBOLS.iter().cloned().map(String::from).collect()), + ..Default::default() + }; + Ok(Target { + llvm_target: "x86_64-unknown-linux-gnu".into(), + target_endian: "little".into(), + target_pointer_width: "64".into(), + target_c_int_width: "32".into(), + target_os: "unknown".into(), + target_env: "sgx".into(), + target_vendor: "fortanix".into(), + data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".into(), + arch: "x86_64".into(), + linker_flavor: LinkerFlavor::Gcc, + options: opts, + }) +} diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index d388d756438..a8164c85e82 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -182,7 +182,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { item_segment: &hir::PathSegment) -> &'tcx Substs<'tcx> { - let (substs, assoc_bindings) = item_segment.with_generic_args(|generic_args| { + let (substs, assoc_bindings, _) = item_segment.with_generic_args(|generic_args| { self.create_substs_for_ast_path( span, def_id, @@ -256,7 +256,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { }, def.parent.is_none() && def.has_self, // `has_self` seg.infer_types || suppress_mismatch, // `infer_types` - ) + ).0 } /// Check that the correct number of generic arguments have been provided. @@ -269,7 +269,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { position: GenericArgPosition, has_self: bool, infer_types: bool, - ) -> bool { + ) -> (bool, Option>) { // At this stage we are guaranteed that the generic arguments are in the correct order, e.g. // that lifetimes will proceed types. So it suffices to check the number of each generic // arguments in order to validate them with respect to the generic parameters. @@ -303,13 +303,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { let mut err = tcx.sess.struct_span_err(span, msg); err.span_note(span_late, note); err.emit(); - return true; + return (true, None); } else { let mut multispan = MultiSpan::from_span(span); multispan.push_span_label(span_late, note.to_string()); tcx.lint_node(lint::builtin::LATE_BOUND_LIFETIME_ARGUMENTS, args.args[0].id(), multispan, msg); - return false; + return (false, None); } } } @@ -323,7 +323,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { // For kinds without defaults (i.e. lifetimes), `required == permitted`. // For other kinds (i.e. types), `permitted` may be greater than `required`. if required <= provided && provided <= permitted { - return false; + return (false, None); } // Unfortunately lifetime and type parameter mismatches are typically styled @@ -338,33 +338,28 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { (required, "") }; - let mut span = span; - let label = if required == permitted && provided > permitted { - let diff = provided - permitted; - if diff == 1 { - // In the case when the user has provided too many arguments, - // we want to point to the first unexpected argument. - let first_superfluous_arg: &GenericArg = &args.args[offset + permitted]; - span = first_superfluous_arg.span(); - } - format!( - "{}unexpected {} argument{}", - if diff != 1 { format!("{} ", diff) } else { String::new() }, - kind, - if diff != 1 { "s" } else { "" }, - ) + let mut potential_assoc_types: Option> = None; + let (spans, label) = if required == permitted && provided > permitted { + // In the case when the user has provided too many arguments, + // we want to point to the unexpected arguments. + let spans: Vec = args.args[offset+permitted .. offset+provided] + .iter() + .map(|arg| arg.span()) + .collect(); + potential_assoc_types = Some(spans.clone()); + (spans, format!( "unexpected {} argument", kind)) } else { - format!( + (vec![span], format!( "expected {}{} {} argument{}", quantifier, bound, kind, if bound != 1 { "s" } else { "" }, - ) + )) }; - tcx.sess.struct_span_err_with_code( - span, + let mut err = tcx.sess.struct_span_err_with_code( + spans.clone(), &format!( "wrong number of {} arguments: expected {}{}, found {}", kind, @@ -373,9 +368,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { provided, ), DiagnosticId::Error("E0107".into()) - ).span_label(span, label).emit(); + ); + for span in spans { + err.span_label(span, label.as_str()); + } + err.emit(); - provided > required // `suppress_error` + (provided > required, // `suppress_error` + potential_assoc_types) }; if !infer_lifetimes || arg_counts.lifetimes > param_counts.lifetimes { @@ -397,7 +397,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { arg_counts.lifetimes, ) } else { - false + (false, None) } } @@ -555,7 +555,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { generic_args: &hir::GenericArgs, infer_types: bool, self_ty: Option>) - -> (&'tcx Substs<'tcx>, Vec>) + -> (&'tcx Substs<'tcx>, Vec>, Option>) { // If the type is parameterized by this region, then replace this // region with the current anon region binding (in other words, @@ -571,7 +571,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { assert_eq!(generic_params.has_self, self_ty.is_some()); let has_self = generic_params.has_self; - Self::check_generic_arg_count( + let (_, potential_assoc_types) = Self::check_generic_arg_count( self.tcx(), span, &generic_params, @@ -676,7 +676,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { debug!("create_substs_for_ast_path(generic_params={:?}, self_ty={:?}) -> {:?}", generic_params, self_ty, substs); - (substs, assoc_bindings) + (substs, assoc_bindings, potential_assoc_types) } /// Instantiates the path for the given trait reference, assuming that it's @@ -718,7 +718,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { self_ty: Ty<'tcx>, poly_projections: &mut Vec<(ty::PolyProjectionPredicate<'tcx>, Span)>, speculative: bool) - -> ty::PolyTraitRef<'tcx> + -> (ty::PolyTraitRef<'tcx>, Option>) { let trait_def_id = self.trait_def_id(trait_ref); @@ -726,11 +726,12 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1); - let (substs, assoc_bindings) = - self.create_substs_for_ast_trait_ref(trait_ref.path.span, - trait_def_id, - self_ty, - trait_ref.path.segments.last().unwrap()); + let (substs, assoc_bindings, potential_assoc_types) = self.create_substs_for_ast_trait_ref( + trait_ref.path.span, + trait_def_id, + self_ty, + trait_ref.path.segments.last().unwrap(), + ); let poly_trait_ref = ty::Binder::bind(ty::TraitRef::new(trait_def_id, substs)); let mut dup_bindings = FxHashMap::default(); @@ -745,14 +746,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { debug!("instantiate_poly_trait_ref({:?}, projections={:?}) -> {:?}", trait_ref, poly_projections, poly_trait_ref); - poly_trait_ref + (poly_trait_ref, potential_assoc_types) } pub fn instantiate_poly_trait_ref(&self, poly_trait_ref: &hir::PolyTraitRef, self_ty: Ty<'tcx>, poly_projections: &mut Vec<(ty::PolyProjectionPredicate<'tcx>, Span)>) - -> ty::PolyTraitRef<'tcx> + -> (ty::PolyTraitRef<'tcx>, Option>) { self.instantiate_poly_trait_ref_inner(&poly_trait_ref.trait_ref, self_ty, poly_projections, false) @@ -765,7 +766,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { trait_segment: &hir::PathSegment) -> ty::TraitRef<'tcx> { - let (substs, assoc_bindings) = + let (substs, assoc_bindings, _) = self.create_substs_for_ast_trait_ref(span, trait_def_id, self_ty, @@ -774,13 +775,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { ty::TraitRef::new(trait_def_id, substs) } - fn create_substs_for_ast_trait_ref(&self, - span: Span, - trait_def_id: DefId, - self_ty: Ty<'tcx>, - trait_segment: &hir::PathSegment) - -> (&'tcx Substs<'tcx>, Vec>) - { + fn create_substs_for_ast_trait_ref( + &self, + span: Span, + trait_def_id: DefId, + self_ty: Ty<'tcx>, + trait_segment: &hir::PathSegment, + ) -> (&'tcx Substs<'tcx>, Vec>, Option>) { debug!("create_substs_for_ast_trait_ref(trait_segment={:?})", trait_segment); @@ -970,9 +971,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { let mut projection_bounds = Vec::new(); let dummy_self = tcx.mk_ty(TRAIT_OBJECT_DUMMY_SELF); - let principal = self.instantiate_poly_trait_ref(&trait_bounds[0], - dummy_self, - &mut projection_bounds); + let (principal, potential_assoc_types) = self.instantiate_poly_trait_ref( + &trait_bounds[0], + dummy_self, + &mut projection_bounds, + ); debug!("principal: {:?}", principal); for trait_bound in trait_bounds[1..].iter() { @@ -1027,16 +1030,74 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { associated_types.remove(&projection_bound.projection_def_id()); } - for item_def_id in associated_types { - let assoc_item = tcx.associated_item(item_def_id); - let trait_def_id = assoc_item.container.id(); - struct_span_err!(tcx.sess, span, E0191, "the value of the associated type `{}` \ - (from the trait `{}`) must be specified", - assoc_item.ident, - tcx.item_path_str(trait_def_id)) - .span_label(span, format!("missing associated type `{}` value", - assoc_item.ident)) - .emit(); + if !associated_types.is_empty() { + let names = associated_types.iter().map(|item_def_id| { + let assoc_item = tcx.associated_item(*item_def_id); + let trait_def_id = assoc_item.container.id(); + format!( + "`{}` (from the trait `{}`)", + assoc_item.ident, + tcx.item_path_str(trait_def_id), + ) + }).collect::>().join(", "); + let mut err = struct_span_err!( + tcx.sess, + span, + E0191, + "the value of the associated type{} {} must be specified", + if associated_types.len() == 1 { "" } else { "s" }, + names, + ); + let mut suggest = false; + let mut potential_assoc_types_spans = vec![]; + if let Some(potential_assoc_types) = potential_assoc_types { + if potential_assoc_types.len() == associated_types.len() { + // Only suggest when the amount of missing associated types is equals to the + // extra type arguments present, as that gives us a relatively high confidence + // that the user forgot to give the associtated type's name. The canonical + // example would be trying to use `Iterator` instead of + // `Iterator`. + suggest = true; + potential_assoc_types_spans = potential_assoc_types; + } + } + let mut suggestions = vec![]; + for (i, item_def_id) in associated_types.iter().enumerate() { + let assoc_item = tcx.associated_item(*item_def_id); + err.span_label( + span, + format!("associated type `{}` must be specified", assoc_item.ident), + ); + if item_def_id.is_local() { + err.span_label( + tcx.def_span(*item_def_id), + format!("`{}` defined here", assoc_item.ident), + ); + } + if suggest { + if let Ok(snippet) = tcx.sess.source_map().span_to_snippet( + potential_assoc_types_spans[i], + ) { + suggestions.push(( + potential_assoc_types_spans[i], + format!("{} = {}", assoc_item.ident, snippet), + )); + } + } + } + if !suggestions.is_empty() { + let msg = if suggestions.len() == 1 { + "if you meant to specify the associated type, write" + } else { + "if you meant to specify the associated types, write" + }; + err.multipart_suggestion_with_applicability( + msg, + suggestions, + Applicability::MaybeIncorrect, + ); + } + err.emit(); } // Erase the `dummy_self` (`TRAIT_OBJECT_DUMMY_SELF`) used above. diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index eed5d909063..e36c0ae2a19 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -643,11 +643,11 @@ impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> { }, infcx, fulfillment_cx: RefCell::new(TraitEngine::new(tcx)), - locals: RefCell::new(NodeMap()), - deferred_call_resolutions: RefCell::new(DefIdMap()), + locals: RefCell::new(Default::default()), + deferred_call_resolutions: RefCell::new(Default::default()), deferred_cast_checks: RefCell::new(Vec::new()), deferred_generator_interiors: RefCell::new(Vec::new()), - opaque_types: RefCell::new(DefIdMap()), + opaque_types: RefCell::new(Default::default()), implicit_region_bound, body_id, } @@ -1779,7 +1779,7 @@ fn check_transparent<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: De // We are currently checking the type this field came from, so it must be local let span = tcx.hir.span_if_local(field.did).unwrap(); let zst = layout.map(|layout| layout.is_zst()).unwrap_or(false); - let align1 = layout.map(|layout| layout.align.abi() == 1).unwrap_or(false); + let align1 = layout.map(|layout| layout.align.abi.bytes() == 1).unwrap_or(false); (span, zst, align1) }); @@ -1986,7 +1986,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { has_errors: Cell::new(false), enclosing_breakables: RefCell::new(EnclosingBreakables { stack: Vec::new(), - by_id: NodeMap(), + by_id: Default::default(), }), inh, } diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 4460d5f64ce..50f54bba3fd 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -56,7 +56,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let used_trait_imports = mem::replace( &mut self.tables.borrow_mut().used_trait_imports, - Lrc::new(DefIdSet()), + Lrc::new(DefIdSet::default()), ); debug!( "used_trait_imports({:?}) = {:?}", diff --git a/src/librustc_typeck/check_unused.rs b/src/librustc_typeck/check_unused.rs index 9d785dfb58a..22a96d4e908 100644 --- a/src/librustc_typeck/check_unused.rs +++ b/src/librustc_typeck/check_unused.rs @@ -24,7 +24,7 @@ use rustc::util::nodemap::DefIdSet; use rustc_data_structures::fx::FxHashMap; pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { - let mut used_trait_imports = DefIdSet(); + let mut used_trait_imports = DefIdSet::default(); for &body_id in tcx.hir.krate().bodies.keys() { let item_def_id = tcx.hir.body_owner_def_id(body_id); let imports = tcx.used_trait_imports(item_def_id); diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs index 370f8857f14..d9dff144129 100644 --- a/src/librustc_typeck/coherence/inherent_impls.rs +++ b/src/librustc_typeck/coherence/inherent_impls.rs @@ -22,7 +22,6 @@ use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc::hir; use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::ty::{self, CrateInherentImpls, TyCtxt}; -use rustc::util::nodemap::DefIdMap; use rustc_data_structures::sync::Lrc; use syntax::ast; @@ -37,9 +36,7 @@ pub fn crate_inherent_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let krate = tcx.hir.krate(); let mut collect = InherentCollect { tcx, - impls_map: CrateInherentImpls { - inherent_impls: DefIdMap() - } + impls_map: Default::default(), }; krate.visit_all_item_likes(&mut collect); Lrc::new(collect.impls_map) diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index f3c570e8400..a1bb0b53f1f 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1892,7 +1892,7 @@ fn explicit_predicates_of<'a, 'tcx>( &hir::GenericBound::Trait(ref poly_trait_ref, _) => { let mut projections = Vec::new(); - let trait_ref = AstConv::instantiate_poly_trait_ref( + let (trait_ref, _) = AstConv::instantiate_poly_trait_ref( &icx, poly_trait_ref, ty, @@ -2016,7 +2016,12 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>( let mut projection_bounds = Vec::new(); let mut trait_bounds: Vec<_> = trait_bounds.iter().map(|&bound| { - (astconv.instantiate_poly_trait_ref(bound, param_ty, &mut projection_bounds), bound.span) + let (poly_trait_ref, _) = astconv.instantiate_poly_trait_ref( + bound, + param_ty, + &mut projection_bounds, + ); + (poly_trait_ref, bound.span) }).collect(); let region_bounds = region_bounds @@ -2057,7 +2062,7 @@ fn predicates_from_bound<'tcx>( match *bound { hir::GenericBound::Trait(ref tr, hir::TraitBoundModifier::None) => { let mut projections = Vec::new(); - let pred = astconv.instantiate_poly_trait_ref(tr, param_ty, &mut projections); + let (pred, _) = astconv.instantiate_poly_trait_ref(tr, param_ty, &mut projections); iter::once((pred.to_predicate(), tr.span)).chain( projections .into_iter() diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 1f5998d8ca3..0fba311d7f7 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -389,7 +389,7 @@ pub fn hir_trait_to_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, hir_trait: let env_def_id = tcx.hir.local_def_id(env_node_id); let item_cx = self::collect::ItemCtxt::new(tcx, env_def_id); let mut projections = Vec::new(); - let principal = astconv::AstConv::instantiate_poly_trait_ref_inner( + let (principal, _) = astconv::AstConv::instantiate_poly_trait_ref_inner( &item_cx, hir_trait, tcx.types.err, &mut projections, true ); diff --git a/src/librustc_typeck/variance/terms.rs b/src/librustc_typeck/variance/terms.rs index 0aec31609b0..087d53b92d4 100644 --- a/src/librustc_typeck/variance/terms.rs +++ b/src/librustc_typeck/variance/terms.rs @@ -81,7 +81,7 @@ pub fn determine_parameters_to_be_inferred<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx> let mut terms_cx = TermsContext { tcx, arena, - inferred_starts: NodeMap(), + inferred_starts: Default::default(), inferred_terms: vec![], lang_items: lang_items(tcx), diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 0bd6f6bf8a2..aac0f9f94e3 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -351,13 +351,15 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt let warnings_lint_name = lint::builtin::WARNINGS.name; let missing_docs = rustc_lint::builtin::MISSING_DOCS.name; let missing_doc_example = rustc_lint::builtin::MISSING_DOC_CODE_EXAMPLES.name; + let private_doc_tests = rustc_lint::builtin::PRIVATE_DOC_TESTS.name; // In addition to those specific lints, we also need to whitelist those given through // command line, otherwise they'll get ignored and we don't want that. let mut whitelisted_lints = vec![warnings_lint_name.to_owned(), intra_link_resolution_failure_name.to_owned(), missing_docs.to_owned(), - missing_doc_example.to_owned()]; + missing_doc_example.to_owned(), + private_doc_tests.to_owned()]; whitelisted_lints.extend(lint_opts.iter().map(|(lint, _)| lint).cloned()); diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index f5056cead56..7183cfe5711 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -24,9 +24,9 @@ use std::ops::Range; use core::DocContext; use fold::DocFolder; -use html::markdown::{find_testable_code, markdown_links, ErrorCodes, LangString}; +use html::markdown::markdown_links; -use passes::Pass; +use passes::{look_for_tests, Pass}; pub const COLLECT_INTRA_DOC_LINKS: Pass = Pass::early("collect-intra-doc-links", collect_intra_doc_links, @@ -214,43 +214,6 @@ impl<'a, 'tcx, 'rcx, 'cstore> LinkCollector<'a, 'tcx, 'rcx, 'cstore> { } } -fn look_for_tests<'a, 'tcx: 'a, 'rcx: 'a, 'cstore: 'rcx>( - cx: &'a DocContext<'a, 'tcx, 'rcx, 'cstore>, - dox: &str, - item: &Item, -) { - if (item.is_mod() && cx.tcx.hir.as_local_node_id(item.def_id).is_none()) || - cx.as_local_node_id(item.def_id).is_none() { - // If non-local, no need to check anything. - return; - } - - struct Tests { - found_tests: usize, - } - - impl ::test::Tester for Tests { - fn add_test(&mut self, _: String, _: LangString, _: usize) { - self.found_tests += 1; - } - } - - let mut tests = Tests { - found_tests: 0, - }; - - if find_testable_code(&dox, &mut tests, ErrorCodes::No).is_ok() { - if tests.found_tests == 0 { - let mut diag = cx.tcx.struct_span_lint_node( - lint::builtin::MISSING_DOC_CODE_EXAMPLES, - NodeId::from_u32(0), - span_of_attrs(&item.attrs), - "Missing code example in this documentation"); - diag.emit(); - } - } -} - impl<'a, 'tcx, 'rcx, 'cstore> DocFolder for LinkCollector<'a, 'tcx, 'rcx, 'cstore> { fn fold_item(&mut self, mut item: Item) -> Option { let item_node_id = if item.is_mod() { @@ -313,7 +276,7 @@ impl<'a, 'tcx, 'rcx, 'cstore> DocFolder for LinkCollector<'a, 'tcx, 'rcx, 'cstor let cx = self.cx; let dox = item.attrs.collapsed_doc_value().unwrap_or_else(String::new); - look_for_tests(&cx, &dox, &item); + look_for_tests(&cx, &dox, &item, true); if !self.is_nightly_build { return None; @@ -488,7 +451,7 @@ fn macro_resolve(cx: &DocContext, path_str: &str) -> Option { None } -fn span_of_attrs(attrs: &Attributes) -> syntax_pos::Span { +pub fn span_of_attrs(attrs: &Attributes) -> syntax_pos::Span { if attrs.doc_strings.is_empty() { return DUMMY_SP; } diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index d00eb3257d4..eee7278e4f0 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -12,16 +12,22 @@ //! process. use rustc::hir::def_id::DefId; +use rustc::lint as lint; use rustc::middle::privacy::AccessLevels; use rustc::util::nodemap::DefIdSet; use std::mem; use std::fmt; +use syntax::ast::NodeId; use clean::{self, GetDefId, Item}; -use core::DocContext; +use core::{DocContext, DocAccessLevels}; use fold; use fold::StripItem; +use html::markdown::{find_testable_code, ErrorCodes, LangString}; + +use self::collect_intra_doc_links::span_of_attrs; + mod collapse_docs; pub use self::collapse_docs::COLLAPSE_DOCS; @@ -43,6 +49,9 @@ pub use self::propagate_doc_cfg::PROPAGATE_DOC_CFG; mod collect_intra_doc_links; pub use self::collect_intra_doc_links::COLLECT_INTRA_DOC_LINKS; +mod private_items_doc_tests; +pub use self::private_items_doc_tests::CHECK_PRIVATE_ITEMS_DOC_TESTS; + mod collect_trait_impls; pub use self::collect_trait_impls::COLLECT_TRAIT_IMPLS; @@ -128,6 +137,7 @@ impl Pass { /// The full list of passes. pub const PASSES: &'static [Pass] = &[ + CHECK_PRIVATE_ITEMS_DOC_TESTS, STRIP_HIDDEN, UNINDENT_COMMENTS, COLLAPSE_DOCS, @@ -141,6 +151,7 @@ pub const PASSES: &'static [Pass] = &[ /// The list of passes run by default. pub const DEFAULT_PASSES: &'static [&'static str] = &[ "collect-trait-impls", + "check-private-items-doc-tests", "strip-hidden", "strip-private", "collect-intra-doc-links", @@ -152,6 +163,7 @@ pub const DEFAULT_PASSES: &'static [&'static str] = &[ /// The list of default passes run with `--document-private-items` is passed to rustdoc. pub const DEFAULT_PRIVATE_PASSES: &'static [&'static str] = &[ "collect-trait-impls", + "check-private-items-doc-tests", "strip-priv-imports", "collect-intra-doc-links", "collapse-docs", @@ -348,3 +360,49 @@ impl fold::DocFolder for ImportStripper { } } } + +pub fn look_for_tests<'a, 'tcx: 'a, 'rcx: 'a, 'cstore: 'rcx>( + cx: &'a DocContext<'a, 'tcx, 'rcx, 'cstore>, + dox: &str, + item: &Item, + check_missing_code: bool, +) { + if cx.as_local_node_id(item.def_id).is_none() { + // If non-local, no need to check anything. + return; + } + + struct Tests { + found_tests: usize, + } + + impl ::test::Tester for Tests { + fn add_test(&mut self, _: String, _: LangString, _: usize) { + self.found_tests += 1; + } + } + + let mut tests = Tests { + found_tests: 0, + }; + + if find_testable_code(&dox, &mut tests, ErrorCodes::No).is_ok() { + if check_missing_code == true && tests.found_tests == 0 { + let mut diag = cx.tcx.struct_span_lint_node( + lint::builtin::MISSING_DOC_CODE_EXAMPLES, + NodeId::from_u32(0), + span_of_attrs(&item.attrs), + "Missing code example in this documentation"); + diag.emit(); + } else if check_missing_code == false && + tests.found_tests > 0 && + !cx.renderinfo.borrow().access_levels.is_doc_reachable(item.def_id) { + let mut diag = cx.tcx.struct_span_lint_node( + lint::builtin::PRIVATE_DOC_TESTS, + NodeId::from_u32(0), + span_of_attrs(&item.attrs), + "Documentation test in private item"); + diag.emit(); + } + } +} diff --git a/src/librustdoc/passes/private_items_doc_tests.rs b/src/librustdoc/passes/private_items_doc_tests.rs new file mode 100644 index 00000000000..7c5ce8894b1 --- /dev/null +++ b/src/librustdoc/passes/private_items_doc_tests.rs @@ -0,0 +1,49 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use clean::*; + +use core::DocContext; +use fold::DocFolder; + +use passes::{look_for_tests, Pass}; + +pub const CHECK_PRIVATE_ITEMS_DOC_TESTS: Pass = + Pass::early("check-private-items-doc-tests", check_private_items_doc_tests, + "check private items doc tests"); + +struct PrivateItemDocTestLinter<'a, 'tcx: 'a, 'rcx: 'a, 'cstore: 'rcx> { + cx: &'a DocContext<'a, 'tcx, 'rcx, 'cstore>, +} + +impl<'a, 'tcx, 'rcx, 'cstore> PrivateItemDocTestLinter<'a, 'tcx, 'rcx, 'cstore> { + fn new(cx: &'a DocContext<'a, 'tcx, 'rcx, 'cstore>) -> Self { + PrivateItemDocTestLinter { + cx, + } + } +} + +pub fn check_private_items_doc_tests(krate: Crate, cx: &DocContext) -> Crate { + let mut coll = PrivateItemDocTestLinter::new(cx); + + coll.fold_crate(krate) +} + +impl<'a, 'tcx, 'rcx, 'cstore> DocFolder for PrivateItemDocTestLinter<'a, 'tcx, 'rcx, 'cstore> { + fn fold_item(&mut self, item: Item) -> Option { + let cx = self.cx; + let dox = item.attrs.collapsed_doc_value().unwrap_or_else(String::new); + + look_for_tests(&cx, &dox, &item, false); + + self.fold_item_recur(item) + } +} diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs index 24dd4cc13bf..946c5c5fa9b 100644 --- a/src/librustdoc/passes/strip_hidden.rs +++ b/src/librustdoc/passes/strip_hidden.rs @@ -25,7 +25,7 @@ pub const STRIP_HIDDEN: Pass = /// Strip items marked `#[doc(hidden)]` pub fn strip_hidden(krate: clean::Crate, _: &DocContext) -> clean::Crate { - let mut retained = DefIdSet(); + let mut retained = DefIdSet::default(); // strip all #[doc(hidden)] items let krate = { diff --git a/src/librustdoc/passes/strip_private.rs b/src/librustdoc/passes/strip_private.rs index 46d0034497e..e9d927398e4 100644 --- a/src/librustdoc/passes/strip_private.rs +++ b/src/librustdoc/passes/strip_private.rs @@ -24,7 +24,7 @@ pub const STRIP_PRIVATE: Pass = /// crate, specified by the `xcrate` flag. pub fn strip_private(mut krate: clean::Crate, cx: &DocContext) -> clean::Crate { // This stripper collects all *retained* nodes. - let mut retained = DefIdSet(); + let mut retained = DefIdSet::default(); let access_levels = cx.renderinfo.borrow().access_levels.clone(); // strip all private items diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index bb2f152edc6..d4650bd68d6 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -2026,12 +2026,12 @@ impl<'a, K, V, S> RawEntryMut<'a, K, V, S> { /// use std::collections::HashMap; /// /// let mut map: HashMap<&str, u32> = HashMap::new(); - /// map.raw_entry_mut().from_key("poneyland").or_insert("poneyland", 12); /// - /// assert_eq!(map["poneyland"], 12); + /// map.raw_entry_mut().from_key("poneyland").or_insert("poneyland", 3); + /// assert_eq!(map["poneyland"], 3); /// - /// *map.raw_entry_mut().from_key("poneyland").or_insert("poneyland", 12).1 += 10; - /// assert_eq!(map["poneyland"], 22); + /// *map.raw_entry_mut().from_key("poneyland").or_insert("poneyland", 10).1 *= 2; + /// assert_eq!(map["poneyland"], 6); /// ``` #[unstable(feature = "hash_raw_entry", issue = "54043")] pub fn or_insert(self, default_key: K, default_val: V) -> (&'a mut K, &'a mut V) @@ -2648,12 +2648,12 @@ impl<'a, K, V> Entry<'a, K, V> { /// use std::collections::HashMap; /// /// let mut map: HashMap<&str, u32> = HashMap::new(); - /// map.entry("poneyland").or_insert(12); /// - /// assert_eq!(map["poneyland"], 12); + /// map.entry("poneyland").or_insert(3); + /// assert_eq!(map["poneyland"], 3); /// - /// *map.entry("poneyland").or_insert(12) += 10; - /// assert_eq!(map["poneyland"], 22); + /// *map.entry("poneyland").or_insert(10) *= 2; + /// assert_eq!(map["poneyland"], 6); /// ``` pub fn or_insert(self, default: V) -> &'a mut V { match self { diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index f460d109c89..575903d576a 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -185,7 +185,7 @@ //! [slice]: primitive.slice.html //! [`atomic`]: sync/atomic/index.html //! [`collections`]: collections/index.html -//! [`for`]: ../book/first-edition/loops.html#for +//! [`for`]: ../book/ch03-05-control-flow.html#looping-through-a-collection-with-for //! [`format!`]: macro.format.html //! [`fs`]: fs/index.html //! [`io`]: io/index.html @@ -200,14 +200,14 @@ //! [`sync`]: sync/index.html //! [`thread`]: thread/index.html //! [`use std::env`]: env/index.html -//! [`use`]: ../book/first-edition/crates-and-modules.html#importing-modules-with-use -//! [crate root]: ../book/first-edition/crates-and-modules.html#basic-terminology-crates-and-modules +//! [`use`]: ../book/ch07-02-modules-and-use-to-control-scope-and-privacy.html#the-use-keyword-to-bring-paths-into-a-scope +//! [crate root]: ../book/ch07-01-packages-and-crates-for-making-libraries-and-executables.html //! [crates.io]: https://crates.io -//! [deref-coercions]: ../book/second-edition/ch15-02-deref.html#implicit-deref-coercions-with-functions-and-methods +//! [deref-coercions]: ../book/ch15-02-deref.html#implicit-deref-coercions-with-functions-and-methods //! [files]: fs/struct.File.html //! [multithreading]: thread/index.html //! [other]: #what-is-in-the-standard-library-documentation -//! [primitive types]: ../book/first-edition/primitive-types.html +//! [primitive types]: ../book/ch03-02-data-types.html #![stable(feature = "rust1", since = "1.0.0")] #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index 15fbb105921..0995ab3c373 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -32,7 +32,7 @@ /// /// [`Result`] enum is often a better solution for recovering from errors than /// using the `panic!` macro. This macro should be used to avoid proceeding using -/// incorrect values, such as from external sources. Detailed information about +/// incorrect values, such as from external sources. Detailed information about /// error handling is found in the [book]. /// /// The multi-argument form of this macro panics with a string and has the @@ -45,7 +45,7 @@ /// [`Result`]: ../std/result/enum.Result.html /// [`format!`]: ../std/macro.format.html /// [`compile_error!`]: ../std/macro.compile_error.html -/// [book]: ../book/second-edition/ch09-01-unrecoverable-errors-with-panic.html +/// [book]: ../book/ch09-00-error-handling.html /// /// # Current implementation /// @@ -839,8 +839,8 @@ mod builtin { /// boolean expression evaluation of configuration flags. This frequently /// leads to less duplicated code. /// - /// The syntax given to this macro is the same syntax as [the `cfg` - /// attribute](../book/first-edition/conditional-compilation.html). + /// The syntax given to this macro is the same syntax as the `cfg` + /// attribute. /// /// # Examples /// @@ -915,7 +915,7 @@ mod builtin { /// Unsafe code relies on `assert!` to enforce run-time invariants that, if /// violated could lead to unsafety. /// - /// Other use-cases of `assert!` include [testing] and enforcing run-time + /// Other use-cases of `assert!` include testing and enforcing run-time /// invariants in safe code (whose violation cannot result in unsafety). /// /// # Custom Messages @@ -926,7 +926,6 @@ mod builtin { /// /// [`panic!`]: macro.panic.html /// [`debug_assert!`]: macro.debug_assert.html - /// [testing]: ../book/second-edition/ch11-01-writing-tests.html#checking-results-with-the-assert-macro /// [`std::fmt`]: ../std/fmt/index.html /// /// # Examples diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index c2a16122a0d..48acc1096a6 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -22,7 +22,7 @@ /// `bool` implements various traits, such as [`BitAnd`], [`BitOr`], [`Not`], etc., /// which allow us to perform boolean operations using `&`, `|` and `!`. /// -/// [`if`] always demands a `bool` value. [`assert!`], being an important macro in testing, +/// `if` always demands a `bool` value. [`assert!`], being an important macro in testing, /// checks whether an expression returns `true`. /// /// ``` @@ -31,7 +31,6 @@ /// ``` /// /// [`assert!`]: macro.assert.html -/// [`if`]: ../book/first-edition/if.html /// [`BitAnd`]: ops/trait.BitAnd.html /// [`BitOr`]: ops/trait.BitOr.html /// [`Not`]: ops/trait.Not.html @@ -695,7 +694,7 @@ mod prim_str { } /// assert_eq!(tuple.2, 'c'); /// ``` /// -/// For more about tuples, see [the book](../book/first-edition/primitive-types.html#tuples). +/// For more about tuples, see [the book](../book/ch03-02-data-types.html#the-tuple-type). /// /// # Trait implementations /// diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index a7c97feee49..2f5db9bd081 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -499,9 +499,6 @@ declare_features! ( // Allows `const _: TYPE = VALUE` (active, underscore_const_names, "1.31.0", Some(54912), None), - // `extern crate foo as bar;` puts `bar` into extern prelude. - (active, extern_crate_item_prelude, "1.31.0", Some(55599), None), - // `reason = ` in lint attributes and `expect` lint attribute (active, lint_reasons, "1.31.0", Some(54503), None), ); @@ -691,6 +688,8 @@ declare_features! ( // impl Iterator for &mut Iterator // impl Debug for Foo<'_> (accepted, impl_header_lifetime_elision, "1.31.0", Some(15872), None), + // `extern crate foo as bar;` puts `bar` into extern prelude. + (accepted, extern_crate_item_prelude, "1.31.0", Some(55599), None), ); // If you change this, please modify src/doc/unstable-book as well. You must diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index b4fc9c2c6fc..e2f09affd4f 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1824,6 +1824,14 @@ impl<'a> Parser<'a> { fn parse_arg_general(&mut self, require_name: bool) -> PResult<'a, Arg> { maybe_whole!(self, NtArg, |x| x); + if let Ok(Some(_)) = self.parse_self_arg() { + let mut err = self.struct_span_err(self.prev_span, + "unexpected `self` argument in function"); + err.span_label(self.prev_span, + "`self` is only valid as the first argument of an associated function"); + return Err(err); + } + let (pat, ty) = if require_name || self.is_named_argument() { debug!("parse_arg_general parse_pat (require_name:{})", require_name); @@ -5385,11 +5393,12 @@ impl<'a> Parser<'a> { fn parse_fn_args(&mut self, named_args: bool, allow_variadic: bool) -> PResult<'a, (Vec , bool)> { + self.expect(&token::OpenDelim(token::Paren))?; + let sp = self.span; let mut variadic = false; let args: Vec> = - self.parse_unspanned_seq( - &token::OpenDelim(token::Paren), + self.parse_seq_to_before_end( &token::CloseDelim(token::Paren), SeqSep::trailing_allowed(token::Comma), |p| { @@ -5436,6 +5445,8 @@ impl<'a> Parser<'a> { } )?; + self.eat(&token::CloseDelim(token::Paren)); + let args: Vec<_> = args.into_iter().filter_map(|x| x).collect(); if variadic && args.is_empty() { diff --git a/src/test/compile-fail/issue-23595-1.rs b/src/test/compile-fail/issue-23595-1.rs index a3422d859c6..1e615c4c0db 100644 --- a/src/test/compile-fail/issue-23595-1.rs +++ b/src/test/compile-fail/issue-23595-1.rs @@ -16,9 +16,7 @@ trait Hierarchy { type Value; type ChildKey; type Children = Index; - //~^ ERROR: the value of the associated type `ChildKey` - //~^^ ERROR: the value of the associated type `Children` - //~^^^ ERROR: the value of the associated type `Value` + //~^ ERROR: the value of the associated types `Value` (from the trait `Hierarchy`), `ChildKey` fn data(&self) -> Option<(Self::Value, Self::Children)>; } diff --git a/src/test/debuginfo/pretty-std-collections.rs b/src/test/debuginfo/pretty-std-collections.rs index 8e37a884b34..0d3f4b90f23 100644 --- a/src/test/debuginfo/pretty-std-collections.rs +++ b/src/test/debuginfo/pretty-std-collections.rs @@ -28,6 +28,9 @@ // gdb-command: print vec_deque // gdb-check:$3 = VecDeque(len: 3, cap: 8) = {5, 3, 7} +// gdb-command: print vec_deque2 +// gdb-check:$4 = VecDeque(len: 7, cap: 8) = {2, 3, 4, 5, 6, 7, 8} + #![allow(unused_variables)] use std::collections::BTreeSet; use std::collections::BTreeMap; @@ -54,6 +57,14 @@ fn main() { vec_deque.push_back(3); vec_deque.push_back(7); + // VecDeque where an element was popped. + let mut vec_deque2 = VecDeque::new(); + for i in 1..8 { + vec_deque2.push_back(i) + } + vec_deque2.pop_front(); + vec_deque2.push_back(8); + zzz(); // #break } diff --git a/src/test/rustdoc-ui/failed-doctest-output.stdout b/src/test/rustdoc-ui/failed-doctest-output.stdout index 527f1355a9e..cab7bda6c67 100644 --- a/src/test/rustdoc-ui/failed-doctest-output.stdout +++ b/src/test/rustdoc-ui/failed-doctest-output.stdout @@ -12,7 +12,7 @@ error[E0425]: cannot find value `no` in this scope 3 | no | ^^ not found in this scope -thread '$DIR/failed-doctest-output.rs - OtherStruct (line 27)' panicked at 'couldn't compile the test', librustdoc/test.rs:323:13 +thread '$DIR/failed-doctest-output.rs - OtherStruct (line 27)' panicked at 'couldn't compile the test', src/librustdoc/test.rs:323:13 note: Run with `RUST_BACKTRACE=1` for a backtrace. ---- $DIR/failed-doctest-output.rs - SomeStruct (line 21) stdout ---- @@ -21,7 +21,7 @@ thread '$DIR/failed-doctest-output.rs - SomeStruct (line 21)' panicked at 'test thread 'main' panicked at 'oh no', $DIR/failed-doctest-output.rs:3:1 note: Run with `RUST_BACKTRACE=1` for a backtrace. -', librustdoc/test.rs:358:17 +', src/librustdoc/test.rs:358:17 failures: diff --git a/src/test/rustdoc-ui/private-item-doc-test.rs b/src/test/rustdoc-ui/private-item-doc-test.rs new file mode 100644 index 00000000000..5a13fe359f5 --- /dev/null +++ b/src/test/rustdoc-ui/private-item-doc-test.rs @@ -0,0 +1,20 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![deny(private_doc_tests)] + +mod foo { + /// private doc test + /// + /// ``` + /// assert!(false); + /// ``` + fn bar() {} +} diff --git a/src/test/rustdoc-ui/private-item-doc-test.stderr b/src/test/rustdoc-ui/private-item-doc-test.stderr new file mode 100644 index 00000000000..b43add7ea50 --- /dev/null +++ b/src/test/rustdoc-ui/private-item-doc-test.stderr @@ -0,0 +1,16 @@ +error: Documentation test in private item + --> $DIR/private-item-doc-test.rs:14:5 + | +LL | / /// private doc test +LL | | /// +LL | | /// ``` +LL | | /// assert!(false); +LL | | /// ``` + | |___________^ + | +note: lint level defined here + --> $DIR/private-item-doc-test.rs:11:9 + | +LL | #![deny(private_doc_tests)] + | ^^^^^^^^^^^^^^^^^ + diff --git a/src/test/ui-fulldeps/proc-macro/extern-prelude-extern-crate-proc-macro.rs b/src/test/ui-fulldeps/proc-macro/extern-prelude-extern-crate-proc-macro.rs index e320ad97135..25a2a376147 100644 --- a/src/test/ui-fulldeps/proc-macro/extern-prelude-extern-crate-proc-macro.rs +++ b/src/test/ui-fulldeps/proc-macro/extern-prelude-extern-crate-proc-macro.rs @@ -1,8 +1,6 @@ // compile-pass // edition:2018 -#![feature(extern_crate_item_prelude)] - extern crate proc_macro; use proc_macro::TokenStream; // OK diff --git a/src/test/ui/associated-type/associated-type-projection-from-multiple-supertraits.stderr b/src/test/ui/associated-type/associated-type-projection-from-multiple-supertraits.stderr index 7a10b6d021f..b4285c0de29 100644 --- a/src/test/ui/associated-type/associated-type-projection-from-multiple-supertraits.stderr +++ b/src/test/ui/associated-type/associated-type-projection-from-multiple-supertraits.stderr @@ -25,8 +25,11 @@ LL | fn dent_object(c: BoxCar) { error[E0191]: the value of the associated type `Color` (from the trait `Vehicle`) must be specified --> $DIR/associated-type-projection-from-multiple-supertraits.rs:33:26 | +LL | type Color; + | ----------- `Color` defined here +... LL | fn dent_object(c: BoxCar) { - | ^^^^^^^^^^^^^^^^^^^ missing associated type `Color` value + | ^^^^^^^^^^^^^^^^^^^ associated type `Color` must be specified error[E0221]: ambiguous associated type `Color` in bounds of `C` --> $DIR/associated-type-projection-from-multiple-supertraits.rs:38:29 diff --git a/src/test/ui/associated-types/associated-types-incomplete-object.rs b/src/test/ui/associated-types/associated-types-incomplete-object.rs index 9f1df14605b..e575fd695b2 100644 --- a/src/test/ui/associated-types/associated-types-incomplete-object.rs +++ b/src/test/ui/associated-types/associated-types-incomplete-object.rs @@ -37,6 +37,5 @@ pub fn main() { //~^ ERROR the value of the associated type `A` (from the trait `Foo`) must be specified let d = &42isize as &Foo; - //~^ ERROR the value of the associated type `A` (from the trait `Foo`) must be specified - //~| ERROR the value of the associated type `B` (from the trait `Foo`) must be specified + //~^ ERROR the value of the associated types `A` (from the trait `Foo`), `B` (from the trait } diff --git a/src/test/ui/associated-types/associated-types-incomplete-object.stderr b/src/test/ui/associated-types/associated-types-incomplete-object.stderr index 95b1c631250..eb8e6f998a5 100644 --- a/src/test/ui/associated-types/associated-types-incomplete-object.stderr +++ b/src/test/ui/associated-types/associated-types-incomplete-object.stderr @@ -1,27 +1,35 @@ error[E0191]: the value of the associated type `B` (from the trait `Foo`) must be specified --> $DIR/associated-types-incomplete-object.rs:33:26 | +LL | type B; + | ------- `B` defined here +... LL | let b = &42isize as &Foo; - | ^^^^^^^^^^^^ missing associated type `B` value + | ^^^^^^^^^^^^ associated type `B` must be specified error[E0191]: the value of the associated type `A` (from the trait `Foo`) must be specified --> $DIR/associated-types-incomplete-object.rs:36:26 | +LL | type A; + | ------- `A` defined here +... LL | let c = &42isize as &Foo; - | ^^^^^^^^^^^ missing associated type `A` value + | ^^^^^^^^^^^ associated type `A` must be specified -error[E0191]: the value of the associated type `A` (from the trait `Foo`) must be specified +error[E0191]: the value of the associated types `A` (from the trait `Foo`), `B` (from the trait `Foo`) must be specified --> $DIR/associated-types-incomplete-object.rs:39:26 | +LL | type A; + | ------- `A` defined here +LL | type B; + | ------- `B` defined here +... LL | let d = &42isize as &Foo; - | ^^^ missing associated type `A` value + | ^^^ + | | + | associated type `A` must be specified + | associated type `B` must be specified -error[E0191]: the value of the associated type `B` (from the trait `Foo`) must be specified - --> $DIR/associated-types-incomplete-object.rs:39:26 - | -LL | let d = &42isize as &Foo; - | ^^^ missing associated type `B` value - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0191`. diff --git a/src/test/ui/consts/const-err4.rs b/src/test/ui/consts/const-err4.rs index 0bbc254453c..129177e9a1a 100644 --- a/src/test/ui/consts/const-err4.rs +++ b/src/test/ui/consts/const-err4.rs @@ -16,7 +16,7 @@ union Foo { enum Bar { Boo = [unsafe { Foo { b: () }.a }; 4][3], - //~^ ERROR evaluation of constant value failed + //~^ ERROR it is undefined behavior to use this value } fn main() { diff --git a/src/test/ui/consts/const-err4.stderr b/src/test/ui/consts/const-err4.stderr index bb50f38062e..38a8f75a5c2 100644 --- a/src/test/ui/consts/const-err4.stderr +++ b/src/test/ui/consts/const-err4.stderr @@ -1,8 +1,10 @@ -error[E0080]: evaluation of constant value failed +error[E0080]: it is undefined behavior to use this value --> $DIR/const-err4.rs:18:11 | LL | Boo = [unsafe { Foo { b: () }.a }; 4][3], - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempted to read undefined bytes + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior error: aborting due to previous error diff --git a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.rs b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.rs index 23e1ab013ef..cc5ddb44016 100644 --- a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.rs +++ b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.rs @@ -37,7 +37,7 @@ fn main() { //~^ ERROR it is undefined behavior to use this value const I32_REF_U128_UNION: u128 = unsafe { Nonsense { int_32_ref: &3 }.uint_128 }; - //~^ ERROR any use of this value will cause an error + //~^ ERROR it is undefined behavior to use this value const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8 }; //~^ ERROR any use of this value will cause an error @@ -52,7 +52,7 @@ fn main() { //~^ ERROR it is undefined behavior to use this value const I32_REF_I128_UNION: i128 = unsafe { Nonsense { int_32_ref: &3 }.int_128 }; - //~^ ERROR any use of this value will cause an error + //~^ ERROR it is undefined behavior to use this value const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.float_32 }; //~^ ERROR any use of this value will cause an error diff --git a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr index 0126743eede..786338222e3 100644 --- a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr +++ b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr @@ -40,11 +40,13 @@ LL | const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uin | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior -error: any use of this value will cause an error +error[E0080]: it is undefined behavior to use this value --> $DIR/const-pointer-values-in-various-types.rs:39:5 | LL | const I32_REF_U128_UNION: u128 = unsafe { Nonsense { int_32_ref: &3 }.uint_128 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempted to read undefined bytes + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior error: any use of this value will cause an error --> $DIR/const-pointer-values-in-various-types.rs:42:5 @@ -78,11 +80,13 @@ LL | const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior -error: any use of this value will cause an error +error[E0080]: it is undefined behavior to use this value --> $DIR/const-pointer-values-in-various-types.rs:54:5 | LL | const I32_REF_I128_UNION: i128 = unsafe { Nonsense { int_32_ref: &3 }.int_128 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempted to read undefined bytes + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior error: any use of this value will cause an error --> $DIR/const-pointer-values-in-various-types.rs:57:5 diff --git a/src/test/ui/consts/const-eval/ub-enum.rs b/src/test/ui/consts/const-eval/ub-enum.rs index 89b44946441..2bf85e25a21 100644 --- a/src/test/ui/consts/const-eval/ub-enum.rs +++ b/src/test/ui/consts/const-eval/ub-enum.rs @@ -16,12 +16,12 @@ enum Enum { A = 0, } union TransmuteEnum { - a: &'static u8, - out: Enum, + in1: &'static u8, + out1: Enum, } // A pointer is guaranteed non-null -const BAD_ENUM: Enum = unsafe { TransmuteEnum { a: &1 }.out }; +const BAD_ENUM: Enum = unsafe { TransmuteEnum { in1: &1 }.out1 }; //~^ ERROR is undefined behavior // (Potentially) invalid enum discriminant @@ -48,8 +48,8 @@ const BAD_ENUM3: Enum2 = unsafe { TransmuteEnum2 { in2: &0 }.out1 }; const BAD_ENUM4: Wrap = unsafe { TransmuteEnum2 { in2: &0 }.out2 }; //~^ ERROR is undefined behavior -// Undef enum discriminant. In an arry to avoid `Scalar` layout. -const BAD_ENUM_UNDEF: [Enum2; 2] = [unsafe { TransmuteEnum2 { in3: () }.out1 }; 2]; +// Undef enum discriminant. +const BAD_ENUM_UNDEF : Enum2 = unsafe { TransmuteEnum2 { in3: () }.out1 }; //~^ ERROR is undefined behavior // Pointer value in an enum with a niche that is not just 0. diff --git a/src/test/ui/consts/const-eval/ub-enum.stderr b/src/test/ui/consts/const-eval/ub-enum.stderr index 5aae3a2f351..509faaa46f8 100644 --- a/src/test/ui/consts/const-eval/ub-enum.stderr +++ b/src/test/ui/consts/const-eval/ub-enum.stderr @@ -1,8 +1,8 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/ub-enum.rs:24:1 | -LL | const BAD_ENUM: Enum = unsafe { TransmuteEnum { a: &1 }.out }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected a valid enum discriminant +LL | const BAD_ENUM: Enum = unsafe { TransmuteEnum { in1: &1 }.out1 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected a valid enum discriminant | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior @@ -33,8 +33,8 @@ LL | const BAD_ENUM4: Wrap = unsafe { TransmuteEnum2 { in2: &0 }.out2 }; error[E0080]: it is undefined behavior to use this value --> $DIR/ub-enum.rs:52:1 | -LL | const BAD_ENUM_UNDEF: [Enum2; 2] = [unsafe { TransmuteEnum2 { in3: () }.out1 }; 2]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes at [0], but expected a valid enum discriminant +LL | const BAD_ENUM_UNDEF : Enum2 = unsafe { TransmuteEnum2 { in3: () }.out1 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected a valid enum discriminant | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior diff --git a/src/test/ui/consts/const-eval/union-const-eval-field.rs b/src/test/ui/consts/const-eval/union-const-eval-field.rs index c0bfbc17629..2bdad3af889 100644 --- a/src/test/ui/consts/const-eval/union-const-eval-field.rs +++ b/src/test/ui/consts/const-eval/union-const-eval-field.rs @@ -34,7 +34,8 @@ const fn read_field2() -> Field2 { } const fn read_field3() -> Field3 { - const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR any use of this value + const FIELD3: Field3 = unsafe { UNION.field3 }; + //~^ ERROR it is undefined behavior to use this value FIELD3 } diff --git a/src/test/ui/consts/const-eval/union-const-eval-field.stderr b/src/test/ui/consts/const-eval/union-const-eval-field.stderr index 565cd916ffc..ca7cf2b028c 100644 --- a/src/test/ui/consts/const-eval/union-const-eval-field.stderr +++ b/src/test/ui/consts/const-eval/union-const-eval-field.stderr @@ -1,10 +1,11 @@ -error: any use of this value will cause an error +error[E0080]: it is undefined behavior to use this value --> $DIR/union-const-eval-field.rs:37:5 | -LL | const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR any use of this value - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempted to read undefined bytes +LL | const FIELD3: Field3 = unsafe { UNION.field3 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes | - = note: #[deny(const_err)] on by default + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior error: aborting due to previous error +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/union-ice.rs b/src/test/ui/consts/const-eval/union-ice.rs index 0e4f1e09171..6bd63472b21 100644 --- a/src/test/ui/consts/const-eval/union-ice.rs +++ b/src/test/ui/consts/const-eval/union-ice.rs @@ -20,7 +20,7 @@ union DummyUnion { const UNION: DummyUnion = DummyUnion { field1: 1065353216 }; -const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR will cause an error +const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR it is undefined behavior to use this value const FIELD_PATH: Struct = Struct { //~ ERROR it is undefined behavior to use this value a: 42, diff --git a/src/test/ui/consts/const-eval/union-ice.stderr b/src/test/ui/consts/const-eval/union-ice.stderr index 98c2c1472aa..7cadef24617 100644 --- a/src/test/ui/consts/const-eval/union-ice.stderr +++ b/src/test/ui/consts/const-eval/union-ice.stderr @@ -1,10 +1,10 @@ -error: any use of this value will cause an error +error[E0080]: it is undefined behavior to use this value --> $DIR/union-ice.rs:23:1 | -LL | const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR will cause an error - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempted to read undefined bytes +LL | const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR it is undefined behavior to use this value + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes | - = note: #[deny(const_err)] on by default + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior error[E0080]: it is undefined behavior to use this value --> $DIR/union-ice.rs:25:1 diff --git a/src/test/ui/consts/min_const_fn/loop_ice.rs b/src/test/ui/consts/min_const_fn/loop_ice.rs new file mode 100644 index 00000000000..4278a8e2d00 --- /dev/null +++ b/src/test/ui/consts/min_const_fn/loop_ice.rs @@ -0,0 +1,5 @@ +const fn foo() { + loop {} //~ ERROR loops are not allowed in const fn +} + +fn main() {} diff --git a/src/test/ui/consts/min_const_fn/loop_ice.stderr b/src/test/ui/consts/min_const_fn/loop_ice.stderr new file mode 100644 index 00000000000..1424cea65af --- /dev/null +++ b/src/test/ui/consts/min_const_fn/loop_ice.stderr @@ -0,0 +1,8 @@ +error: loops are not allowed in const fn + --> $DIR/loop_ice.rs:2:5 + | +LL | loop {} //~ ERROR loops are not allowed in const fn + | ^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/error-codes/E0107.rs b/src/test/ui/error-codes/E0107.rs index 815c7fefd2a..87ac9e37853 100644 --- a/src/test/ui/error-codes/E0107.rs +++ b/src/test/ui/error-codes/E0107.rs @@ -26,7 +26,8 @@ struct Baz<'a, 'b, 'c> { //~| unexpected lifetime argument foo2: Foo<'a, 'b, 'c>, //~^ ERROR E0107 - //~| 2 unexpected lifetime arguments + //~| unexpected lifetime argument + //~| unexpected lifetime argument } fn main() {} diff --git a/src/test/ui/error-codes/E0107.stderr b/src/test/ui/error-codes/E0107.stderr index 497fa91bd4f..a07c92cf26a 100644 --- a/src/test/ui/error-codes/E0107.stderr +++ b/src/test/ui/error-codes/E0107.stderr @@ -11,10 +11,12 @@ LL | bar: Bar<'a>, | ^^ unexpected lifetime argument error[E0107]: wrong number of lifetime arguments: expected 1, found 3 - --> $DIR/E0107.rs:27:11 + --> $DIR/E0107.rs:27:19 | LL | foo2: Foo<'a, 'b, 'c>, - | ^^^^^^^^^^^^^^^ 2 unexpected lifetime arguments + | ^^ ^^ unexpected lifetime argument + | | + | unexpected lifetime argument error: aborting due to 3 previous errors diff --git a/src/test/ui/error-codes/E0191.stderr b/src/test/ui/error-codes/E0191.stderr index 08b0a845814..f07529e7e9e 100644 --- a/src/test/ui/error-codes/E0191.stderr +++ b/src/test/ui/error-codes/E0191.stderr @@ -1,8 +1,11 @@ error[E0191]: the value of the associated type `Bar` (from the trait `Trait`) must be specified --> $DIR/E0191.rs:15:12 | +LL | type Bar; + | --------- `Bar` defined here +... LL | type Foo = Trait; //~ ERROR E0191 - | ^^^^^ missing associated type `Bar` value + | ^^^^^ associated type `Bar` must be specified error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0220.stderr b/src/test/ui/error-codes/E0220.stderr index c8a587f2b53..d26e61fba8c 100644 --- a/src/test/ui/error-codes/E0220.stderr +++ b/src/test/ui/error-codes/E0220.stderr @@ -7,8 +7,11 @@ LL | type Foo = Trait; //~ ERROR E0220 error[E0191]: the value of the associated type `Bar` (from the trait `Trait`) must be specified --> $DIR/E0220.rs:15:12 | +LL | type Bar; + | --------- `Bar` defined here +... LL | type Foo = Trait; //~ ERROR E0220 - | ^^^^^^^^^^^^ missing associated type `Bar` value + | ^^^^^^^^^^^^ associated type `Bar` must be specified error: aborting due to 2 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-extern_crate_item_prelude.rs b/src/test/ui/feature-gates/feature-gate-extern_crate_item_prelude.rs deleted file mode 100644 index 27b9a34ff4e..00000000000 --- a/src/test/ui/feature-gates/feature-gate-extern_crate_item_prelude.rs +++ /dev/null @@ -1,46 +0,0 @@ -// edition:2018 - -#![feature(alloc, underscore_imports)] - -extern crate alloc; - -mod in_scope { - fn check() { - let v = alloc::vec![0]; - //~^ ERROR use of extern prelude names introduced with `extern crate` items is unstable - type A = alloc::boxed::Box; - //~^ ERROR use of extern prelude names introduced with `extern crate` items is unstable - } -} - -mod absolute { - fn check() { - let v = ::alloc::vec![0]; - //~^ ERROR use of extern prelude names introduced with `extern crate` items is unstable - type A = ::alloc::boxed::Box; - //~^ ERROR use of extern prelude names introduced with `extern crate` items is unstable - } -} - -mod import_in_scope { - use alloc as _; - //~^ ERROR use of extern prelude names introduced with `extern crate` items is unstable - use alloc::boxed; - //~^ ERROR use of extern prelude names introduced with `extern crate` items is unstable -} - -mod import_absolute { - use ::alloc; - //~^ ERROR use of extern prelude names introduced with `extern crate` items is unstable - use ::alloc::boxed; - //~^ ERROR use of extern prelude names introduced with `extern crate` items is unstable -} - -extern crate alloc as core; - -mod unrelated_crate_renamed { - type A = core::boxed::Box; - //~^ ERROR use of extern prelude names introduced with `extern crate` items is unstable -} - -fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-extern_crate_item_prelude.stderr b/src/test/ui/feature-gates/feature-gate-extern_crate_item_prelude.stderr deleted file mode 100644 index 103ab79ef84..00000000000 --- a/src/test/ui/feature-gates/feature-gate-extern_crate_item_prelude.stderr +++ /dev/null @@ -1,75 +0,0 @@ -error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #55599) - --> $DIR/feature-gate-extern_crate_item_prelude.rs:26:9 - | -LL | use alloc as _; - | ^^^^^ - | - = help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable - -error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #55599) - --> $DIR/feature-gate-extern_crate_item_prelude.rs:28:9 - | -LL | use alloc::boxed; - | ^^^^^ - | - = help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable - -error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #55599) - --> $DIR/feature-gate-extern_crate_item_prelude.rs:33:11 - | -LL | use ::alloc; - | ^^^^^ - | - = help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable - -error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #55599) - --> $DIR/feature-gate-extern_crate_item_prelude.rs:35:11 - | -LL | use ::alloc::boxed; - | ^^^^^ - | - = help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable - -error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #55599) - --> $DIR/feature-gate-extern_crate_item_prelude.rs:9:17 - | -LL | let v = alloc::vec![0]; - | ^^^^^ - | - = help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable - -error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #55599) - --> $DIR/feature-gate-extern_crate_item_prelude.rs:11:18 - | -LL | type A = alloc::boxed::Box; - | ^^^^^ - | - = help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable - -error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #55599) - --> $DIR/feature-gate-extern_crate_item_prelude.rs:18:19 - | -LL | let v = ::alloc::vec![0]; - | ^^^^^ - | - = help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable - -error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #55599) - --> $DIR/feature-gate-extern_crate_item_prelude.rs:20:20 - | -LL | type A = ::alloc::boxed::Box; - | ^^^^^ - | - = help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable - -error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #55599) - --> $DIR/feature-gate-extern_crate_item_prelude.rs:42:14 - | -LL | type A = core::boxed::Box; - | ^^^^ - | - = help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable - -error: aborting due to 9 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/imports/auxiliary/issue-55811.rs b/src/test/ui/imports/auxiliary/issue-55811.rs new file mode 100644 index 00000000000..877e4cdb0bd --- /dev/null +++ b/src/test/ui/imports/auxiliary/issue-55811.rs @@ -0,0 +1,5 @@ +mod m {} + +// These two imports should not conflict when this crate is loaded from some other crate. +use m::{}; +use m::{}; diff --git a/src/test/ui/imports/auxiliary/issue-56125.rs b/src/test/ui/imports/auxiliary/issue-56125.rs new file mode 100644 index 00000000000..0ff407756b3 --- /dev/null +++ b/src/test/ui/imports/auxiliary/issue-56125.rs @@ -0,0 +1,9 @@ +pub mod last_segment { + pub mod issue_56125 {} +} + +pub mod non_last_segment { + pub mod non_last_segment { + pub mod issue_56125 {} + } +} diff --git a/src/test/ui/imports/extern-prelude-extern-crate-absolute-expanded.rs b/src/test/ui/imports/extern-prelude-extern-crate-absolute-expanded.rs index b1154f2076b..cf91a9714ad 100644 --- a/src/test/ui/imports/extern-prelude-extern-crate-absolute-expanded.rs +++ b/src/test/ui/imports/extern-prelude-extern-crate-absolute-expanded.rs @@ -1,8 +1,6 @@ // compile-pass // edition:2018 -#![feature(extern_crate_item_prelude)] - macro_rules! define_iso { () => { extern crate std as iso; }} diff --git a/src/test/ui/imports/extern-prelude-extern-crate-cfg.rs b/src/test/ui/imports/extern-prelude-extern-crate-cfg.rs index c48a65798b6..6117e5f6f3c 100644 --- a/src/test/ui/imports/extern-prelude-extern-crate-cfg.rs +++ b/src/test/ui/imports/extern-prelude-extern-crate-cfg.rs @@ -1,7 +1,6 @@ // compile-pass // compile-flags:--cfg my_feature -#![feature(extern_crate_item_prelude)] #![no_std] #[cfg(my_feature)] diff --git a/src/test/ui/imports/extern-prelude-extern-crate-pass.rs b/src/test/ui/imports/extern-prelude-extern-crate-pass.rs index 8c147dfd04a..bb4cf6ca99c 100644 --- a/src/test/ui/imports/extern-prelude-extern-crate-pass.rs +++ b/src/test/ui/imports/extern-prelude-extern-crate-pass.rs @@ -1,8 +1,6 @@ // compile-pass // aux-build:two_macros.rs -#![feature(extern_crate_item_prelude)] - extern crate two_macros; mod m { diff --git a/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs b/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs index 732f1c4de2f..6ff3ab73639 100644 --- a/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs +++ b/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs @@ -1,7 +1,5 @@ // aux-build:two_macros.rs -#![feature(extern_crate_item_prelude)] - macro_rules! define_vec { () => { extern crate std as Vec; @@ -16,4 +14,13 @@ mod m { } } +macro_rules! define_other_core { + () => { + extern crate std as core; + //~^ ERROR macro-expanded `extern crate` items cannot shadow names passed with `--extern` + } +} + +define_other_core!(); + fn main() {} diff --git a/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr b/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr index 218dfb796f7..795e1761ccd 100644 --- a/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr +++ b/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr @@ -1,12 +1,21 @@ +error: macro-expanded `extern crate` items cannot shadow names passed with `--extern` + --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:19:9 + | +LL | extern crate std as core; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | define_other_core!(); + | --------------------- in this macro invocation + error[E0659]: `Vec` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) - --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:15:9 + --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:13:9 | LL | Vec::panic!(); //~ ERROR `Vec` is ambiguous | ^^^ ambiguous name | = note: `Vec` could refer to a struct from prelude note: `Vec` could also refer to the extern crate imported here - --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:7:9 + --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:5:9 | LL | extern crate std as Vec; | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -14,6 +23,6 @@ LL | extern crate std as Vec; LL | define_vec!(); | -------------- in this macro invocation -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0659`. diff --git a/src/test/ui/imports/extern-prelude-extern-crate-shadowing.rs b/src/test/ui/imports/extern-prelude-extern-crate-shadowing.rs new file mode 100644 index 00000000000..c5adeaf17fa --- /dev/null +++ b/src/test/ui/imports/extern-prelude-extern-crate-shadowing.rs @@ -0,0 +1,12 @@ +// compile-pass +// aux-build:two_macros.rs + +extern crate two_macros as core; + +mod m { + fn check() { + core::m!(); // OK + } +} + +fn main() {} diff --git a/src/test/ui/imports/issue-55811.rs b/src/test/ui/imports/issue-55811.rs new file mode 100644 index 00000000000..95316777fab --- /dev/null +++ b/src/test/ui/imports/issue-55811.rs @@ -0,0 +1,6 @@ +// compile-pass +// aux-build:issue-55811.rs + +extern crate issue_55811; + +fn main() {} diff --git a/src/test/ui/imports/issue-56125.rs b/src/test/ui/imports/issue-56125.rs new file mode 100644 index 00000000000..4baeb8a34dd --- /dev/null +++ b/src/test/ui/imports/issue-56125.rs @@ -0,0 +1,12 @@ +// edition:2018 +// compile-flags:--extern issue_56125 +// aux-build:issue-56125.rs + +use issue_56125::last_segment::*; +//~^ ERROR `issue_56125` is ambiguous +//~| ERROR unresolved import `issue_56125::last_segment` +use issue_56125::non_last_segment::non_last_segment::*; +//~^ ERROR `issue_56125` is ambiguous +//~| ERROR failed to resolve: could not find `non_last_segment` in `issue_56125` + +fn main() {} diff --git a/src/test/ui/imports/issue-56125.stderr b/src/test/ui/imports/issue-56125.stderr new file mode 100644 index 00000000000..096d5be97f0 --- /dev/null +++ b/src/test/ui/imports/issue-56125.stderr @@ -0,0 +1,46 @@ +error[E0433]: failed to resolve: could not find `non_last_segment` in `issue_56125` + --> $DIR/issue-56125.rs:8:18 + | +LL | use issue_56125::non_last_segment::non_last_segment::*; + | ^^^^^^^^^^^^^^^^ could not find `non_last_segment` in `issue_56125` + +error[E0432]: unresolved import `issue_56125::last_segment` + --> $DIR/issue-56125.rs:5:18 + | +LL | use issue_56125::last_segment::*; + | ^^^^^^^^^^^^ could not find `last_segment` in `issue_56125` + +error[E0659]: `issue_56125` is ambiguous (name vs any other name during import resolution) + --> $DIR/issue-56125.rs:5:5 + | +LL | use issue_56125::last_segment::*; + | ^^^^^^^^^^^ ambiguous name + | + = note: `issue_56125` could refer to an extern crate passed with `--extern` + = help: use `::issue_56125` to refer to this extern crate unambiguously +note: `issue_56125` could also refer to the module imported here + --> $DIR/issue-56125.rs:5:5 + | +LL | use issue_56125::last_segment::*; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: use `self::issue_56125` to refer to this module unambiguously + +error[E0659]: `issue_56125` is ambiguous (name vs any other name during import resolution) + --> $DIR/issue-56125.rs:8:5 + | +LL | use issue_56125::non_last_segment::non_last_segment::*; + | ^^^^^^^^^^^ ambiguous name + | + = note: `issue_56125` could refer to an extern crate passed with `--extern` + = help: use `::issue_56125` to refer to this extern crate unambiguously +note: `issue_56125` could also refer to the module imported here + --> $DIR/issue-56125.rs:5:5 + | +LL | use issue_56125::last_segment::*; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: use `self::issue_56125` to refer to this module unambiguously + +error: aborting due to 4 previous errors + +Some errors occurred: E0432, E0433, E0659. +For more information about an error, try `rustc --explain E0432`. diff --git a/src/test/ui/invalid-self-argument/bare-fn-start.rs b/src/test/ui/invalid-self-argument/bare-fn-start.rs new file mode 100644 index 00000000000..741ba5f41ce --- /dev/null +++ b/src/test/ui/invalid-self-argument/bare-fn-start.rs @@ -0,0 +1,5 @@ +fn a(&self) { } +//~^ ERROR unexpected `self` argument in function +//~| NOTE `self` is only valid as the first argument of an associated function + +fn main() { } diff --git a/src/test/ui/invalid-self-argument/bare-fn-start.stderr b/src/test/ui/invalid-self-argument/bare-fn-start.stderr new file mode 100644 index 00000000000..6a878b619d8 --- /dev/null +++ b/src/test/ui/invalid-self-argument/bare-fn-start.stderr @@ -0,0 +1,8 @@ +error: unexpected `self` argument in function + --> $DIR/bare-fn-start.rs:1:7 + | +LL | fn a(&self) { } + | ^^^^ `self` is only valid as the first argument of an associated function + +error: aborting due to previous error + diff --git a/src/test/ui/invalid-self-argument/bare-fn.rs b/src/test/ui/invalid-self-argument/bare-fn.rs new file mode 100644 index 00000000000..704fa996ca6 --- /dev/null +++ b/src/test/ui/invalid-self-argument/bare-fn.rs @@ -0,0 +1,5 @@ +fn b(foo: u32, &mut self) { } +//~^ ERROR unexpected `self` argument in function +//~| NOTE `self` is only valid as the first argument of an associated function + +fn main() { } diff --git a/src/test/ui/invalid-self-argument/bare-fn.stderr b/src/test/ui/invalid-self-argument/bare-fn.stderr new file mode 100644 index 00000000000..b13f746a4ec --- /dev/null +++ b/src/test/ui/invalid-self-argument/bare-fn.stderr @@ -0,0 +1,8 @@ +error: unexpected `self` argument in function + --> $DIR/bare-fn.rs:1:21 + | +LL | fn b(foo: u32, &mut self) { } + | ^^^^ `self` is only valid as the first argument of an associated function + +error: aborting due to previous error + diff --git a/src/test/ui/invalid-self-argument/trait-fn.rs b/src/test/ui/invalid-self-argument/trait-fn.rs new file mode 100644 index 00000000000..31e867bc764 --- /dev/null +++ b/src/test/ui/invalid-self-argument/trait-fn.rs @@ -0,0 +1,11 @@ +struct Foo {} + +impl Foo { + fn c(foo: u32, self) {} + //~^ ERROR unexpected `self` argument in function + //~| NOTE `self` is only valid as the first argument of an associated function + + fn good(&mut self, foo: u32) {} +} + +fn main() { } diff --git a/src/test/ui/invalid-self-argument/trait-fn.stderr b/src/test/ui/invalid-self-argument/trait-fn.stderr new file mode 100644 index 00000000000..b3c2cc5b5eb --- /dev/null +++ b/src/test/ui/invalid-self-argument/trait-fn.stderr @@ -0,0 +1,8 @@ +error: unexpected `self` argument in function + --> $DIR/trait-fn.rs:4:20 + | +LL | fn c(foo: u32, self) {} + | ^^^^ `self` is only valid as the first argument of an associated function + +error: aborting due to previous error + diff --git a/src/test/ui/issues/issue-19482.stderr b/src/test/ui/issues/issue-19482.stderr index 5e2d427ab72..d125438b851 100644 --- a/src/test/ui/issues/issue-19482.stderr +++ b/src/test/ui/issues/issue-19482.stderr @@ -1,8 +1,11 @@ error[E0191]: the value of the associated type `A` (from the trait `Foo`) must be specified --> $DIR/issue-19482.rs:20:12 | +LL | type A; + | ------- `A` defined here +... LL | fn bar(x: &Foo) {} - | ^^^ missing associated type `A` value + | ^^^ associated type `A` must be specified error: aborting due to previous error diff --git a/src/test/ui/issues/issue-21950.stderr b/src/test/ui/issues/issue-21950.stderr index a2f74a29aab..33c89dd4994 100644 --- a/src/test/ui/issues/issue-21950.stderr +++ b/src/test/ui/issues/issue-21950.stderr @@ -10,7 +10,7 @@ error[E0191]: the value of the associated type `Output` (from the trait `std::op --> $DIR/issue-21950.rs:17:14 | LL | &Add; - | ^^^ missing associated type `Output` value + | ^^^ associated type `Output` must be specified error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-22434.stderr b/src/test/ui/issues/issue-22434.stderr index 914da801ad4..3ba77346a1f 100644 --- a/src/test/ui/issues/issue-22434.stderr +++ b/src/test/ui/issues/issue-22434.stderr @@ -1,8 +1,11 @@ error[E0191]: the value of the associated type `A` (from the trait `Foo`) must be specified --> $DIR/issue-22434.rs:15:19 | +LL | type A; + | ------- `A` defined here +... LL | type I<'a> = &'a (Foo + 'a); - | ^^^^^^^^ missing associated type `A` value + | ^^^^^^^^ associated type `A` must be specified error: aborting due to previous error diff --git a/src/test/ui/issues/issue-22560.stderr b/src/test/ui/issues/issue-22560.stderr index b5524036fae..715f84011f6 100644 --- a/src/test/ui/issues/issue-22560.stderr +++ b/src/test/ui/issues/issue-22560.stderr @@ -28,7 +28,7 @@ LL | type Test = Add + LL | | //~^ ERROR E0393 LL | | //~| ERROR E0191 LL | | Sub; - | |_______________^ missing associated type `Output` value + | |_______________^ associated type `Output` must be specified error: aborting due to 4 previous errors diff --git a/src/test/ui/issues/issue-23024.stderr b/src/test/ui/issues/issue-23024.stderr index 129d0945303..adee12a36d3 100644 --- a/src/test/ui/issues/issue-23024.stderr +++ b/src/test/ui/issues/issue-23024.stderr @@ -16,7 +16,7 @@ error[E0191]: the value of the associated type `Output` (from the trait `std::op --> $DIR/issue-23024.rs:19:35 | LL | println!("{:?}",(vfnfer[0] as Fn)(3)); - | ^^ missing associated type `Output` value + | ^^ associated type `Output` must be specified error: aborting due to 3 previous errors diff --git a/src/test/ui/issues/issue-28344.stderr b/src/test/ui/issues/issue-28344.stderr index 7ef2e906422..734c761d0b7 100644 --- a/src/test/ui/issues/issue-28344.stderr +++ b/src/test/ui/issues/issue-28344.stderr @@ -2,7 +2,7 @@ error[E0191]: the value of the associated type `Output` (from the trait `std::op --> $DIR/issue-28344.rs:14:17 | LL | let x: u8 = BitXor::bitor(0 as u8, 0 as u8); - | ^^^^^^^^^^^^^ missing associated type `Output` value + | ^^^^^^^^^^^^^ associated type `Output` must be specified error[E0599]: no function or associated item named `bitor` found for type `dyn std::ops::BitXor<_>` in the current scope --> $DIR/issue-28344.rs:14:17 @@ -16,7 +16,7 @@ error[E0191]: the value of the associated type `Output` (from the trait `std::op --> $DIR/issue-28344.rs:18:13 | LL | let g = BitXor::bitor; - | ^^^^^^^^^^^^^ missing associated type `Output` value + | ^^^^^^^^^^^^^ associated type `Output` must be specified error[E0599]: no function or associated item named `bitor` found for type `dyn std::ops::BitXor<_>` in the current scope --> $DIR/issue-28344.rs:18:13 diff --git a/src/test/ui/issues/issue-56128.rs b/src/test/ui/issues/issue-56128.rs new file mode 100644 index 00000000000..3a3eccdc33c --- /dev/null +++ b/src/test/ui/issues/issue-56128.rs @@ -0,0 +1,15 @@ +// Regression test for #56128. When this `pub(super) use...` gets +// exploded in the HIR, we were not handling ids correctly. +// +// compile-pass + +mod bar { + pub(super) use self::baz::{x, y}; + + mod baz { + pub fn x() { } + pub fn y() { } + } +} + +fn main() { } diff --git a/src/test/ui/lint/must_use-trait.rs b/src/test/ui/lint/must_use-trait.rs new file mode 100644 index 00000000000..23df4fa6132 --- /dev/null +++ b/src/test/ui/lint/must_use-trait.rs @@ -0,0 +1,22 @@ +#![deny(unused_must_use)] + +#[must_use] +trait Critical {} + +trait NotSoCritical {} + +trait DecidedlyUnimportant {} + +struct Anon; + +impl Critical for Anon {} +impl NotSoCritical for Anon {} +impl DecidedlyUnimportant for Anon {} + +fn get_critical() -> impl NotSoCritical + Critical + DecidedlyUnimportant { + Anon {} +} + +fn main() { + get_critical(); //~ ERROR unused implementer of `Critical` that must be used +} diff --git a/src/test/ui/lint/must_use-trait.stderr b/src/test/ui/lint/must_use-trait.stderr new file mode 100644 index 00000000000..94f5f4f40d2 --- /dev/null +++ b/src/test/ui/lint/must_use-trait.stderr @@ -0,0 +1,14 @@ +error: unused implementer of `Critical` that must be used + --> $DIR/must_use-trait.rs:21:5 + | +LL | get_critical(); //~ ERROR unused implementer of `Critical` that must be used + | ^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/must_use-trait.rs:1:9 + | +LL | #![deny(unused_must_use)] + | ^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/mismatched_types/closure-arg-count.rs b/src/test/ui/mismatched_types/closure-arg-count.rs index 9eb11148a8b..2dcc7a25c84 100644 --- a/src/test/ui/mismatched_types/closure-arg-count.rs +++ b/src/test/ui/mismatched_types/closure-arg-count.rs @@ -22,6 +22,8 @@ fn main() { //~^ ERROR closure is expected to take f(|| panic!()); //~^ ERROR closure is expected to take + f( move || panic!()); + //~^ ERROR closure is expected to take let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x| i); //~^ ERROR closure is expected to take diff --git a/src/test/ui/mismatched_types/closure-arg-count.stderr b/src/test/ui/mismatched_types/closure-arg-count.stderr index 057cf6efa1d..eeadf07262c 100644 --- a/src/test/ui/mismatched_types/closure-arg-count.stderr +++ b/src/test/ui/mismatched_types/closure-arg-count.stderr @@ -60,8 +60,26 @@ help: consider changing the closure to take and ignore the expected argument LL | f(|_| panic!()); | ^^^ +error[E0593]: closure is expected to take 1 argument, but it takes 0 arguments + --> $DIR/closure-arg-count.rs:25:5 + | +LL | f( move || panic!()); + | ^ ---------- takes 0 arguments + | | + | expected closure that takes 1 argument + | +note: required by `f` + --> $DIR/closure-arg-count.rs:13:1 + | +LL | fn f>(_: F) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ +help: consider changing the closure to take and ignore the expected argument + | +LL | f( move |_| panic!()); + | ^^^ + error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments - --> $DIR/closure-arg-count.rs:26:53 + --> $DIR/closure-arg-count.rs:28:53 | LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x| i); | ^^^ ------ takes 2 distinct arguments @@ -73,7 +91,7 @@ LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(|(i, x)| i); | ^^^^^^^^ error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments - --> $DIR/closure-arg-count.rs:28:53 + --> $DIR/closure-arg-count.rs:30:53 | LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i: usize, x| i); | ^^^ ------------- takes 2 distinct arguments @@ -85,7 +103,7 @@ LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(|(i, x)| i); | ^^^^^^^^ error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 3 distinct arguments - --> $DIR/closure-arg-count.rs:30:53 + --> $DIR/closure-arg-count.rs:32:53 | LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x, y| i); | ^^^ --------- takes 3 distinct arguments @@ -93,7 +111,7 @@ LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x, y| i); | expected closure that takes a single 2-tuple as argument error[E0593]: function is expected to take a single 2-tuple as argument, but it takes 0 arguments - --> $DIR/closure-arg-count.rs:32:53 + --> $DIR/closure-arg-count.rs:34:53 | LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(foo); | ^^^ expected function that takes a single 2-tuple as argument @@ -102,7 +120,7 @@ LL | fn foo() {} | -------- takes 0 arguments error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 3 distinct arguments - --> $DIR/closure-arg-count.rs:35:53 + --> $DIR/closure-arg-count.rs:37:53 | LL | let bar = |i, x, y| i; | --------- takes 3 distinct arguments @@ -110,7 +128,7 @@ LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(bar); | ^^^ expected closure that takes a single 2-tuple as argument error[E0593]: function is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments - --> $DIR/closure-arg-count.rs:37:53 + --> $DIR/closure-arg-count.rs:39:53 | LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(qux); | ^^^ expected function that takes a single 2-tuple as argument @@ -119,13 +137,13 @@ LL | fn qux(x: usize, y: usize) {} | -------------------------- takes 2 distinct arguments error[E0593]: function is expected to take 1 argument, but it takes 2 arguments - --> $DIR/closure-arg-count.rs:40:41 + --> $DIR/closure-arg-count.rs:42:41 | LL | let _it = vec![1, 2, 3].into_iter().map(usize::checked_add); | ^^^ expected function that takes 1 argument error[E0593]: function is expected to take 0 arguments, but it takes 1 argument - --> $DIR/closure-arg-count.rs:43:5 + --> $DIR/closure-arg-count.rs:45:5 | LL | call(Foo); | ^^^^ expected function that takes 0 arguments @@ -134,11 +152,11 @@ LL | struct Foo(u8); | --------------- takes 1 argument | note: required by `call` - --> $DIR/closure-arg-count.rs:50:1 + --> $DIR/closure-arg-count.rs:52:1 | LL | fn call(_: F) where F: FnOnce() -> R {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 13 previous errors +error: aborting due to 14 previous errors For more information about this error, try `rustc --explain E0593`. diff --git a/src/test/ui/panic-runtime/bad-panic-flag1.rs b/src/test/ui/panic-runtime/bad-panic-flag1.rs index f067b6b8349..4e553c4df2f 100644 --- a/src/test/ui/panic-runtime/bad-panic-flag1.rs +++ b/src/test/ui/panic-runtime/bad-panic-flag1.rs @@ -9,6 +9,6 @@ // except according to those terms. // compile-flags:-C panic=foo -// error-pattern:either `panic` or `abort` was expected +// error-pattern:either `unwind` or `abort` was expected fn main() {} diff --git a/src/test/ui/panic-runtime/bad-panic-flag1.stderr b/src/test/ui/panic-runtime/bad-panic-flag1.stderr index 3a65419c98f..013373c6f93 100644 --- a/src/test/ui/panic-runtime/bad-panic-flag1.stderr +++ b/src/test/ui/panic-runtime/bad-panic-flag1.stderr @@ -1,2 +1,2 @@ -error: incorrect value `foo` for codegen option `panic` - either `panic` or `abort` was expected +error: incorrect value `foo` for codegen option `panic` - either `unwind` or `abort` was expected diff --git a/src/test/ui/panic-runtime/bad-panic-flag2.rs b/src/test/ui/panic-runtime/bad-panic-flag2.rs index 0ecf65f080f..f560e7f4eb2 100644 --- a/src/test/ui/panic-runtime/bad-panic-flag2.rs +++ b/src/test/ui/panic-runtime/bad-panic-flag2.rs @@ -9,6 +9,6 @@ // except according to those terms. // compile-flags:-C panic -// error-pattern:requires either `panic` or `abort` +// error-pattern:requires either `unwind` or `abort` fn main() {} diff --git a/src/test/ui/panic-runtime/bad-panic-flag2.stderr b/src/test/ui/panic-runtime/bad-panic-flag2.stderr index 8d919e55c90..6ab94ea704d 100644 --- a/src/test/ui/panic-runtime/bad-panic-flag2.stderr +++ b/src/test/ui/panic-runtime/bad-panic-flag2.stderr @@ -1,2 +1,2 @@ -error: codegen option `panic` requires either `panic` or `abort` (C panic=) +error: codegen option `panic` requires either `unwind` or `abort` (C panic=) diff --git a/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.rs b/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.rs new file mode 100644 index 00000000000..58e7718ba5b --- /dev/null +++ b/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.rs @@ -0,0 +1,8 @@ +pub trait T { + type A; + type B; + type C; +} + pub struct Foo { i: Box> } + + fn main() {} diff --git a/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr b/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr new file mode 100644 index 00000000000..b62b5d3b04c --- /dev/null +++ b/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr @@ -0,0 +1,31 @@ +error[E0107]: wrong number of type arguments: expected 2, found 4 + --> $DIR/use-type-argument-instead-of-assoc-type.rs:6:42 + | +LL | pub struct Foo { i: Box> } + | ^^^^^ ^^^^^ unexpected type argument + | | + | unexpected type argument + +error[E0191]: the value of the associated types `A` (from the trait `T`), `C` (from the trait `T`) must be specified + --> $DIR/use-type-argument-instead-of-assoc-type.rs:6:26 + | +LL | type A; + | ------- `A` defined here +LL | type B; +LL | type C; + | ------- `C` defined here +LL | } +LL | pub struct Foo { i: Box> } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | associated type `A` must be specified + | associated type `C` must be specified +help: if you meant to specify the associated types, write + | +LL | pub struct Foo { i: Box> } + | ^^^^^^^^^ ^^^^^^^^^ + +error: aborting due to 2 previous errors + +Some errors occurred: E0107, E0191. +For more information about an error, try `rustc --explain E0107`. diff --git a/src/test/ui/traits/trait-alias-object.stderr b/src/test/ui/traits/trait-alias-object.stderr index 6b7b322a53d..fdb9427cba7 100644 --- a/src/test/ui/traits/trait-alias-object.stderr +++ b/src/test/ui/traits/trait-alias-object.stderr @@ -10,7 +10,7 @@ error[E0191]: the value of the associated type `Item` (from the trait `std::iter --> $DIR/trait-alias-object.rs:18:13 | LL | let _: &dyn IteratorAlias = &vec![123].into_iter(); - | ^^^^^^^^^^^^^^^^^ missing associated type `Item` value + | ^^^^^^^^^^^^^^^^^ associated type `Item` must be specified error: aborting due to 2 previous errors diff --git a/src/tools/clippy b/src/tools/clippy index f5d868c9edf..754b4c07233 160000 --- a/src/tools/clippy +++ b/src/tools/clippy @@ -1 +1 @@ -Subproject commit f5d868c9edfc6c2a9310d564a2f738bec67dfd6b +Subproject commit 754b4c07233ee18820265bd18467aa82263f9a3a diff --git a/src/tools/rls b/src/tools/rls index 1c755efed6e..daa138ce7f2 160000 --- a/src/tools/rls +++ b/src/tools/rls @@ -1 +1 @@ -Subproject commit 1c755efed6ee265c762f4d3fec73de8a989637a5 +Subproject commit daa138ce7f222559e9a339600b44a715101a3f4d diff --git a/src/tools/rustfmt b/src/tools/rustfmt index 750b2526138..1cc61cfc2b2 160000 --- a/src/tools/rustfmt +++ b/src/tools/rustfmt @@ -1 +1 @@ -Subproject commit 750b25261380b776de2518fd6863fe63f98d2722 +Subproject commit 1cc61cfc2b29ae3f29a924b4c8feb1bcb09aa5fc diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 2dfb9fc68ac..a40ae8894d5 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Check license of third-party deps by inspecting src/vendor +//! Check license of third-party deps by inspecting vendor use std::collections::{BTreeSet, HashSet, HashMap}; use std::fs::File; @@ -203,7 +203,7 @@ impl<'a> From> for Crate<'a> { /// Specifically, this checks that the license is correct. pub fn check(path: &Path, bad: &mut bool) { // Check licences - let path = path.join("vendor"); + let path = path.join("../vendor"); assert!(path.exists(), "vendor directory missing"); let mut saw_dir = false; for dir in t!(path.read_dir()) { @@ -215,7 +215,7 @@ pub fn check(path: &Path, bad: &mut bool) { dir.path() .to_str() .unwrap() - .contains(&format!("src/vendor/{}", exception)) + .contains(&format!("vendor/{}", exception)) }); if is_exception { continue; @@ -304,7 +304,7 @@ fn get_deps(path: &Path, cargo: &Path) -> Resolve { .arg("--format-version") .arg("1") .arg("--manifest-path") - .arg(path.join("Cargo.toml")) + .arg(path.join("../Cargo.toml")) .output() .expect("Unable to run `cargo metadata`") .stdout; diff --git a/src/tools/tidy/src/extdeps.rs b/src/tools/tidy/src/extdeps.rs index 7f58b440a83..a78d2d4ee4e 100644 --- a/src/tools/tidy/src/extdeps.rs +++ b/src/tools/tidy/src/extdeps.rs @@ -21,8 +21,8 @@ const WHITELISTED_SOURCES: &[&str] = &[ /// check for external package sources pub fn check(path: &Path, bad: &mut bool) { - // Cargo.lock of rust: src/Cargo.lock - let path = path.join("Cargo.lock"); + // Cargo.lock of rust (tidy runs inside src/) + let path = path.join("../Cargo.lock"); // open and read the whole file let mut cargo_lock = String::new(); diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index e235de9c5e1..700103d35d8 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -64,7 +64,6 @@ fn filter_dirs(path: &Path) -> bool { "src/librustc_data_structures/owning_ref", "src/compiler-rt", "src/liblibc", - "src/vendor", "src/rt/hoedown", "src/tools/cargo", "src/tools/clang", @@ -78,6 +77,7 @@ fn filter_dirs(path: &Path) -> bool { "src/target", "src/stdsimd", "target", + "vendor", ]; skip.iter().any(|p| path.ends_with(p)) }