diff options
535 files changed, 11082 insertions, 5385 deletions
diff --git a/.gitmodules b/.gitmodules index 373ca90eca1..ffa7b321ba6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -48,3 +48,6 @@ [submodule "src/binaryen"] path = src/binaryen url = https://github.com/alexcrichton/binaryen.git +[submodule "src/doc/rust-by-example"] + path = src/doc/rust-by-example + url = https://github.com/rust-lang/rust-by-example diff --git a/.mailmap b/.mailmap index c2d3b28602b..9034aae1714 100644 --- a/.mailmap +++ b/.mailmap @@ -41,11 +41,12 @@ Boris Egorov <jightuse@gmail.com> <egorov@linux.com> Brandon Sanderson <singingboyo@gmail.com> Brandon Sanderson <singingboyo@hotmail.com> Brett Cannon <brett@python.org> Brett Cannon <brettcannon@users.noreply.github.com> Brian Anderson <banderson@mozilla.com> <andersrb@gmail.com> +Brian Anderson <banderson@mozilla.com> <banderson@mozilla.org> Brian Dawn <brian.t.dawn@gmail.com> Brian Leibig <brian@brianleibig.com> Brian Leibig <brian.leibig@gmail.com> Carl-Anton Ingmarsson <mail@carlanton.se> <ca.ingmarsson@gmail.com> -Carol (Nichols || Goulding) <carol.nichols@gmail.com> -Carol (Nichols || Goulding) <cnichols@thinkthroughmath.com> +Carol (Nichols || Goulding) <carol.nichols@gmail.com> <cnichols@thinkthroughmath.com> +Carol (Nichols || Goulding) <carol.nichols@gmail.com> Carol Nichols <carol.nichols@gmail.com> Carol Willing <carolcode@willingconsulting.com> Chris C Cerami <chrisccerami@users.noreply.github.com> Chris C Cerami <chrisccerami@gmail.com> Chris Pressey <cpressey@gmail.com> diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 54c507304f9..70376c120fc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -301,12 +301,12 @@ It's absolutely fine to have multiple build directories with different [pull-requests]: #pull-requests Pull requests are the primary mechanism we use to change Rust. GitHub itself -has some [great documentation][pull-requests] on using the Pull Request feature. +has some [great documentation][about-pull-requests] on using the Pull Request feature. We use the "fork and pull" model [described here][development-models], where contributors push changes to their personal fork and create pull requests to bring those changes into the source repository. -[pull-requests]: https://help.github.com/articles/about-pull-requests/ +[about-pull-requests]: https://help.github.com/articles/about-pull-requests/ [development-models]: https://help.github.com/articles/about-collaborative-development-models/ Please make pull requests against the `master` branch. diff --git a/RELEASES.md b/RELEASES.md index a4e6f22ba3d..45c389d72af 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -577,7 +577,7 @@ Compatibility Notes a warning. - [From the pound escape, lines consisting of multiple `#`s are now visible][41785] -- [It is an error to reexport private enum variants][42460]. This is +- [It is an error to re-export private enum variants][42460]. This is known to break a number of crates that depend on an older version of mustache. - [On Windows, if `VCINSTALLDIR` is set incorrectly, `rustc` will try @@ -2251,10 +2251,10 @@ Rustdoc ------- * [Fix empty implementation section on some module pages](https://github.com/rust-lang/rust/pull/34536) -* [Fix inlined renamed reexports in import lists](https://github.com/rust-lang/rust/pull/34479) +* [Fix inlined renamed re-exports in import lists](https://github.com/rust-lang/rust/pull/34479) * [Fix search result layout for enum variants and struct fields](https://github.com/rust-lang/rust/pull/34477) * [Fix issues with source links to external crates](https://github.com/rust-lang/rust/pull/34387) -* [Fix redirect pages for renamed reexports](https://github.com/rust-lang/rust/pull/34245) +* [Fix redirect pages for renamed re-exports](https://github.com/rust-lang/rust/pull/34245) Tooling ------- @@ -4988,7 +4988,7 @@ Version 0.10 (2014-04-03) * std: The `vec` module has been renamed to `slice`. * std: A new vector type, `Vec<T>`, has been added in preparation for DST. This will become the only growable vector in the future. - * std: `std::io` now has more public-reexports. Types such as `BufferedReader` + * std: `std::io` now has more public re-exports. Types such as `BufferedReader` are now found at `std::io::BufferedReader` instead of `std::io::buffered::BufferedReader`. * std: `print` and `println` are no longer in the prelude, the `print!` and @@ -5079,8 +5079,8 @@ Version 0.10 (2014-04-03) * render standalone markdown files. * the --test flag tests all code blocks by default. * exported macros are displayed. - * reexported types have their documentation inlined at the location of the - first reexport. + * re-exported types have their documentation inlined at the location of the + first re-export. * search works across crates that have been rendered to the same output directory. @@ -5467,7 +5467,7 @@ Version 0.7 (2013-07-03) incl. `any`, `all`. removed. * std: The `finalize` method of `Drop` renamed to `drop`. * std: The `drop` method now takes `&mut self` instead of `&self`. - * std: The prelude no longer reexports any modules, only types and traits. + * std: The prelude no longer re-exports any modules, only types and traits. * std: Prelude additions: `print`, `println`, `FromStr`, `ApproxEq`, `Equiv`, `Iterator`, `IteratorUtil`, many numeric traits, many tuple traits. * std: New numeric traits: `Fractional`, `Real`, `RealExt`, `Integer`, `Ratio`, diff --git a/src/Cargo.lock b/src/Cargo.lock index 8fbf3535264..6f919fd1acd 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -28,7 +28,7 @@ name = "alloc" version = "0.0.0" dependencies = [ "core 0.0.0", - "rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", "std_unicode 0.0.0", ] @@ -39,7 +39,7 @@ dependencies = [ "alloc 0.0.0", "alloc_system 0.0.0", "build_helper 0.1.0", - "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", "libc 0.0.0", ] @@ -70,27 +70,24 @@ version = "0.0.0" [[package]] name = "atty" -version = "0.2.3" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "backtrace" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -98,8 +95,8 @@ name = "backtrace-sys" version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -126,16 +123,16 @@ name = "bootstrap" version = "0.0.0" dependencies = [ "build_helper 0.1.0", - "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "filetime 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", + "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -152,8 +149,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "build-manifest" version = "0.1.0" dependencies = [ - "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -161,7 +158,7 @@ dependencies = [ name = "build_helper" version = "0.1.0" dependencies = [ - "filetime 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", + "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -171,51 +168,49 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cargo" -version = "0.25.0" +version = "0.26.0" dependencies = [ - "atty 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "cargotest 0.1.0", "core-foundation 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "crates-io 0.14.0", - "crossbeam 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crates-io 0.15.0", + "crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-hash 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "curl 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "docopt 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "curl 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "docopt 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "filetime 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", + "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "fs2 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "git2 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "git2 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", "git2-curl 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "hamcrest 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hex 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "home 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ignore 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ignore 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "jobserver 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", - "libgit2-sys 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "libgit2-sys 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "psapi-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "semver 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "shell-escape 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "tar 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -223,9 +218,9 @@ name = "cargo_metadata" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -235,23 +230,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cargotest" version = "0.1.0" dependencies = [ - "cargo 0.25.0", - "filetime 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", + "cargo 0.26.0", + "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "git2 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "git2 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", "hamcrest 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "tar 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -262,7 +257,7 @@ version = "0.1.0" [[package]] name = "cc" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -276,7 +271,7 @@ version = "2.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", - "atty 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -295,9 +290,9 @@ dependencies = [ "compiletest_rs 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "duct 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -314,10 +309,10 @@ dependencies = [ "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "pulldown-cmark 0.0.15 (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.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -328,7 +323,7 @@ name = "cmake" version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -353,14 +348,14 @@ name = "commoncrypto-sys" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "compiler_builtins" version = "0.0.0" dependencies = [ - "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -370,12 +365,12 @@ version = "0.0.0" dependencies = [ "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "filetime 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", + "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -386,9 +381,9 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "filetime 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", + "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", @@ -410,7 +405,7 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation-sys 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -418,29 +413,29 @@ name = "core-foundation-sys" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "crates-io" -version = "0.14.0" +version = "0.15.0" dependencies = [ - "curl 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "curl 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "crossbeam" -version = "0.2.10" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "crossbeam" -version = "0.3.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -481,38 +476,31 @@ dependencies = [ [[package]] name = "curl" -version = "0.4.8" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "curl-sys 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "curl-sys 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)", - "socket2 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)", + "schannel 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "socket2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "curl-sys" -version = "0.3.15" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "dbghelp-sys" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -551,13 +539,13 @@ dependencies = [ [[package]] name = "docopt" -version = "0.8.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -610,7 +598,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -618,7 +606,7 @@ name = "error-chain" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -626,7 +614,7 @@ name = "error-chain" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -641,7 +629,7 @@ name = "failure" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -661,12 +649,12 @@ version = "0.1.0" [[package]] name = "filetime" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -682,7 +670,7 @@ name = "flate2" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -710,26 +698,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "fs2" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "fuchsia-zircon" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "fuchsia-zircon-sys" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -753,14 +740,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "git2" -version = "0.6.10" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", - "libgit2-sys 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "libgit2-sys 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -769,8 +756,8 @@ name = "git2-curl" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "curl 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "git2 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "curl 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "git2 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -789,7 +776,7 @@ dependencies = [ "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -814,9 +801,9 @@ dependencies = [ "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "pest 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -825,6 +812,11 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] +name = "hex" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] name = "home" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -838,7 +830,7 @@ dependencies = [ [[package]] name = "html-diff" -version = "0.0.5" +version = "0.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "kuchiki 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -873,17 +865,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "ignore" -version = "0.2.2" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", "globset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -907,10 +900,11 @@ dependencies = [ "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "tar 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "xz2 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "xz2 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -931,8 +925,8 @@ name = "jobserver" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -947,9 +941,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -978,9 +972,9 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1009,21 +1003,21 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.35" +version = "0.2.36" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libgit2-sys" -version = "0.6.18" +version = "0.6.19" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "curl-sys 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "curl-sys 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "libssh2-sys 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1033,9 +1027,9 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1044,8 +1038,8 @@ name = "libz-sys" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1083,9 +1077,9 @@ name = "lzma-sys" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "filetime 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1125,10 +1119,10 @@ dependencies = [ "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "pulldown-cmark 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1138,15 +1132,7 @@ name = "memchr" version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "memchr" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1154,7 +1140,7 @@ name = "memchr" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1162,8 +1148,8 @@ name = "miniz-sys" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1185,7 +1171,7 @@ dependencies = [ "cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "compiletest_rs 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1199,7 +1185,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1216,7 +1202,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1240,7 +1226,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1288,10 +1274,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "num_cpus" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1307,8 +1293,8 @@ dependencies = [ "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1318,11 +1304,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "openssl-sys" -version = "0.9.23" +version = "0.9.24" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1378,8 +1364,8 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1417,7 +1403,7 @@ version = "0.7.21" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1456,20 +1442,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "profiler_builtins" version = "0.0.0" dependencies = [ - "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] [[package]] -name = "psapi-sys" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] name = "pulldown-cmark" version = "0.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1527,11 +1504,11 @@ dependencies = [ [[package]] name = "rand" -version = "0.3.19" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "fuchsia-zircon 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1550,14 +1527,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "redox_syscall" -version = "0.1.32" +version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1565,7 +1542,7 @@ name = "redox_termios" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1590,12 +1567,12 @@ dependencies = [ [[package]] name = "regex" -version = "0.2.3" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1607,7 +1584,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "regex-syntax" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1622,7 +1599,7 @@ version = "0.1.0" name = "rls" version = "0.124.0" dependencies = [ - "cargo 0.25.0", + "cargo 0.26.0", "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "json 0.11.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1637,10 +1614,10 @@ dependencies = [ "rls-rustc 0.1.1 (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.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rustfmt-nightly 0.3.4", - "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "rustfmt-nightly 0.3.6", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1664,8 +1641,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1679,8 +1656,8 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1705,7 +1682,7 @@ name = "rustc" version = "0.0.0" dependencies = [ "arena 0.0.0", - "backtrace 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1724,6 +1701,72 @@ dependencies = [ ] [[package]] +name = "rustc-ap-rustc_cratesio_shim" +version = "12.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rustc-ap-rustc_data_structures" +version = "12.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rustc-ap-rustc_errors" +version = "12.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rustc-ap-rustc_data_structures 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-syntax_pos 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rustc-ap-serialize" +version = "12.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rustc-ap-syntax" +version = "12.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_cratesio_shim 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_data_structures 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_errors 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-syntax_pos 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rustc-ap-syntax_pos" +version = "12.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rustc-ap-rustc_data_structures 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "rustc-demangle" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1775,7 +1818,7 @@ name = "rustc_back" version = "0.0.0" dependencies = [ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", "serialize 0.0.0", "syntax 0.0.0", ] @@ -1784,9 +1827,9 @@ dependencies = [ name = "rustc_binaryen" version = "0.0.0" dependencies = [ - "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1894,7 +1937,7 @@ version = "0.0.0" dependencies = [ "graphviz 0.0.0", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", "rustc_data_structures 0.0.0", "serialize 0.0.0", @@ -1919,7 +1962,7 @@ version = "0.0.0" dependencies = [ "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "build_helper 0.1.0", - "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_cratesio_shim 0.0.0", ] @@ -1967,7 +2010,6 @@ dependencies = [ "rustc_const_math 0.0.0", "rustc_data_structures 0.0.0", "rustc_errors 0.0.0", - "rustc_trans_utils 0.0.0", "serialize 0.0.0", "syntax 0.0.0", "syntax_pos 0.0.0", @@ -2055,11 +2097,11 @@ name = "rustc_trans" version = "0.0.0" dependencies = [ "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "jobserver 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", "rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_allocator 0.0.0", @@ -2090,6 +2132,8 @@ dependencies = [ "rustc 0.0.0", "rustc_back 0.0.0", "rustc_data_structures 0.0.0", + "rustc_incremental 0.0.0", + "rustc_mir 0.0.0", "syntax 0.0.0", "syntax_pos 0.0.0", ] @@ -2126,8 +2170,8 @@ name = "rustdoc" version = "0.0.0" dependencies = [ "build_helper 0.1.0", - "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "html-diff 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "html-diff 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "pulldown-cmark 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2141,7 +2185,7 @@ dependencies = [ [[package]] name = "rustfmt-nightly" -version = "0.3.4" +version = "0.3.6" dependencies = [ "cargo_metadata 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "derive-new 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2149,12 +2193,15 @@ dependencies = [ "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_errors 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-syntax 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2171,6 +2218,23 @@ dependencies = [ ] [[package]] +name = "same-file" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "schannel" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "scoped-tls" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2214,7 +2278,16 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2224,22 +2297,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.25" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_derive" -version = "1.0.25" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive_internals 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive_internals 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_derive_internals" -version = "0.18.1" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2251,18 +2324,18 @@ name = "serde_ignored" version = "0.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_json" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2275,7 +2348,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2301,14 +2374,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "socket2" -version = "0.2.4" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2330,7 +2401,7 @@ dependencies = [ "panic_abort 0.0.0", "panic_unwind 0.0.0", "profiler_builtins 0.0.0", - "rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_asan 0.0.0", "rustc_lsan 0.0.0", "rustc_msan 0.0.0", @@ -2355,7 +2426,7 @@ dependencies = [ "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", "precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2446,7 +2517,7 @@ name = "syntex_errors" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", "syntex_pos 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2468,7 +2539,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", "syntex_errors 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2482,9 +2553,9 @@ name = "tar" version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "filetime 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", "xattr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2493,7 +2564,7 @@ name = "tempdir" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2532,8 +2603,8 @@ name = "termion" version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2559,7 +2630,7 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2596,7 +2667,7 @@ name = "toml" version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2678,7 +2749,7 @@ name = "url_serde" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2735,16 +2806,43 @@ dependencies = [ ] [[package]] +name = "walkdir" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "winapi" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] +name = "winapi" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "winapi-build" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] name = "wincolor" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2771,12 +2869,12 @@ name = "xattr" version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "xz2" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lzma-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2793,8 +2891,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4" "checksum ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b3568b48b7cefa6b8ce125f9bb4989e52fbcc29ebea88df04cc7c5f12f70455" "checksum ar 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "35c7a5669cb64f085739387e1308b74e6d44022464b7f1b63bbd4ceb6379ec31" -"checksum atty 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "21e50800ec991574876040fff8ee46b136a53e985286fbe6a3bdfe6421b78860" -"checksum backtrace 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8709cc7ec06f6f0ae6c2c7e12f6ed41540781f72b488d83734978295ceae182e" +"checksum atty 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8352656fd42c30a0c3c89d26dea01e3b77c0ab2af18230835c15e2e13cd51859" +"checksum backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbbf59b1c43eefa8c3ede390fcc36820b4999f7914104015be25025e0d62af2" "checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661" "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" @@ -2803,7 +2901,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23" "checksum cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "be1057b8462184f634c3a208ee35b0f935cfd94b694b26deadccd98732088d7b" "checksum cargo_metadata 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "20d6fb2b5574726329c85cdba0df0347fddfec3cf9c8b588f9931708280f5643" -"checksum cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a9b13a57efd6b30ecd6598ebdb302cca617930b5470647570468a65d12ef9719" +"checksum cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "deaf9ec656256bb25b404c51ef50097207b9cbb29c933d31f92cae5a8a0ffee0" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" "checksum clap 2.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "110d43e343eb29f4f51c1db31beb879d546db27998577e5715270a54bcf41d3f" "checksum cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "56d741ea7a69e577f6d06b36b7dff4738f680593dc27a701ffa8506b73ce28bb" @@ -2813,18 +2911,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum compiletest_rs 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "562bafeec9aef1e3e08f1c5b0c542220bb80ff2894e5373a1f9d17c346412c66" "checksum core-foundation 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8047f547cd6856d45b1cdd75ef8d2f21f3d0e4bf1dab0a0041b0ae9a5dda9c0e" "checksum core-foundation-sys 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "152195421a2e6497a8179195672e9d4ee8e45ed8c465b626f1606d27a08ebcd5" -"checksum crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0c5ea215664ca264da8a9d9c3be80d2eaf30923c259d03e870388eb927508f97" -"checksum crossbeam 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8837ab96533202c5b610ed44bc7f4183e7957c1c8f56e8cc78bb098593c8ba0a" +"checksum crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "bd66663db5a988098a89599d4857919b3acf7f61402e61365acfd3919857b9be" +"checksum crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19" "checksum crypto-hash 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34903878eec1694faf53cae8473a088df333181de421d4d3d48061d6559fe602" "checksum cssparser 0.13.7 (registry+https://github.com/rust-lang/crates.io-index)" = "ef6124306e5ebc5ab11891d063aeafdd0cdc308079b708c8b566125f3680292b" "checksum cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "079adec4af52bb5275eadd004292028c79eb3c5f5b4ee8086a36d4197032f6df" -"checksum curl 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7034c534a1d7d22f7971d6088aa9d281d219ef724026c3428092500f41ae9c2c" -"checksum curl-sys 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "4bee31aa3a079d5f3ff9579ea4dcfb1b1a17a40886f5f467436d383e78134b55" -"checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" +"checksum curl 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b70fd6394677d3c0e239ff4be6f2b3176e171ffd1c23ffdc541e78dea2b8bb5e" +"checksum curl-sys 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f46e49c7125131f5afaded06944d6888b55cbdf8eba05dae73c954019b907961" "checksum debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9a032eac705ca39214d169f83e3d3da290af06d8d1d344d1baad2fd002dca4b3" "checksum derive-new 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "415f627ab054041c3eb748c2e1da0ef751989f5f0c386b63a098e545854a98ba" "checksum diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3c2b69f912779fbb121ceb775d74d51e915af17aaebc38d28a592843a2dd0a3a" -"checksum docopt 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3b5b93718f8b3e5544fcc914c43de828ca6c6ace23e0332c6080a2977b49787a" +"checksum docopt 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d8acd393692c503b168471874953a2531df0e9ab77d0b6bbc582395743300a4a" "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" "checksum duct 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e45aa15fe0a8a8f511e6d834626afd55e49b62e5c8802e18328a87e8a8f6065c" "checksum either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "740178ddf48b1a9e878e6d6509a1442a2d42fd2928aae8e7a6f8a36fb01981b3" @@ -2836,30 +2933,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum error-chain 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6930e04918388a9a2e41d518c25cf679ccafe26733fb4127dbf21993f2575d46" "checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82" "checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b" -"checksum filetime 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "aa75ec8f7927063335a9583e7fa87b0110bb888cf766dc01b54c0ff70d760c8e" +"checksum filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "714653f3e34871534de23771ac7b26e999651a0a228f47beb324dfdf1dd4b10f" "checksum flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9fac2277e84e5e858483756647a9d0aa8d9a2b7cba517fd84325a0aaa69a0909" "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" "checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" -"checksum fs2 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ab76cfd2aaa59b7bf6688ad9ba15bbae64bff97f04ea02144cfd3443e5c2866" -"checksum fuchsia-zircon 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bd510087c325af53ba24f3be8f1c081b0982319adcb8b03cad764512923ccc19" -"checksum fuchsia-zircon-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "08b3a6f13ad6b96572b53ce7af74543132f1a7055ccceb6d073dd36c54481859" +"checksum fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" +"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum futf 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "51f93f3de6ba1794dcd5810b3546d004600a59a98266487c8407bc4b24e398f3" "checksum futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "118b49cac82e04121117cbd3121ede3147e885627d82c4546b87c702debb90c1" "checksum getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "65922871abd2f101a2eb0eaebadc66668e54a87ad9c3dd82520b5f86ede5eff9" -"checksum git2 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "40a111aecd59985496012976beca164b4f6c930d507a099831e06b07f19d54f1" +"checksum git2 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "ee5b4bb7cd2a44e6e5ee3a26ba6a9ca10d4ce2771cdc3839bbc54b47b7d1be84" "checksum git2-curl 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "68676bc784bf0bef83278898929bf64a251e87c0340723d0b93fa096c9c5bf8e" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" "checksum globset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "464627f948c3190ae3d04b1bc6d7dca2f785bda0ac01278e6db129ad383dbeb6" "checksum hamcrest 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bf088f042a467089e9baa4972f57f9247e42a0cc549ba264c7a04fbb8ecb89d4" "checksum handlebars 0.29.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fb04af2006ea09d985fef82b81e0eb25337e51b691c76403332378a53d521edc" "checksum hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d6a22814455d41612f41161581c2883c0c6a1c41852729b17d5ed88f01e153aa" +"checksum hex 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "459d3cf58137bb02ad4adeef5036377ff59f066dbb82517b7192e3a5462a2abc" "checksum home 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9f25ae61099d8f3fee8b483df0bd4ecccf4b2731897aad40d50eca1b641fe6db" -"checksum html-diff 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "9778743e3b3c3679f471f0ed1833c690f19f4a0919e33b281f12ef5f77ad64c6" +"checksum html-diff 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ee4cfdf62a484a3ac0d9b80f562d37f99366db08a63621b917ea3056565345f7" "checksum html5ever 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5bfb46978eb757a603b7dfe2dafb1c62cb4dee3428d8ac1de734d83d6b022d06" "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" "checksum if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "61bb90bdd39e3af69b0172dfc6130f6cd6332bf040fbb9bdd4401d37adbd48b8" -"checksum ignore 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b3fcaf2365eb14b28ec7603c98c06cc531f19de9eb283d89a3dff8417c8c99f5" +"checksum ignore 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bb2f0238094bd1b41800fb6eb9b16fdd5e9832ed6053ed91409f0cd5bf28dcfd" "checksum itertools 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d3f2be4da1690a039e9ae5fd575f706a63ad5a2120f161b1d653c9da3930dd21" "checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c" "checksum jobserver 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "565f6106bd87b394398f813bea4e5ecad6d6b0f6aa077592d088f882a506481d" @@ -2871,8 +2969,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" "checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" "checksum lazycell 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3b585b7a6811fb03aa10e74b278a0f00f8dd9b45dc681f148bb29fa5cb61859b" -"checksum libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)" = "96264e9b293e95d25bfcbbf8a88ffd1aedc85b754eba8b7d78012f638ba220eb" -"checksum libgit2-sys 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)" = "82fc20bd8beefe7c9f98aae2d3cff78e57f544cdd83d58fe181ec37a5fbe0c77" +"checksum libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "1e5d97d6708edaa407429faa671b942dc0f2727222fb6b6539bf1db936e4b121" +"checksum libgit2-sys 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "6eeae66e7b1c995de45cb4e65c5ab438a96a7b4077e448645d4048dc753ad357" "checksum libssh2-sys 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0db4ec23611747ef772db1c4d650f8bd762f07b461727ec998f953c614024b75" "checksum libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "87f737ad6cc6fd6eefe3d9dc5412f1573865bded441300904d2f42269e140f16" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" @@ -2884,7 +2982,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" "checksum mdbook 0.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "8a1ac668292d1e5c7b1c6fd64f70d3a85105b8069a89558a0d67bdb2ff298ca1" "checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20" -"checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a" "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" "checksum miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "609ce024854aeb19a0ef7567d348aaa5a746b32fb72e336df7fcc16869d7e2b4" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" @@ -2898,11 +2995,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "7485fcc84f85b4ecd0ea527b14189281cf27d60e583ae65ebc9c088b13dffe01" "checksum num-rational 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "0c7cb72a95250d8a370105c828f388932373e0e94414919891a0f945222310fe" "checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070" -"checksum num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "514f0d73e64be53ff320680ca671b64fe3fb91da01e1ae2ddc99eb51d453b20d" +"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" "checksum open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c281318d992e4432cfa799969467003d05921582a7489a8325e37f8a450d5113" "checksum openssl 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)" = "169a4b9160baf9b9b1ab975418c673686638995ba921683a7f1e01470dcb8854" "checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" -"checksum openssl-sys 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)" = "2200ffec628e3f14c39fc0131a301db214f1a7d584e36507ee8700b0c7fb7a46" +"checksum openssl-sys 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)" = "14ba54ac7d5a4eabd1d5f2c1fdeb7e7c14debfa669d94b983d01b465e767ba9e" "checksum os_pipe 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "998bfbb3042e715190fe2a41abfa047d7e8cb81374d2977d7f100eacd8619cb1" "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" "checksum parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3e7f7c9857874e54afeb950eebeae662b1e51a2493666d2ea4c0a5d91dcf0412" @@ -2916,7 +3013,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903" "checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" "checksum procedural-masquerade 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "dc1bcafee1590f81acb329ae45ec627b318123f085153913620316ae9a144b2a" -"checksum psapi-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f71c7e142c25f297077a8ebc21f10847096b5d21ad7619d7bf0c1fcecb40bb0" "checksum pulldown-cmark 0.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "378e941dbd392c101f2cb88097fa4d7167bc421d4b88de3ff7dbee503bc3233b" "checksum pulldown-cmark 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a656fdb8b6848f896df5e478a0eb9083681663e37dcb77dd16981ff65329fe8b" "checksum quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eda5fe9b71976e62bc81b781206aaa076401769b2143379d3eb2118388babac4" @@ -2924,41 +3020,50 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum racer 2.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "034f1c4528581c40a60e96875467c03315868084e08ff4ceb46a00f7be3b16b4" "checksum radix_trie 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "211c49b6a9995cac0fd1dd9ca60b42cf3a51e151a12eb954b3a9e75513426ee8" -"checksum rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "9e7944d95d25ace8f377da3ac7068ce517e4c646754c43a1b1849177bbf72e59" +"checksum rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)" = "512870020642bb8c221bf68baa1b2573da814f6ccfe5c9699b1c303047abe9b1" "checksum rayon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed02d09394c94ffbdfdc755ad62a132e94c3224a8354e78a1200ced34df12edf" "checksum rayon-core 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e64b609139d83da75902f88fd6c01820046840a18471e4dfcd5ac7c0f46bea53" -"checksum redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ab105df655884ede59d45b7070c8a65002d921461ee813a024558ca16030eea0" +"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" "checksum regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f" -"checksum regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ac6ab4e9218ade5b423358bbd2567d1617418403c7a512603630181813316322" +"checksum regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "744554e01ccbd98fff8c457c3b092cd67af62a555a43bfe97ae8a0451f7799fa" "checksum regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957" -"checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db" +"checksum regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8e931c58b93d86f080c734bfd2bce7dd0079ae2331235818133c8be7f422e20e" "checksum rls-analysis 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "38841e3c5271715a574ac220d9b408b59ed9e2626909c3bc54b5853b4eaadb7b" "checksum rls-data 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8024f1feaca72d0aa4ae1e2a8d454a31b9a33ed02f8d0e9c8559bf53c267ec3c" "checksum rls-rustc 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b21ea952e9bf1569929abf1bb920262cde04b7b1b26d8e0260286302807299d2" "checksum rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d7c7046dc6a92f2ae02ed302746db4382e75131b9ce20ce967259f6b5867a6a" "checksum rls-vfs 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ffd34691a510938bb67fe0444fb363103c73ffb31c121d1e16bc92d8945ea8ff" +"checksum rustc-ap-rustc_cratesio_shim 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f1a51c10af5abd5d698b7e3487e869e6d15f6feb04cbedb5c792e2824f9d845e" +"checksum rustc-ap-rustc_data_structures 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1aa227490501072780d57f74b1164d361833ff8e172f817da0da2cdf2e4280cc" +"checksum rustc-ap-rustc_errors 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "21ff6c6e13ac4fc04b7d4d398828b024c4b6577045cb3175b33d35fea35ff6d0" +"checksum rustc-ap-serialize 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6b4e7f51e298675c2bf830f7265621a8936fb09e63b825b58144cbaac969e604" +"checksum rustc-ap-syntax 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8bf5639869ba2f7fa581939cd217cb71a85506b82ad0ea520614fb0dceb2386c" +"checksum rustc-ap-syntax_pos 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1c020cdb7379e1c733ae0a311ae47c748337ba584d2dd7b7f53baaae78de6f8b" "checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7" +"checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637" +"checksum schannel 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "acece75e0f987c48863a6c792ec8b7d6c4177d4a027f8ccc72f849794f437016" "checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d" "checksum scopeguard 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "59a076157c1e2dc561d8de585151ee6965d910dd4dcb5dabb7ae3e83981a6c57" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum selectors 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e3c89b1c6a3c029c82263f7dd2d44d0005ee7374eb09e254ab59dede4353a8c0" "checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537" "checksum semver 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bee2bc909ab2d8d60dab26e8cad85b25d795b14603a0dcb627b78b9d30b6454b" +"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "386122ba68c214599c44587e0c0b411e8d90894503a95425b4f9508e4317901f" -"checksum serde_derive 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "ec0bfa6c5784e7d110514448da0e1dbad41ea5514c3e68be755b23858b83a399" -"checksum serde_derive_internals 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)" = "730fe9f29fe8db69a601837f416e46cba07792031ed6b27557a43e49d62d89ae" +"checksum serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "db99f3919e20faa51bb2996057f5031d8685019b5a06139b1ce761da671b8526" +"checksum serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "f4ba7591cfe93755e89eeecdbcc668885624829b020050e6aec99c2a03bd3fd0" +"checksum serde_derive_internals 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6e03f1c9530c3fb0a0a5c9b826bdd9246a5921ae995d75f512ac917fc4dd55b5" "checksum serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "190e9765dcedb56be63b6e0993a006c7e3b071a016a304736e4a315dc01fb142" -"checksum serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7cf5b0b5b4bd22eeecb7e01ac2e1225c7ef5e4272b79ee28a8392a8c8489c839" +"checksum serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c9db7266c7d63a4c4b7fe8719656ccdd51acf1bed6124b174f933b009fb10bcb" "checksum shared_child 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "099b38928dbe4a0a01fcd8c233183072f14a7d126a34bed05880869be66e14cc" "checksum shell-escape 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "dd5cc96481d54583947bfe88bf30c23d53f883c6cd0145368b69989d97b84ef8" "checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537" "checksum smallvec 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4f8266519bc1d17d0b5b16f6c21295625d562841c708f6376f49028a43e9c11e" "checksum smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44db0ecb22921ef790d17ae13a3f6d15784183ff5f2a01aa32098c7498d2b4b9" -"checksum socket2 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "36b4896961171cd3317c7e9603d88f379f8c6e45342212235d356496680c68fd" +"checksum socket2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cf5d5aa364bf61a0d744a293da20381617b6445b89eb524800fab857c5aed2d8" "checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b" "checksum string_cache 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "413fc7852aeeb5472f1986ef755f561ddf0c789d3d796e65f0b6fe293ecd4ef8" "checksum string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "479cde50c3539481f33906a387f2bd17c8e87cb848c35b6021d41fb81ff9b4d7" @@ -3000,10 +3105,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bb08f9e670fab86099470b97cd2b252d6527f0b3cc1401acdb595ffc9dd288ff" +"checksum walkdir 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40b6d201f4f8998a837196b6de9c73e35af14c992cbb92c4ab641d2c2dce52de" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" +"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum wincolor 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a39ee4464208f6430992ff20154216ab2357772ac871d994c51628d60e58b8b0" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" "checksum xattr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "5f04de8a1346489a2f9e9bd8526b73d135ec554227b17568456e86aa35b6f3fc" -"checksum xz2 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e9510bdf100731599107c61f77daf46713a69a568f75458999c1f9dbf6ba25b0" +"checksum xz2 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "98df591c3504d014dd791d998123ed00a476c7e26dc6b2e873cb55c6ac9e59fa" "checksum yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e66366e18dc58b46801afbf2ca7661a9f59cc8c5962c29892b6039b4f86fa992" diff --git a/src/Cargo.toml b/src/Cargo.toml index 15594a54ef6..ad795b23cf2 100644 --- a/src/Cargo.toml +++ b/src/Cargo.toml @@ -55,8 +55,18 @@ debug-assertions = false debug = false debug-assertions = false +# We want the RLS to use the version of Cargo that we've got vendored in this +# repository to ensure that the same exact version of Cargo is used by both the +# RLS and the Cargo binary itself. The RLS depends on Cargo as a git repository +# 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" } [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 vesion). Unlike Cargo, however, the +# RLS depends on `rustfmt` from crates.io, so we put this in a `[patch]` section +# for crates.io rustfmt-nightly = { path = "tools/rustfmt" } diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 707aceebb1e..93c3694bc0c 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -351,11 +351,6 @@ class RustBuild(object): with open(self.rustc_stamp(), 'w') as rust_stamp: rust_stamp.write(self.date) - if "pc-windows-gnu" in self.build: - filename = "rust-mingw-{}-{}.tar.gz".format( - rustc_channel, self.build) - self._download_stage0_helper(filename, "rust-mingw") - if self.cargo().startswith(self.bin_root()) and \ (not os.path.exists(self.cargo()) or self.program_out_of_date(self.cargo_stamp())): diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index a660b5cf852..7655097681b 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -254,11 +254,13 @@ impl<'a> Builder<'a> { Kind::Test => describe!(check::Tidy, check::Bootstrap, check::DefaultCompiletest, check::HostCompiletest, check::Crate, check::CrateLibrustc, check::Rustdoc, check::Linkcheck, check::Cargotest, check::Cargo, check::Rls, check::Docs, - check::ErrorIndex, check::Distcheck, check::Rustfmt, check::Miri, check::Clippy), + check::ErrorIndex, check::Distcheck, check::Rustfmt, check::Miri, check::Clippy, + check::RustdocJS), + Kind::Bench => describe!(check::Crate, check::CrateLibrustc), Kind::Doc => describe!(doc::UnstableBook, doc::UnstableBookGen, doc::TheBook, doc::Standalone, doc::Std, doc::Test, doc::Rustc, doc::ErrorIndex, doc::Nomicon, - doc::Reference, doc::Rustdoc, doc::CargoBook), + doc::Reference, doc::Rustdoc, doc::RustByExample, doc::CargoBook), Kind::Dist => describe!(dist::Docs, dist::Mingw, dist::Rustc, dist::DebuggerScripts, dist::Std, dist::Analysis, dist::Src, dist::PlainSourceTarball, dist::Cargo, dist::Rls, dist::Rustfmt, dist::Extended, dist::HashSign, @@ -443,7 +445,8 @@ impl<'a> Builder<'a> { let out_dir = self.stage_out(compiler, mode); cargo.env("CARGO_TARGET_DIR", out_dir) .arg(cmd) - .arg("--target").arg(target); + .arg("--target") + .arg(target); // If we were invoked from `make` then that's already got a jobserver // set up for us so no need to tell Cargo about jobs all over again. @@ -620,6 +623,39 @@ impl<'a> Builder<'a> { // Set this for all builds to make sure doc builds also get it. cargo.env("CFG_RELEASE_CHANNEL", &self.build.config.channel); + // This one's a bit tricky. As of the time of this writing the compiler + // links to the `winapi` crate on crates.io. This crate provides raw + // bindings to Windows system functions, sort of like libc does for + // Unix. This crate also, however, provides "import libraries" for the + // MinGW targets. There's an import library per dll in the windows + // distribution which is what's linked to. These custom import libraries + // are used because the winapi crate can reference Windows functions not + // present in the MinGW import libraries. + // + // For example MinGW may ship libdbghelp.a, but it may not have + // references to all the functions in the dbghelp dll. Instead the + // custom import library for dbghelp in the winapi crates has all this + // information. + // + // Unfortunately for us though the import libraries are linked by + // default via `-ldylib=winapi_foo`. That is, they're linked with the + // `dylib` type with a `winapi_` prefix (so the winapi ones don't + // conflict with the system MinGW ones). This consequently means that + // the binaries we ship of things like rustc_trans (aka the rustc_trans + // DLL) when linked against *again*, for example with procedural macros + // or plugins, will trigger the propagation logic of `-ldylib`, passing + // `-lwinapi_foo` to the linker again. This isn't actually available in + // our distribution, however, so the link fails. + // + // To solve this problem we tell winapi to not use its bundled import + // libraries. This means that it will link to the system MinGW import + // libraries by default, and the `-ldylib=foo` directives will still get + // passed to the final linker, but they'll look like `-lfoo` which can + // be resolved because MinGW has the import library. The downside is we + // don't get newer functions from Windows, but we don't use any of them + // anyway. + cargo.env("WINAPI_NO_BUNDLED_LIBRARIES", "1"); + if self.is_very_verbose() { cargo.arg("-v"); } diff --git a/src/bootstrap/channel.rs b/src/bootstrap/channel.rs index 4e3f3a00b15..e412dd9e3e6 100644 --- a/src/bootstrap/channel.rs +++ b/src/bootstrap/channel.rs @@ -26,11 +26,6 @@ use config::Config; // The version number pub const CFG_RELEASE_NUM: &str = "1.25.0"; -// An optional number to put after the label, e.g. '.2' -> '-beta.2' -// Be sure to make this starts with a dot to conform to semver pre-release -// versions (section 9) -pub const CFG_PRERELEASE_VERSION: &str = ".1"; - pub struct GitInfo { inner: Option<Info>, } diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index ed110762cb3..1187376e177 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -424,6 +424,43 @@ fn path_for_cargo(builder: &Builder, compiler: Compiler) -> OsString { env::join_paths(iter::once(path).chain(env::split_paths(&old_path))).expect("") } +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RustdocJS { + pub host: Interned<String>, + pub target: Interned<String>, +} + +impl Step for RustdocJS { + type Output = (); + const DEFAULT: bool = true; + const ONLY_HOSTS: bool = true; + + fn should_run(run: ShouldRun) -> ShouldRun { + run.path("src/test/rustdoc-js") + } + + fn make_run(run: RunConfig) { + run.builder.ensure(RustdocJS { + host: run.host, + target: run.target, + }); + } + + fn run(self, builder: &Builder) { + if let Some(ref nodejs) = builder.config.nodejs { + let mut command = Command::new(nodejs); + command.args(&["src/tools/rustdoc-js/tester.js", &*self.host]); + builder.ensure(::doc::Std { + target: self.target, + stage: builder.top_stage, + }); + builder.run(&mut command); + } else { + println!("No nodejs found, skipping \"src/test/rustdoc-js\" tests"); + } + } +} + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct Tidy { host: Interned<String>, @@ -568,6 +605,11 @@ static HOST_COMPILETESTS: &[Test] = &[ mode: "compile-fail", suite: "compile-fail-fulldeps", }, + Test { + path: "src/test/incremental-fulldeps", + mode: "incremental", + suite: "incremental-fulldeps", + }, Test { path: "src/test/run-make", mode: "run-make", suite: "run-make" }, Test { path: "src/test/rustdoc", mode: "rustdoc", suite: "rustdoc" }, diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 3d2795f04e2..224b31ef268 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -224,6 +224,8 @@ fn make_win_dist( "libwinspool.a", "libws2_32.a", "libwsock32.a", + "libdbghelp.a", + "libmsimg32.a", ]; //Find mingw artifacts we want to bundle @@ -1650,7 +1652,6 @@ fn add_env(build: &Build, cmd: &mut Command, target: Interned<String>) { cmd.env("CFG_RELEASE_INFO", build.rust_version()) .env("CFG_RELEASE_NUM", channel::CFG_RELEASE_NUM) .env("CFG_RELEASE", build.rust_release()) - .env("CFG_PRERELEASE_VERSION", channel::CFG_PRERELEASE_VERSION) .env("CFG_VER_MAJOR", parts.next().unwrap()) .env("CFG_VER_MINOR", parts.next().unwrap()) .env("CFG_VER_PATCH", parts.next().unwrap()) diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 178d60dd7df..9bf762a3b4b 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -12,7 +12,7 @@ //! //! This module implements generation for all bits and pieces of documentation //! for the Rust project. This notably includes suites like the rust book, the -//! nomicon, standalone documentation, etc. +//! nomicon, rust by example, standalone documentation, etc. //! //! Everything here is basically just a shim around calling either `rustbook` or //! `rustdoc`. @@ -69,6 +69,7 @@ book!( Nomicon, "src/doc/nomicon", "nomicon"; Reference, "src/doc/reference", "reference"; Rustdoc, "src/doc/rustdoc", "rustdoc"; + RustByExample, "src/doc/rust-by-example", "rust-by-example"; ); #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] @@ -159,7 +160,7 @@ impl Step for CargoBook { let target = self.target; let name = self.name; - let src = build.src.join("src/tools/cargo/src/doc/book"); + let src = build.src.join("src/tools/cargo/src/doc"); let out = build.doc_out(target); t!(fs::create_dir_all(&out)); @@ -418,8 +419,8 @@ impl Step for Standalone { #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct Std { - stage: u32, - target: Interned<String>, + pub stage: u32, + pub target: Interned<String>, } impl Step for Std { diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 948bf29bbac..3738828a4ba 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -134,7 +134,7 @@ extern crate toml; #[cfg(unix)] extern crate libc; -use std::cell::RefCell; +use std::cell::{RefCell, Cell}; use std::collections::{HashSet, HashMap}; use std::env; use std::fs::{self, File}; @@ -250,6 +250,7 @@ pub struct Build { is_sudo: bool, ci_env: CiEnv, delayed_failures: RefCell<Vec<String>>, + prerelease_version: Cell<Option<u32>>, } #[derive(Debug)] @@ -335,6 +336,7 @@ impl Build { is_sudo, ci_env: CiEnv::current(), delayed_failures: RefCell::new(Vec::new()), + prerelease_version: Cell::new(None), } } @@ -774,12 +776,59 @@ impl Build { fn release(&self, num: &str) -> String { match &self.config.channel[..] { "stable" => num.to_string(), - "beta" => format!("{}-beta{}", num, channel::CFG_PRERELEASE_VERSION), + "beta" => format!("{}-beta.{}", num, self.beta_prerelease_version()), "nightly" => format!("{}-nightly", num), _ => format!("{}-dev", num), } } + fn beta_prerelease_version(&self) -> u32 { + if let Some(s) = self.prerelease_version.get() { + return s + } + + let beta = output( + Command::new("git") + .arg("ls-remote") + .arg("origin") + .arg("beta") + .current_dir(&self.src) + ); + let beta = beta.trim().split_whitespace().next().unwrap(); + let master = output( + Command::new("git") + .arg("ls-remote") + .arg("origin") + .arg("master") + .current_dir(&self.src) + ); + let master = master.trim().split_whitespace().next().unwrap(); + + // Figure out where the current beta branch started. + let base = output( + Command::new("git") + .arg("merge-base") + .arg(beta) + .arg(master) + .current_dir(&self.src), + ); + let base = base.trim(); + + // Next figure out how many merge commits happened since we branched off + // beta. That's our beta number! + let count = output( + Command::new("git") + .arg("rev-list") + .arg("--count") + .arg("--merges") + .arg(format!("{}...HEAD", base)) + .current_dir(&self.src), + ); + let n = count.trim().parse().unwrap(); + self.prerelease_version.set(Some(n)); + n + } + /// Returns the value of `release` above for Rust itself. fn rust_release(&self) -> String { self.release(channel::CFG_RELEASE_NUM) diff --git a/src/ci/docker/dist-various-2/Dockerfile b/src/ci/docker/dist-various-2/Dockerfile index c7885db559a..d8f09bf47a4 100644 --- a/src/ci/docker/dist-various-2/Dockerfile +++ b/src/ci/docker/dist-various-2/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:16.04 +FROM ubuntu:17.10 COPY scripts/cross-apt-packages.sh /scripts/ RUN sh /scripts/cross-apt-packages.sh @@ -21,9 +21,12 @@ RUN apt-key adv --batch --yes --keyserver keyserver.ubuntu.com --recv-keys 74DA7 RUN add-apt-repository -y 'deb http://apt.dilos.org/dilos dilos2-testing main' WORKDIR /tmp -COPY dist-various-2/shared.sh dist-various-2/build-fuchsia-toolchain.sh /tmp/ -COPY dist-various-2/build-solaris-toolchain.sh /tmp/ +COPY dist-various-2/shared.sh /tmp/ +COPY dist-various-2/build-cloudabi-toolchain.sh /tmp/ +RUN /tmp/build-cloudabi-toolchain.sh x86_64-unknown-cloudabi +COPY dist-various-2/build-fuchsia-toolchain.sh /tmp/ RUN /tmp/build-fuchsia-toolchain.sh +COPY dist-various-2/build-solaris-toolchain.sh /tmp/ RUN /tmp/build-solaris-toolchain.sh x86_64 amd64 solaris-i386 RUN /tmp/build-solaris-toolchain.sh sparcv9 sparcv9 solaris-sparc @@ -44,12 +47,20 @@ ENV \ CC_x86_64_sun_solaris=x86_64-sun-solaris2.10-gcc \ CXX_x86_64_sun_solaris=x86_64-sun-solaris2.10-g++ +# FIXME(EdSchouten): Remove this once cc ≥1.0.4 has been merged. It can +# automatically pick the right compiler path. +ENV \ + AR_x86_64_unknown_cloudabi=x86_64-unknown-cloudabi-ar \ + CC_x86_64_unknown_cloudabi=x86_64-unknown-cloudabi-clang \ + CXX_x86_64_unknown_cloudabi=x86_64-unknown-cloudabi-clang++ + ENV TARGETS=x86_64-unknown-fuchsia ENV TARGETS=$TARGETS,aarch64-unknown-fuchsia ENV TARGETS=$TARGETS,sparcv9-sun-solaris ENV TARGETS=$TARGETS,wasm32-unknown-unknown ENV TARGETS=$TARGETS,x86_64-sun-solaris ENV TARGETS=$TARGETS,x86_64-unknown-linux-gnux32 +ENV TARGETS=$TARGETS,x86_64-unknown-cloudabi ENV RUST_CONFIGURE_ARGS --target=$TARGETS --enable-extended ENV SCRIPT python2.7 ../x.py dist --target $TARGETS diff --git a/src/ci/docker/dist-various-2/build-cloudabi-toolchain.sh b/src/ci/docker/dist-various-2/build-cloudabi-toolchain.sh new file mode 100755 index 00000000000..d64da436639 --- /dev/null +++ b/src/ci/docker/dist-various-2/build-cloudabi-toolchain.sh @@ -0,0 +1,55 @@ +#!/bin/bash +# Copyright 2018 The Rust Project Developers. See the COPYRIGHT +# file at the top-level directory of this distribution and at +# http://rust-lang.org/COPYRIGHT. +# +# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +# option. This file may not be copied, modified, or distributed +# except according to those terms. + +set -eux + +# Install prerequisites. +apt-get update +apt-get install -y --no-install-recommends \ + apt-transport-https \ + ca-certificates \ + clang-5.0 \ + cmake \ + curl \ + file \ + g++ \ + gdb \ + git \ + lld-5.0 \ + make \ + python \ + sudo \ + xz-utils + +# Set up a Clang-based cross compiler toolchain. +# Based on the steps described at https://nuxi.nl/cloudabi/debian/ +target=$1 +for tool in ar nm objdump ranlib size; do + ln -s ../lib/llvm-5.0/bin/llvm-${tool} /usr/bin/${target}-${tool} +done +ln -s ../lib/llvm-5.0/bin/clang /usr/bin/${target}-cc +ln -s ../lib/llvm-5.0/bin/clang /usr/bin/${target}-c++ +ln -s ../lib/llvm-5.0/bin/lld /usr/bin/${target}-ld +ln -s ../../${target} /usr/lib/llvm-5.0/${target} + +# FIXME(EdSchouten): Remove this once cc ≥1.0.4 has been merged. It +# can make use of ${target}-cc and ${target}-c++, without incorrectly +# assuming it's MSVC. +ln -s ../lib/llvm-5.0/bin/clang /usr/bin/${target}-clang +ln -s ../lib/llvm-5.0/bin/clang /usr/bin/${target}-clang++ + +# Install the C++ runtime libraries from CloudABI Ports. +echo deb https://nuxi.nl/distfiles/cloudabi-ports/debian/ cloudabi cloudabi > \ + /etc/apt/sources.list.d/cloudabi.list +curl 'https://pgp.mit.edu/pks/lookup?op=get&search=0x0DA51B8531344B15' | \ + apt-key add - +apt-get update +apt-get install -y $(echo ${target} | sed -e s/_/-/g)-cxx-runtime diff --git a/src/ci/init_repo.sh b/src/ci/init_repo.sh index e073a3d99c1..14a1906ff42 100755 --- a/src/ci/init_repo.sh +++ b/src/ci/init_repo.sh @@ -36,6 +36,12 @@ fi rm -rf "$CACHE_DIR" mkdir "$CACHE_DIR" +# On the beta channel we'll be automatically calculating the prerelease version +# via the git history, so unshallow our shallow clone from CI. +if grep -q RUST_RELEASE_CHANNEL=beta src/ci/run.sh; then + git fetch origin --unshallow beta master +fi + travis_fold start update_cache travis_time_start diff --git a/src/doc/index.md b/src/doc/index.md index 3784cc3c4b4..3add2774105 100644 --- a/src/doc/index.md +++ b/src/doc/index.md @@ -28,6 +28,7 @@ Rust provides a number of book-length sets of documentation, collectively nicknamed 'The Rust Bookshelf.' * [The Rust Programming Language][book] teaches you how to program in Rust. +* [Rust By Example][rbe] teaches you how to program in Rust using editable examples. * [The Cargo Book][cargo-book] is a guide to Cargo, Rust's build tool and dependency manager. * [The Unstable Book][unstable-book] has documentation for unstable features. * [The Rustonomicon][nomicon] is your guidebook to the dark arts of unsafe Rust. @@ -51,6 +52,7 @@ before this policy was put into place. That work is being tracked [refchecklist]: https://github.com/rust-lang-nursery/reference/issues/9 [err]: error-index.html [book]: book/index.html +[rbe]: rust-by-example/index.html [nomicon]: nomicon/index.html [unstable-book]: unstable-book/index.html [rustdoc-book]: rustdoc/index.html diff --git a/src/doc/nomicon b/src/doc/nomicon -Subproject 2f7b05fd5939aa49d52c4ab309b9a47776ba7bd +Subproject fec3182d0b0a3cf8122e192b3270064a5b19be5 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example new file mode 160000 +Subproject 4ebb8169dfe569b3dcbeab560607800bb717978 diff --git a/src/doc/rustdoc/src/the-doc-attribute.md b/src/doc/rustdoc/src/the-doc-attribute.md index aadd72d1c90..296422744fa 100644 --- a/src/doc/rustdoc/src/the-doc-attribute.md +++ b/src/doc/rustdoc/src/the-doc-attribute.md @@ -1,7 +1,7 @@ # The `#[doc]` attribute The `#[doc]` attribute lets you control various aspects of how `rustdoc` does -its job. +its job. The most basic function of `#[doc]` is to handle the actual documentation text. That is, `///` is syntax sugar for `#[doc]`. This means that these two @@ -143,7 +143,7 @@ pub mod bar { } ``` -The documentation will generate a "Reexports" section, and say `pub use bar::Bar;`, where +The documentation will generate a "Re-exports" section, and say `pub use bar::Bar;`, where `Bar` is a link to its page. If we change the `use` line like this: @@ -184,7 +184,7 @@ mod bar { } ``` -Now we'll have a `Reexports` line, and `Bar` will not link to anywhere. +Now we'll have a `Re-exports` line, and `Bar` will not link to anywhere. ## `#[doc(hidden)]` diff --git a/src/doc/unstable-book/src/language-features/crate_in_paths.md b/src/doc/unstable-book/src/language-features/crate-in-paths.md index f1656993e87..f1656993e87 100644 --- a/src/doc/unstable-book/src/language-features/crate_in_paths.md +++ b/src/doc/unstable-book/src/language-features/crate-in-paths.md diff --git a/src/doc/unstable-book/src/language-features/extern_absolute_paths.md b/src/doc/unstable-book/src/language-features/extern-absolute-paths.md index f45c5053e8d..f45c5053e8d 100644 --- a/src/doc/unstable-book/src/language-features/extern_absolute_paths.md +++ b/src/doc/unstable-book/src/language-features/extern-absolute-paths.md diff --git a/src/doc/unstable-book/src/language-features/extern_in_paths.md b/src/doc/unstable-book/src/language-features/extern-in-paths.md index 3ae6cc29df0..3ae6cc29df0 100644 --- a/src/doc/unstable-book/src/language-features/extern_in_paths.md +++ b/src/doc/unstable-book/src/language-features/extern-in-paths.md diff --git a/src/doc/unstable-book/src/language-features/match_default_bindings.md b/src/doc/unstable-book/src/language-features/match-default-bindings.md index cc542931cbe..cc542931cbe 100644 --- a/src/doc/unstable-book/src/language-features/match_default_bindings.md +++ b/src/doc/unstable-book/src/language-features/match-default-bindings.md diff --git a/src/doc/unstable-book/src/language-features/repr-transparent.md b/src/doc/unstable-book/src/language-features/repr-transparent.md new file mode 100644 index 00000000000..62202dc96fd --- /dev/null +++ b/src/doc/unstable-book/src/language-features/repr-transparent.md @@ -0,0 +1,176 @@ +# `repr_transparent` + +The tracking issue for this feature is: [#43036] + +[#43036]: https://github.com/rust-lang/rust/issues/43036 + +------------------------ + +This feature enables the `repr(transparent)` attribute on structs, which enables +the use of newtypes without the usual ABI implications of wrapping the value in +a struct. + +## Background + +It's sometimes useful to add additional type safety by introducing *newtypes*. +For example, code that handles numeric quantities in different units such as +millimeters, centimeters, grams, kilograms, etc. may want to use the type system +to rule out mistakes such as adding millimeters to grams: + +```rust +use std::ops::Add; + +struct Millimeters(f64); +struct Grams(f64); + +impl Add<Millimeters> for Millimeters { + type Output = Millimeters; + + fn add(self, other: Millimeters) -> Millimeters { + Millimeters(self.0 + other.0) + } +} + +// Likewise: impl Add<Grams> for Grams {} +``` + +Other uses of newtypes include using `PhantomData` to add lifetimes to raw +pointers or to implement the "phantom types" pattern. See the [PhantomData] +documentation and [the Nomicon][nomicon-phantom] for more details. + +The added type safety is especially useful when interacting with C or other +languages. However, in those cases we need to ensure the newtypes we add do not +introduce incompatibilities with the C ABI. + +## Newtypes in FFI + +Luckily, `repr(C)` newtypes are laid out just like the type they wrap on all +platforms which Rust currently supports, and likely on many more. For example, +consider this C declaration: + +```C +struct Object { + double weight; //< in grams + double height; //< in millimeters + // ... +} + +void frobnicate(struct Object *); +``` + +While using this C code from Rust, we could add `repr(C)` to the `Grams` and +`Millimeters` newtypes introduced above and use them to add some type safety +while staying compatible with the memory layout of `Object`: + +```rust,no_run +#[repr(C)] +struct Grams(f64); + +#[repr(C)] +struct Millimeters(f64); + +#[repr(C)] +struct Object { + weight: Grams, + height: Millimeters, + // ... +} + +extern { + fn frobnicate(_: *mut Object); +} +``` + +This works even when adding some `PhantomData` fields, because they are +zero-sized and therefore don't have to affect the memory layout. + +However, there's more to the ABI than just memory layout: there's also the +question of how function call arguments and return values are passed. Many +common ABI treat a struct containing a single field differently from that field +itself, at least when the field is a scalar (e.g., integer or float or pointer). + +To continue the above example, suppose the C library also exposes a function +like this: + +```C +double calculate_weight(double height); +``` + +Using our newtypes on the Rust side like this will cause an ABI mismatch on many +platforms: + +```rust,ignore +extern { + fn calculate_weight(height: Millimeters) -> Grams; +} +``` + +For example, on x86_64 Linux, Rust will pass the argument in an integer +register, while the C function expects the argument to be in a floating-point +register. Likewise, the C function will return the result in a floating-point +register while Rust will expect it in an integer register. + +Note that this problem is not specific to floats: To give another example, +32-bit x86 linux will pass and return `struct Foo(i32);` on the stack while +`i32` is placed in registers. + +## Enter `repr(transparent)` + +So while `repr(C)` happens to do the right thing with respect to memory layout, +it's not quite the right tool for newtypes in FFI. Instead of declaring a C +struct, we need to communicate to the Rust compiler that our newtype is just for +type safety on the Rust side. This is what `repr(transparent)` does. + +The attribute can be applied to a newtype-like structs that contains a single +field. It indicates that the newtype should be represented exactly like that +field's type, i.e., the newtype should be ignored for ABI purpopses: not only is +it laid out the same in memory, it is also passed identically in function calls. + +In the above example, the ABI mismatches can be prevented by making the newtypes +`Grams` and `Millimeters` transparent like this: + +```rust +#![feature(repr_transparent)] + +#[repr(transparent)] +struct Grams(f64); + +#[repr(transparent)] +struct Millimeters(f64); +``` + +In addition to that single field, any number of zero-sized fields are permitted, +including but not limited to `PhantomData`: + +```rust +#![feature(repr_transparent)] + +use std::marker::PhantomData; + +struct Foo { /* ... */ } + +#[repr(transparent)] +struct FooPtrWithLifetime<'a>(*const Foo, PhantomData<&'a Foo>); + +#[repr(transparent)] +struct NumberWithUnit<T, U>(T, PhantomData<U>); + +struct CustomZst; + +#[repr(transparent)] +struct PtrWithCustomZst<'a> { + ptr: FooPtrWithLifetime<'a>, + some_marker: CustomZst, +} +``` + +Transparent structs can be nested: `PtrWithCustomZst` is also represented +exactly like `*const Foo`. + +Because `repr(transparent)` delegates all representation concerns to another +type, it is incompatible with all other `repr(..)` attributes. It also cannot be +applied to enums, unions, empty structs, structs whose fields are all +zero-sized, or structs with *multiple* non-zero-sized fields. + +[PhantomData]: https://doc.rust-lang.org/std/marker/struct.PhantomData.html +[nomicon-phantom]: https://doc.rust-lang.org/nomicon/phantom-data.html diff --git a/src/liballoc/allocator.rs b/src/liballoc/allocator.rs index c2a8f5f8ff9..55e8c0b430f 100644 --- a/src/liballoc/allocator.rs +++ b/src/liballoc/allocator.rs @@ -19,7 +19,7 @@ use core::cmp; use core::fmt; use core::mem; use core::usize; -use core::ptr::{self, Unique}; +use core::ptr::{self, NonNull}; /// Represents the combination of a starting address and /// a total capacity of the returned block. @@ -895,12 +895,12 @@ pub unsafe trait Alloc { /// Clients wishing to abort computation in response to an /// allocation error are encouraged to call the allocator's `oom` /// method, rather than directly invoking `panic!` or similar. - fn alloc_one<T>(&mut self) -> Result<Unique<T>, AllocErr> + fn alloc_one<T>(&mut self) -> Result<NonNull<T>, AllocErr> where Self: Sized { let k = Layout::new::<T>(); if k.size() > 0 { - unsafe { self.alloc(k).map(|p| Unique::new_unchecked(p as *mut T)) } + unsafe { self.alloc(k).map(|p| NonNull::new_unchecked(p as *mut T)) } } else { Err(AllocErr::invalid_input("zero-sized type invalid for alloc_one")) } @@ -923,7 +923,7 @@ pub unsafe trait Alloc { /// * `ptr` must denote a block of memory currently allocated via this allocator /// /// * the layout of `T` must *fit* that block of memory. - unsafe fn dealloc_one<T>(&mut self, ptr: Unique<T>) + unsafe fn dealloc_one<T>(&mut self, ptr: NonNull<T>) where Self: Sized { let raw_ptr = ptr.as_ptr() as *mut u8; @@ -963,7 +963,7 @@ pub unsafe trait Alloc { /// Clients wishing to abort computation in response to an /// allocation error are encouraged to call the allocator's `oom` /// method, rather than directly invoking `panic!` or similar. - fn alloc_array<T>(&mut self, n: usize) -> Result<Unique<T>, AllocErr> + fn alloc_array<T>(&mut self, n: usize) -> Result<NonNull<T>, AllocErr> where Self: Sized { match Layout::array::<T>(n) { @@ -971,7 +971,7 @@ pub unsafe trait Alloc { unsafe { self.alloc(layout.clone()) .map(|p| { - Unique::new_unchecked(p as *mut T) + NonNull::new_unchecked(p as *mut T) }) } } @@ -1012,15 +1012,15 @@ pub unsafe trait Alloc { /// reallocation error are encouraged to call the allocator's `oom` /// method, rather than directly invoking `panic!` or similar. unsafe fn realloc_array<T>(&mut self, - ptr: Unique<T>, + ptr: NonNull<T>, n_old: usize, - n_new: usize) -> Result<Unique<T>, AllocErr> + n_new: usize) -> Result<NonNull<T>, AllocErr> where Self: Sized { match (Layout::array::<T>(n_old), Layout::array::<T>(n_new), ptr.as_ptr()) { (Some(ref k_old), Some(ref k_new), ptr) if k_old.size() > 0 && k_new.size() > 0 => { self.realloc(ptr as *mut u8, k_old.clone(), k_new.clone()) - .map(|p|Unique::new_unchecked(p as *mut T)) + .map(|p| NonNull::new_unchecked(p as *mut T)) } _ => { Err(AllocErr::invalid_input("invalid layout for realloc_array")) @@ -1048,7 +1048,7 @@ pub unsafe trait Alloc { /// constraints. /// /// Always returns `Err` on arithmetic overflow. - unsafe fn dealloc_array<T>(&mut self, ptr: Unique<T>, n: usize) -> Result<(), AllocErr> + unsafe fn dealloc_array<T>(&mut self, ptr: NonNull<T>, n: usize) -> Result<(), AllocErr> where Self: Sized { let raw_ptr = ptr.as_ptr() as *mut u8; diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 185af8835d1..6a77bf64bae 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -25,7 +25,7 @@ use core::intrinsics::abort; use core::mem::{self, align_of_val, size_of_val, uninitialized}; use core::ops::Deref; use core::ops::CoerceUnsized; -use core::ptr::{self, Shared}; +use core::ptr::{self, NonNull}; use core::marker::{Unsize, PhantomData}; use core::hash::{Hash, Hasher}; use core::{isize, usize}; @@ -197,7 +197,7 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize; /// [rc_examples]: ../../std/rc/index.html#examples #[stable(feature = "rust1", since = "1.0.0")] pub struct Arc<T: ?Sized> { - ptr: Shared<ArcInner<T>>, + ptr: NonNull<ArcInner<T>>, phantom: PhantomData<T>, } @@ -234,7 +234,7 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Arc<U>> for Arc<T> {} /// [`None`]: ../../std/option/enum.Option.html#variant.None #[stable(feature = "arc_weak", since = "1.4.0")] pub struct Weak<T: ?Sized> { - ptr: Shared<ArcInner<T>>, + ptr: NonNull<ArcInner<T>>, } #[stable(feature = "arc_weak", since = "1.4.0")] @@ -286,7 +286,7 @@ impl<T> Arc<T> { weak: atomic::AtomicUsize::new(1), data, }; - Arc { ptr: Shared::from(Box::into_unique(x)), phantom: PhantomData } + Arc { ptr: Box::into_raw_non_null(x), phantom: PhantomData } } /// Returns the contained value, if the `Arc` has exactly one strong reference. @@ -397,7 +397,7 @@ impl<T: ?Sized> Arc<T> { let arc_ptr = set_data_ptr(fake_ptr, (ptr as *mut u8).offset(-offset)); Arc { - ptr: Shared::new_unchecked(arc_ptr), + ptr: NonNull::new_unchecked(arc_ptr), phantom: PhantomData, } } @@ -582,7 +582,7 @@ impl<T: ?Sized> Arc<T> { // Free the allocation without dropping its contents box_free(bptr); - Arc { ptr: Shared::new_unchecked(ptr), phantom: PhantomData } + Arc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData } } } } @@ -609,7 +609,7 @@ impl<T> Arc<[T]> { &mut (*ptr).data as *mut [T] as *mut T, v.len()); - Arc { ptr: Shared::new_unchecked(ptr), phantom: PhantomData } + Arc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData } } } @@ -669,7 +669,7 @@ impl<T: Clone> ArcFromSlice<T> for Arc<[T]> { // All clear. Forget the guard so it doesn't free the new ArcInner. mem::forget(guard); - Arc { ptr: Shared::new_unchecked(ptr), phantom: PhantomData } + Arc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData } } } } @@ -991,11 +991,11 @@ impl<T> Weak<T> { pub fn new() -> Weak<T> { unsafe { Weak { - ptr: Shared::from(Box::into_unique(box ArcInner { + ptr: Box::into_raw_non_null(box ArcInner { strong: atomic::AtomicUsize::new(0), weak: atomic::AtomicUsize::new(1), data: uninitialized(), - })), + }), } } } diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 6f125cdba81..bfe23ddeca3 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -68,7 +68,7 @@ use core::marker::{self, Unsize}; use core::mem; use core::ops::{CoerceUnsized, Deref, DerefMut, Generator, GeneratorState}; use core::ops::{BoxPlace, Boxed, InPlace, Place, Placer}; -use core::ptr::{self, Unique}; +use core::ptr::{self, NonNull, Unique}; use core::convert::From; use str::from_boxed_utf8_unchecked; @@ -269,38 +269,7 @@ impl<T: ?Sized> Box<T> { #[stable(feature = "box_raw", since = "1.4.0")] #[inline] pub unsafe fn from_raw(raw: *mut T) -> Self { - Box::from_unique(Unique::new_unchecked(raw)) - } - - /// Constructs a `Box` from a `Unique<T>` pointer. - /// - /// After calling this function, the memory is owned by a `Box` and `T` can - /// then be destroyed and released upon drop. - /// - /// # Safety - /// - /// A `Unique<T>` can be safely created via [`Unique::new`] and thus doesn't - /// necessarily own the data pointed to nor is the data guaranteed to live - /// as long as the pointer. - /// - /// [`Unique::new`]: ../../core/ptr/struct.Unique.html#method.new - /// - /// # Examples - /// - /// ``` - /// #![feature(unique)] - /// - /// fn main() { - /// let x = Box::new(5); - /// let ptr = Box::into_unique(x); - /// let x = unsafe { Box::from_unique(ptr) }; - /// } - /// ``` - #[unstable(feature = "unique", reason = "needs an RFC to flesh out design", - issue = "27730")] - #[inline] - pub unsafe fn from_unique(u: Unique<T>) -> Self { - Box(u) + Box(Unique::new_unchecked(raw)) } /// Consumes the `Box`, returning the wrapped raw pointer. @@ -326,40 +295,42 @@ impl<T: ?Sized> Box<T> { #[stable(feature = "box_raw", since = "1.4.0")] #[inline] pub fn into_raw(b: Box<T>) -> *mut T { - Box::into_unique(b).as_ptr() + Box::into_raw_non_null(b).as_ptr() } - /// Consumes the `Box`, returning the wrapped pointer as `Unique<T>`. + /// Consumes the `Box`, returning the wrapped pointer as `NonNull<T>`. /// /// After calling this function, the caller is responsible for the /// memory previously managed by the `Box`. In particular, the /// caller should properly destroy `T` and release the memory. The - /// proper way to do so is to either convert the `Unique<T>` pointer: - /// - /// - Into a `Box` with the [`Box::from_unique`] function. - /// - /// - Into a raw pointer and back into a `Box` with the [`Box::from_raw`] - /// function. + /// proper way to do so is to convert the `NonNull<T>` pointer + /// into a raw pointer and back into a `Box` with the [`Box::from_raw`] + /// function. /// /// Note: this is an associated function, which means that you have - /// to call it as `Box::into_unique(b)` instead of `b.into_unique()`. This + /// to call it as `Box::into_raw_non_null(b)` + /// instead of `b.into_raw_non_null()`. This /// is so that there is no conflict with a method on the inner type. /// - /// [`Box::from_unique`]: struct.Box.html#method.from_unique /// [`Box::from_raw`]: struct.Box.html#method.from_raw /// /// # Examples /// /// ``` - /// #![feature(unique)] + /// #![feature(box_into_raw_non_null)] /// /// fn main() { /// let x = Box::new(5); - /// let ptr = Box::into_unique(x); + /// let ptr = Box::into_raw_non_null(x); /// } /// ``` - #[unstable(feature = "unique", reason = "needs an RFC to flesh out design", - issue = "27730")] + #[unstable(feature = "box_into_raw_non_null", issue = "47336")] + #[inline] + pub fn into_raw_non_null(b: Box<T>) -> NonNull<T> { + Box::into_unique(b).into() + } + + #[unstable(feature = "ptr_internals", issue = "0", reason = "use into_raw_non_null instead")] #[inline] pub fn into_unique(b: Box<T>) -> Unique<T> { let unique = b.0; diff --git a/src/liballoc/btree/set.rs b/src/liballoc/btree/set.rs index e094070fc3d..327eaaf4651 100644 --- a/src/liballoc/btree/set.rs +++ b/src/liballoc/btree/set.rs @@ -658,26 +658,26 @@ impl<T: Ord> BTreeSet<T> { /// Basic usage: /// /// ``` - /// use std::collections::BTreeMap; + /// use std::collections::BTreeSet; /// - /// let mut a = BTreeMap::new(); - /// a.insert(1, "a"); - /// a.insert(2, "b"); - /// a.insert(3, "c"); - /// a.insert(17, "d"); - /// a.insert(41, "e"); + /// let mut a = BTreeSet::new(); + /// a.insert(1); + /// a.insert(2); + /// a.insert(3); + /// a.insert(17); + /// a.insert(41); /// /// let b = a.split_off(&3); /// /// assert_eq!(a.len(), 2); /// assert_eq!(b.len(), 3); /// - /// assert_eq!(a[&1], "a"); - /// assert_eq!(a[&2], "b"); + /// assert!(a.contains(&1)); + /// assert!(a.contains(&2)); /// - /// assert_eq!(b[&3], "c"); - /// assert_eq!(b[&17], "d"); - /// assert_eq!(b[&41], "e"); + /// assert!(b.contains(&3)); + /// assert!(b.contains(&17)); + /// assert!(b.contains(&41)); /// ``` #[stable(feature = "btree_split_off", since = "1.11.0")] pub fn split_off<Q: ?Sized + Ord>(&mut self, key: &Q) -> Self where T: Borrow<Q> { diff --git a/src/liballoc/heap.rs b/src/liballoc/heap.rs index b2bd9d7d8fa..37af9ea5295 100644 --- a/src/liballoc/heap.rs +++ b/src/liballoc/heap.rs @@ -232,7 +232,7 @@ unsafe impl Alloc for Heap { /// /// This preserves the non-null invariant for types like `Box<T>`. The address /// may overlap with non-zero-size memory allocations. -#[rustc_deprecated(since = "1.19", reason = "Use Unique/Shared::empty() instead")] +#[rustc_deprecated(since = "1.19", reason = "Use Unique/NonNull::empty() instead")] #[unstable(feature = "heap_api", issue = "27700")] pub const EMPTY: *mut () = 1 as *mut (); diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 3cc3ea46796..5139e54b560 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -15,7 +15,7 @@ //! //! This library, like libcore, is not intended for general usage, but rather as //! a building block of other libraries. The types and interfaces in this -//! library are reexported through the [standard library](../std/index.html), +//! library are re-exported through the [standard library](../std/index.html), //! and should not be used through this library. //! //! ## Boxed values @@ -52,7 +52,7 @@ //! ## Collections //! //! Implementations of the most common general purpose data structures are -//! defined in this library. They are reexported through the +//! defined in this library. They are re-exported through the //! [standard collections library](../std/collections/index.html). //! //! ## Heap interfaces @@ -84,6 +84,7 @@ #![cfg_attr(test, feature(rand, test))] #![feature(allow_internal_unstable)] #![feature(ascii_ctype)] +#![feature(box_into_raw_non_null)] #![feature(box_patterns)] #![feature(box_syntax)] #![feature(cfg_target_has_atomic)] @@ -109,8 +110,8 @@ #![feature(pattern)] #![feature(placement_in_syntax)] #![feature(placement_new_protocol)] +#![feature(ptr_internals)] #![feature(rustc_attrs)] -#![feature(shared)] #![feature(slice_get_slice)] #![feature(slice_patterns)] #![feature(slice_rsplit)] @@ -120,10 +121,10 @@ #![feature(trusted_len)] #![feature(unboxed_closures)] #![feature(unicode)] -#![feature(unique)] #![feature(unsize)] #![feature(allocator_internals)] #![feature(on_unimplemented)] +#![feature(exact_chunks)] #![cfg_attr(not(test), feature(fused, fn_traits, placement_new_protocol, swap_with_slice, i128))] #![cfg_attr(test, feature(test, box_heap))] diff --git a/src/liballoc/linked_list.rs b/src/liballoc/linked_list.rs index 3ac5a85d721..3cc810a055f 100644 --- a/src/liballoc/linked_list.rs +++ b/src/liballoc/linked_list.rs @@ -29,7 +29,7 @@ use core::iter::{FromIterator, FusedIterator}; use core::marker::PhantomData; use core::mem; use core::ops::{BoxPlace, InPlace, Place, Placer}; -use core::ptr::{self, Shared}; +use core::ptr::{self, NonNull}; use boxed::{Box, IntermediateBox}; use super::SpecExtend; @@ -44,15 +44,15 @@ use super::SpecExtend; /// more memory efficient and make better use of CPU cache. #[stable(feature = "rust1", since = "1.0.0")] pub struct LinkedList<T> { - head: Option<Shared<Node<T>>>, - tail: Option<Shared<Node<T>>>, + head: Option<NonNull<Node<T>>>, + tail: Option<NonNull<Node<T>>>, len: usize, marker: PhantomData<Box<Node<T>>>, } struct Node<T> { - next: Option<Shared<Node<T>>>, - prev: Option<Shared<Node<T>>>, + next: Option<NonNull<Node<T>>>, + prev: Option<NonNull<Node<T>>>, element: T, } @@ -65,8 +65,8 @@ struct Node<T> { /// [`LinkedList`]: struct.LinkedList.html #[stable(feature = "rust1", since = "1.0.0")] pub struct Iter<'a, T: 'a> { - head: Option<Shared<Node<T>>>, - tail: Option<Shared<Node<T>>>, + head: Option<NonNull<Node<T>>>, + tail: Option<NonNull<Node<T>>>, len: usize, marker: PhantomData<&'a Node<T>>, } @@ -98,8 +98,8 @@ impl<'a, T> Clone for Iter<'a, T> { #[stable(feature = "rust1", since = "1.0.0")] pub struct IterMut<'a, T: 'a> { list: &'a mut LinkedList<T>, - head: Option<Shared<Node<T>>>, - tail: Option<Shared<Node<T>>>, + head: Option<NonNull<Node<T>>>, + tail: Option<NonNull<Node<T>>>, len: usize, } @@ -157,7 +157,7 @@ impl<T> LinkedList<T> { unsafe { node.next = self.head; node.prev = None; - let node = Some(Shared::from(Box::into_unique(node))); + let node = Some(Box::into_raw_non_null(node)); match self.head { None => self.tail = node, @@ -192,7 +192,7 @@ impl<T> LinkedList<T> { unsafe { node.next = None; node.prev = self.tail; - let node = Some(Shared::from(Box::into_unique(node))); + let node = Some(Box::into_raw_non_null(node)); match self.tail { None => self.head = node, @@ -225,7 +225,7 @@ impl<T> LinkedList<T> { /// /// Warning: this will not check that the provided node belongs to the current list. #[inline] - unsafe fn unlink_node(&mut self, mut node: Shared<Node<T>>) { + unsafe fn unlink_node(&mut self, mut node: NonNull<Node<T>>) { let node = node.as_mut(); match node.prev { @@ -986,11 +986,11 @@ impl<'a, T> IterMut<'a, T> { Some(prev) => prev, }; - let node = Some(Shared::from(Box::into_unique(box Node { + let node = Some(Box::into_raw_non_null(box Node { next: Some(head), prev: Some(prev), element, - }))); + })); prev.as_mut().next = node; head.as_mut().prev = node; @@ -1038,7 +1038,7 @@ pub struct DrainFilter<'a, T: 'a, F: 'a> where F: FnMut(&mut T) -> bool, { list: &'a mut LinkedList<T>, - it: Option<Shared<Node<T>>>, + it: Option<NonNull<Node<T>>>, pred: F, idx: usize, old_len: usize, diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index dbf1fb1367d..621e1906961 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -322,7 +322,7 @@ impl<T, A: Alloc> RawVec<T, A> { // would cause overflow let new_cap = if elem_size > (!0) / 8 { 1 } else { 4 }; match self.a.alloc_array::<T>(new_cap) { - Ok(ptr) => (new_cap, ptr), + Ok(ptr) => (new_cap, ptr.into()), Err(e) => self.a.oom(e), } } diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 59079f9ba76..1fa5d34cb57 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -256,7 +256,7 @@ use core::marker::{Unsize, PhantomData}; use core::mem::{self, align_of_val, forget, size_of_val, uninitialized}; use core::ops::Deref; use core::ops::CoerceUnsized; -use core::ptr::{self, Shared}; +use core::ptr::{self, NonNull}; use core::convert::From; use heap::{Heap, Alloc, Layout, box_free}; @@ -282,7 +282,7 @@ struct RcBox<T: ?Sized> { /// [get_mut]: #method.get_mut #[stable(feature = "rust1", since = "1.0.0")] pub struct Rc<T: ?Sized> { - ptr: Shared<RcBox<T>>, + ptr: NonNull<RcBox<T>>, phantom: PhantomData<T>, } @@ -311,11 +311,11 @@ impl<T> Rc<T> { // pointers, which ensures that the weak destructor never frees // the allocation while the strong destructor is running, even // if the weak pointer is stored inside the strong one. - ptr: Shared::from(Box::into_unique(box RcBox { + ptr: Box::into_raw_non_null(box RcBox { strong: Cell::new(1), weak: Cell::new(1), value, - })), + }), phantom: PhantomData, } } @@ -428,7 +428,7 @@ impl<T: ?Sized> Rc<T> { let rc_ptr = set_data_ptr(fake_ptr, (ptr as *mut u8).offset(-offset)); Rc { - ptr: Shared::new_unchecked(rc_ptr), + ptr: NonNull::new_unchecked(rc_ptr), phantom: PhantomData, } } @@ -649,7 +649,7 @@ impl Rc<Any> { let raw: *const RcBox<Any> = self.ptr.as_ptr(); forget(self); Ok(Rc { - ptr: Shared::new_unchecked(raw as *const RcBox<T> as *mut _), + ptr: NonNull::new_unchecked(raw as *const RcBox<T> as *mut _), phantom: PhantomData, }) } @@ -695,7 +695,7 @@ impl<T: ?Sized> Rc<T> { // Free the allocation without dropping its contents box_free(bptr); - Rc { ptr: Shared::new_unchecked(ptr), phantom: PhantomData } + Rc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData } } } } @@ -722,7 +722,7 @@ impl<T> Rc<[T]> { &mut (*ptr).value as *mut [T] as *mut T, v.len()); - Rc { ptr: Shared::new_unchecked(ptr), phantom: PhantomData } + Rc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData } } } @@ -781,7 +781,7 @@ impl<T: Clone> RcFromSlice<T> for Rc<[T]> { // All clear. Forget the guard so it doesn't free the new RcBox. forget(guard); - Rc { ptr: Shared::new_unchecked(ptr), phantom: PhantomData } + Rc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData } } } } @@ -1160,7 +1160,7 @@ impl<T> From<Vec<T>> for Rc<[T]> { /// [`None`]: ../../std/option/enum.Option.html#variant.None #[stable(feature = "rc_weak", since = "1.4.0")] pub struct Weak<T: ?Sized> { - ptr: Shared<RcBox<T>>, + ptr: NonNull<RcBox<T>>, } #[stable(feature = "rc_weak", since = "1.4.0")] @@ -1190,11 +1190,11 @@ impl<T> Weak<T> { pub fn new() -> Weak<T> { unsafe { Weak { - ptr: Shared::from(Box::into_unique(box RcBox { + ptr: Box::into_raw_non_null(box RcBox { strong: Cell::new(0), weak: Cell::new(1), value: uninitialized(), - })), + }), } } } diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 2c7bdc427ea..028983de556 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -123,6 +123,8 @@ pub use core::slice::{from_raw_parts, from_raw_parts_mut}; pub use core::slice::{from_ref, from_ref_mut}; #[unstable(feature = "slice_get_slice", issue = "35729")] pub use core::slice::SliceIndex; +#[unstable(feature = "exact_chunks", issue = "47115")] +pub use core::slice::{ExactChunks, ExactChunksMut}; //////////////////////////////////////////////////////////////////////////////// // Basic slice extension methods @@ -611,6 +613,9 @@ impl<T> [T] { /// not divide the length of the slice, then the last chunk will /// not have length `chunk_size`. /// + /// See [`exact_chunks`] for a variant of this iterator that returns chunks + /// of always exactly `chunk_size` elements. + /// /// # Panics /// /// Panics if `chunk_size` is 0. @@ -625,17 +630,54 @@ impl<T> [T] { /// assert_eq!(iter.next().unwrap(), &['m']); /// assert!(iter.next().is_none()); /// ``` + /// + /// [`exact_chunks`]: #method.exact_chunks #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn chunks(&self, chunk_size: usize) -> Chunks<T> { core_slice::SliceExt::chunks(self, chunk_size) } + /// Returns an iterator over `chunk_size` elements of the slice at a + /// time. The chunks are slices and do not overlap. If `chunk_size` does + /// not divide the length of the slice, then the last up to `chunk_size-1` + /// elements will be omitted. + /// + /// Due to each chunk having exactly `chunk_size` elements, the compiler + /// can often optimize the resulting code better than in the case of + /// [`chunks`]. + /// + /// # Panics + /// + /// Panics if `chunk_size` is 0. + /// + /// # Examples + /// + /// ``` + /// #![feature(exact_chunks)] + /// + /// let slice = ['l', 'o', 'r', 'e', 'm']; + /// let mut iter = slice.exact_chunks(2); + /// assert_eq!(iter.next().unwrap(), &['l', 'o']); + /// assert_eq!(iter.next().unwrap(), &['r', 'e']); + /// assert!(iter.next().is_none()); + /// ``` + /// + /// [`chunks`]: #method.chunks + #[unstable(feature = "exact_chunks", issue = "47115")] + #[inline] + pub fn exact_chunks(&self, chunk_size: usize) -> ExactChunks<T> { + core_slice::SliceExt::exact_chunks(self, chunk_size) + } + /// Returns an iterator over `chunk_size` elements of the slice at a time. /// The chunks are mutable slices, and do not overlap. If `chunk_size` does /// not divide the length of the slice, then the last chunk will not /// have length `chunk_size`. /// + /// See [`exact_chunks_mut`] for a variant of this iterator that returns chunks + /// of always exactly `chunk_size` elements. + /// /// # Panics /// /// Panics if `chunk_size` is 0. @@ -654,12 +696,52 @@ impl<T> [T] { /// } /// assert_eq!(v, &[1, 1, 2, 2, 3]); /// ``` + /// + /// [`exact_chunks_mut`]: #method.exact_chunks_mut #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<T> { core_slice::SliceExt::chunks_mut(self, chunk_size) } + /// Returns an iterator over `chunk_size` elements of the slice at a time. + /// The chunks are mutable slices, and do not overlap. If `chunk_size` does + /// not divide the length of the slice, then the last up to `chunk_size-1` + /// elements will be omitted. + /// + /// + /// Due to each chunk having exactly `chunk_size` elements, the compiler + /// can often optimize the resulting code better than in the case of + /// [`chunks_mut`]. + /// + /// # Panics + /// + /// Panics if `chunk_size` is 0. + /// + /// # Examples + /// + /// ``` + /// #![feature(exact_chunks)] + /// + /// let v = &mut [0, 0, 0, 0, 0]; + /// let mut count = 1; + /// + /// for chunk in v.exact_chunks_mut(2) { + /// for elem in chunk.iter_mut() { + /// *elem += count; + /// } + /// count += 1; + /// } + /// assert_eq!(v, &[1, 1, 2, 2, 0]); + /// ``` + /// + /// [`chunks_mut`]: #method.chunks_mut + #[unstable(feature = "exact_chunks", issue = "47115")] + #[inline] + pub fn exact_chunks_mut(&mut self, chunk_size: usize) -> ExactChunksMut<T> { + core_slice::SliceExt::exact_chunks_mut(self, chunk_size) + } + /// Divides one slice into two at an index. /// /// The first will contain all indices from `[0, mid)` (excluding diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs index f1e95883b38..eee229bc6fd 100644 --- a/src/liballoc/tests/lib.rs +++ b/src/liballoc/tests/lib.rs @@ -30,6 +30,7 @@ #![feature(string_retain)] #![feature(unboxed_closures)] #![feature(unicode)] +#![feature(exact_chunks)] extern crate alloc_system; extern crate std_unicode; diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs index 49bdc9e1b90..1a9d26fd1a2 100644 --- a/src/liballoc/tests/slice.rs +++ b/src/liballoc/tests/slice.rs @@ -946,6 +946,30 @@ fn test_chunksator_0() { } #[test] +fn test_exact_chunksator() { + let v = &[1, 2, 3, 4, 5]; + + assert_eq!(v.exact_chunks(2).len(), 2); + + let chunks: &[&[_]] = &[&[1, 2], &[3, 4]]; + assert_eq!(v.exact_chunks(2).collect::<Vec<_>>(), chunks); + let chunks: &[&[_]] = &[&[1, 2, 3]]; + assert_eq!(v.exact_chunks(3).collect::<Vec<_>>(), chunks); + let chunks: &[&[_]] = &[]; + assert_eq!(v.exact_chunks(6).collect::<Vec<_>>(), chunks); + + let chunks: &[&[_]] = &[&[3, 4], &[1, 2]]; + assert_eq!(v.exact_chunks(2).rev().collect::<Vec<_>>(), chunks); +} + +#[test] +#[should_panic] +fn test_exact_chunksator_0() { + let v = &[1, 2, 3, 4]; + let _it = v.exact_chunks(0); +} + +#[test] fn test_reverse_part() { let mut values = [1, 2, 3, 4, 5]; values[1..4].reverse(); @@ -1159,7 +1183,7 @@ fn test_mut_chunks() { } } let result = [0, 0, 0, 1, 1, 1, 2]; - assert!(v == result); + assert_eq!(v, result); } #[test] @@ -1171,7 +1195,7 @@ fn test_mut_chunks_rev() { } } let result = [2, 2, 2, 1, 1, 1, 0]; - assert!(v == result); + assert_eq!(v, result); } #[test] @@ -1182,6 +1206,38 @@ fn test_mut_chunks_0() { } #[test] +fn test_mut_exact_chunks() { + let mut v = [0, 1, 2, 3, 4, 5, 6]; + assert_eq!(v.exact_chunks_mut(2).len(), 3); + for (i, chunk) in v.exact_chunks_mut(3).enumerate() { + for x in chunk { + *x = i as u8; + } + } + let result = [0, 0, 0, 1, 1, 1, 6]; + assert_eq!(v, result); +} + +#[test] +fn test_mut_exact_chunks_rev() { + let mut v = [0, 1, 2, 3, 4, 5, 6]; + for (i, chunk) in v.exact_chunks_mut(3).rev().enumerate() { + for x in chunk { + *x = i as u8; + } + } + let result = [1, 1, 1, 0, 0, 0, 6]; + assert_eq!(v, result); +} + +#[test] +#[should_panic] +fn test_mut_exact_chunks_0() { + let mut v = [1, 2, 3, 4]; + let _it = v.exact_chunks_mut(0); +} + +#[test] fn test_mut_last() { let mut x = [1, 2, 3, 4, 5]; let h = x.last_mut(); diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 301e44632b8..b14b9d74765 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -78,7 +78,7 @@ use core::num::Float; use core::ops::{InPlace, Index, IndexMut, Place, Placer}; use core::ops; use core::ptr; -use core::ptr::Shared; +use core::ptr::NonNull; use core::slice; use borrow::ToOwned; @@ -1124,7 +1124,7 @@ impl<T> Vec<T> { tail_start: end, tail_len: len - end, iter: range_slice.iter(), - vec: Shared::from(self), + vec: NonNull::from(self), } } } @@ -1745,7 +1745,7 @@ impl<T> IntoIterator for Vec<T> { let cap = self.buf.cap(); mem::forget(self); IntoIter { - buf: Shared::new_unchecked(begin), + buf: NonNull::new_unchecked(begin), phantom: PhantomData, cap, ptr: begin, @@ -2267,7 +2267,7 @@ impl<'a, T> FromIterator<T> for Cow<'a, [T]> where T: Clone { /// [`IntoIterator`]: ../../std/iter/trait.IntoIterator.html #[stable(feature = "rust1", since = "1.0.0")] pub struct IntoIter<T> { - buf: Shared<T>, + buf: NonNull<T>, phantom: PhantomData<T>, cap: usize, ptr: *const T, @@ -2442,7 +2442,7 @@ pub struct Drain<'a, T: 'a> { tail_len: usize, /// Current remaining range to remove iter: slice::Iter<'a, T>, - vec: Shared<Vec<T>>, + vec: NonNull<Vec<T>>, } #[stable(feature = "collection_debug", since = "1.17.0")] diff --git a/src/liballoc/vec_deque.rs b/src/liballoc/vec_deque.rs index f56aa23a4eb..9259138bab0 100644 --- a/src/liballoc/vec_deque.rs +++ b/src/liballoc/vec_deque.rs @@ -23,7 +23,7 @@ use core::iter::{repeat, FromIterator, FusedIterator}; use core::mem; use core::ops::{Index, IndexMut, Place, Placer, InPlace}; use core::ptr; -use core::ptr::Shared; +use core::ptr::NonNull; use core::slice; use core::hash::{Hash, Hasher}; @@ -895,7 +895,7 @@ impl<T> VecDeque<T> { self.head = drain_tail; Drain { - deque: Shared::from(&mut *self), + deque: NonNull::from(&mut *self), after_tail: drain_head, after_head: head, iter: Iter { @@ -906,7 +906,7 @@ impl<T> VecDeque<T> { } } - /// Clears the buffer, removing all values. + /// Clears the `VecDeque`, removing all values. /// /// # Examples /// @@ -1624,10 +1624,10 @@ impl<T> VecDeque<T> { return elem; } - /// Splits the collection into two at the given index. + /// Splits the `VecDeque` into two at the given index. /// - /// Returns a newly allocated `Self`. `self` contains elements `[0, at)`, - /// and the returned `Self` contains elements `[at, len)`. + /// Returns a newly allocated `VecDeque`. `self` contains elements `[0, at)`, + /// and the returned `VecDeque` contains elements `[at, len)`. /// /// Note that the capacity of `self` does not change. /// @@ -1635,7 +1635,7 @@ impl<T> VecDeque<T> { /// /// # Panics /// - /// Panics if `at > len` + /// Panics if `at > len`. /// /// # Examples /// @@ -1815,7 +1815,8 @@ impl<T> VecDeque<T> { impl<T: Clone> VecDeque<T> { /// Modifies the `VecDeque` in-place so that `len()` is equal to new_len, - /// either by removing excess elements or by appending clones of `value` to the back. + /// either by removing excess elements from the back or by appending clones of `value` + /// to the back. /// /// # Examples /// @@ -2154,7 +2155,7 @@ pub struct Drain<'a, T: 'a> { after_tail: usize, after_head: usize, iter: Iter<'a, T>, - deque: Shared<VecDeque<T>>, + deque: NonNull<VecDeque<T>>, } #[stable(feature = "collection_debug", since = "1.17.0")] @@ -2390,7 +2391,7 @@ impl<T> IntoIterator for VecDeque<T> { type Item = T; type IntoIter = IntoIter<T>; - /// Consumes the list into a front-to-back iterator yielding elements by + /// Consumes the `VecDeque` into a front-to-back iterator yielding elements by /// value. fn into_iter(self) -> IntoIter<T> { IntoIter { inner: self } @@ -2480,7 +2481,7 @@ impl<T> From<VecDeque<T>> for Vec<T> { if other.is_contiguous() { ptr::copy(buf.offset(tail as isize), buf, len); } else { - if (tail - head) >= cmp::min((cap - tail), head) { + if (tail - head) >= cmp::min(cap - tail, head) { // There is enough free space in the centre for the shortest block so we can // do this in at most three copy moves. if (cap - tail) > head { diff --git a/src/libcore/option.rs b/src/libcore/option.rs index d8f3ec38cf3..b8fe28d0f0d 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -407,9 +407,7 @@ impl<T> Option<T> { } /// Applies a function to the contained value (if any), - /// or returns a [`default`][] (if not). - /// - /// [`default`]: ../default/trait.Default.html#tymethod.default + /// or returns the provided default (if not). /// /// # Examples /// @@ -430,9 +428,7 @@ impl<T> Option<T> { } /// Applies a function to the contained value (if any), - /// or computes a [`default`][] (if not). - /// - /// [`default`]: ../default/trait.Default.html#tymethod.default + /// or computes a default (if not). /// /// # Examples /// @@ -850,7 +846,7 @@ impl<T: Default> Option<T> { /// Returns the contained value or a default /// /// Consumes the `self` argument then, if [`Some`], returns the contained - /// value, otherwise if [`None`], returns the default value for that + /// value, otherwise if [`None`], returns the [default value] for that /// type. /// /// # Examples @@ -872,6 +868,7 @@ impl<T: Default> Option<T> { /// /// [`Some`]: #variant.Some /// [`None`]: #variant.None + /// [default value]: ../default/trait.Default.html#tymethod.default /// [`parse`]: ../../std/primitive.str.html#method.parse /// [`FromStr`]: ../../std/str/trait.FromStr.html #[inline] @@ -884,6 +881,35 @@ impl<T: Default> Option<T> { } } +impl<T, E> Option<Result<T, E>> { + /// Transposes an `Option` of a `Result` into a `Result` of an `Option`. + /// + /// `None` will be mapped to `Ok(None)`. + /// `Some(Ok(_))` and `Some(Err(_))` will be mapped to `Ok(Some(_))` and `Err(_)`. + /// + /// # Examples + /// + /// ``` + /// #![feature(transpose_result)] + /// + /// #[derive(Debug, Eq, PartialEq)] + /// struct SomeErr; + /// + /// let x: Result<Option<i32>, SomeErr> = Ok(Some(5)); + /// let y: Option<Result<i32, SomeErr>> = Some(Ok(5)); + /// assert_eq!(x, y.transpose()); + /// ``` + #[inline] + #[unstable(feature = "transpose_result", issue = "47338")] + pub fn transpose(self) -> Result<Option<T>, E> { + match self { + Some(Ok(x)) => Ok(Some(x)), + Some(Err(e)) => Err(e), + None => Ok(None), + } + } +} + // This is a separate function to reduce the code size of .expect() itself. #[inline(never)] #[cold] diff --git a/src/libcore/prelude/v1.rs b/src/libcore/prelude/v1.rs index 3fa6a97d4cd..d43496c387c 100644 --- a/src/libcore/prelude/v1.rs +++ b/src/libcore/prelude/v1.rs @@ -16,7 +16,7 @@ #![stable(feature = "core_prelude", since = "1.4.0")] -// Reexported core operators +// Re-exported core operators #[stable(feature = "core_prelude", since = "1.4.0")] #[doc(no_inline)] pub use marker::{Copy, Send, Sized, Sync}; @@ -24,12 +24,12 @@ pub use marker::{Copy, Send, Sized, Sync}; #[doc(no_inline)] pub use ops::{Drop, Fn, FnMut, FnOnce}; -// Reexported functions +// Re-exported functions #[stable(feature = "core_prelude", since = "1.4.0")] #[doc(no_inline)] pub use mem::drop; -// Reexported types and traits +// Re-exported types and traits #[stable(feature = "core_prelude", since = "1.4.0")] #[doc(no_inline)] pub use clone::Clone; @@ -55,7 +55,7 @@ pub use option::Option::{self, Some, None}; #[doc(no_inline)] pub use result::Result::{self, Ok, Err}; -// Reexported extension traits for primitive types +// Re-exported extension traits for primitive types #[stable(feature = "core_prelude", since = "1.4.0")] #[doc(no_inline)] pub use slice::SliceExt; diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 7f7246df8f2..fab5832d905 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -2321,7 +2321,7 @@ impl<T: ?Sized> PartialOrd for *mut T { /// its owning Unique. /// /// If you're uncertain of whether it's correct to use `Unique` for your purposes, -/// consider using `Shared`, which has weaker semantics. +/// consider using `NonNull`, which has weaker semantics. /// /// Unlike `*mut T`, the pointer must always be non-null, even if the pointer /// is never dereferenced. This is so that enums may use this forbidden value @@ -2330,9 +2330,9 @@ impl<T: ?Sized> PartialOrd for *mut T { /// /// Unlike `*mut T`, `Unique<T>` is covariant over `T`. This should always be correct /// for any type which upholds Unique's aliasing requirements. -#[allow(missing_debug_implementations)] -#[unstable(feature = "unique", reason = "needs an RFC to flesh out design", - issue = "27730")] +#[unstable(feature = "ptr_internals", issue = "0", + reason = "use NonNull instead and consider PhantomData<T> \ + (if you also use #[may_dangle]), Send, and/or Sync")] pub struct Unique<T: ?Sized> { pointer: NonZero<*const T>, // NOTE: this marker has no consequences for variance, but is necessary @@ -2343,26 +2343,34 @@ pub struct Unique<T: ?Sized> { _marker: PhantomData<T>, } +#[unstable(feature = "ptr_internals", issue = "0")] +impl<T: ?Sized> fmt::Debug for Unique<T> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Pointer::fmt(&self.as_ptr(), f) + } +} + /// `Unique` pointers are `Send` if `T` is `Send` because the data they /// reference is unaliased. Note that this aliasing invariant is /// unenforced by the type system; the abstraction using the /// `Unique` must enforce it. -#[unstable(feature = "unique", issue = "27730")] +#[unstable(feature = "ptr_internals", issue = "0")] unsafe impl<T: Send + ?Sized> Send for Unique<T> { } /// `Unique` pointers are `Sync` if `T` is `Sync` because the data they /// reference is unaliased. Note that this aliasing invariant is /// unenforced by the type system; the abstraction using the /// `Unique` must enforce it. -#[unstable(feature = "unique", issue = "27730")] +#[unstable(feature = "ptr_internals", issue = "0")] unsafe impl<T: Sync + ?Sized> Sync for Unique<T> { } -#[unstable(feature = "unique", issue = "27730")] +#[unstable(feature = "ptr_internals", issue = "0")] impl<T: Sized> Unique<T> { /// Creates a new `Unique` that is dangling, but well-aligned. /// /// This is useful for initializing types which lazily allocate, like /// `Vec::new` does. + // FIXME: rename to dangling() to match NonNull? pub fn empty() -> Self { unsafe { let ptr = mem::align_of::<T>() as *mut T; @@ -2371,14 +2379,13 @@ impl<T: Sized> Unique<T> { } } -#[unstable(feature = "unique", issue = "27730")] +#[unstable(feature = "ptr_internals", issue = "0")] impl<T: ?Sized> Unique<T> { /// Creates a new `Unique`. /// /// # Safety /// /// `ptr` must be non-null. - #[unstable(feature = "unique", issue = "27730")] pub const unsafe fn new_unchecked(ptr: *mut T) -> Self { Unique { pointer: NonZero::new_unchecked(ptr), _marker: PhantomData } } @@ -2397,7 +2404,7 @@ impl<T: ?Sized> Unique<T> { /// /// The resulting lifetime is bound to self so this behaves "as if" /// it were actually an instance of T that is getting borrowed. If a longer - /// (unbound) lifetime is needed, use `&*my_ptr.ptr()`. + /// (unbound) lifetime is needed, use `&*my_ptr.as_ptr()`. pub unsafe fn as_ref(&self) -> &T { &*self.as_ptr() } @@ -2406,112 +2413,130 @@ impl<T: ?Sized> Unique<T> { /// /// The resulting lifetime is bound to self so this behaves "as if" /// it were actually an instance of T that is getting borrowed. If a longer - /// (unbound) lifetime is needed, use `&mut *my_ptr.ptr()`. + /// (unbound) lifetime is needed, use `&mut *my_ptr.as_ptr()`. pub unsafe fn as_mut(&mut self) -> &mut T { &mut *self.as_ptr() } } -#[unstable(feature = "unique", issue = "27730")] +#[unstable(feature = "ptr_internals", issue = "0")] impl<T: ?Sized> Clone for Unique<T> { fn clone(&self) -> Self { *self } } -#[unstable(feature = "unique", issue = "27730")] +#[unstable(feature = "ptr_internals", issue = "0")] impl<T: ?Sized> Copy for Unique<T> { } -#[unstable(feature = "unique", issue = "27730")] +#[unstable(feature = "ptr_internals", issue = "0")] impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> { } -#[unstable(feature = "unique", issue = "27730")] +#[unstable(feature = "ptr_internals", issue = "0")] impl<T: ?Sized> fmt::Pointer for Unique<T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Pointer::fmt(&self.as_ptr(), f) } } -#[unstable(feature = "unique", issue = "27730")] +#[unstable(feature = "ptr_internals", issue = "0")] impl<'a, T: ?Sized> From<&'a mut T> for Unique<T> { fn from(reference: &'a mut T) -> Self { Unique { pointer: NonZero::from(reference), _marker: PhantomData } } } -#[unstable(feature = "unique", issue = "27730")] +#[unstable(feature = "ptr_internals", issue = "0")] impl<'a, T: ?Sized> From<&'a T> for Unique<T> { fn from(reference: &'a T) -> Self { Unique { pointer: NonZero::from(reference), _marker: PhantomData } } } +#[unstable(feature = "ptr_internals", issue = "0")] +impl<'a, T: ?Sized> From<NonNull<T>> for Unique<T> { + fn from(p: NonNull<T>) -> Self { + Unique { pointer: p.pointer, _marker: PhantomData } + } +} + +/// Previous name of `NonNull`. +#[rustc_deprecated(since = "1.24", reason = "renamed to `NonNull`")] +#[unstable(feature = "shared", issue = "27730")] +pub type Shared<T> = NonNull<T>; + /// `*mut T` but non-zero and covariant. /// /// This is often the correct thing to use when building data structures using /// raw pointers, but is ultimately more dangerous to use because of its additional -/// properties. If you're not sure if you should use `Shared<T>`, just use `*mut T`! +/// properties. If you're not sure if you should use `NonNull<T>`, just use `*mut T`! /// /// Unlike `*mut T`, the pointer must always be non-null, even if the pointer /// is never dereferenced. This is so that enums may use this forbidden value -/// as a discriminant -- `Option<Shared<T>>` has the same size as `Shared<T>`. +/// as a discriminant -- `Option<NonNull<T>>` has the same size as `NonNull<T>`. /// However the pointer may still dangle if it isn't dereferenced. /// -/// Unlike `*mut T`, `Shared<T>` is covariant over `T`. If this is incorrect +/// Unlike `*mut T`, `NonNull<T>` is covariant over `T`. If this is incorrect /// for your use case, you should include some PhantomData in your type to /// provide invariance, such as `PhantomData<Cell<T>>` or `PhantomData<&'a mut T>`. /// Usually this won't be necessary; covariance is correct for most safe abstractions, /// such as Box, Rc, Arc, Vec, and LinkedList. This is the case because they /// provide a public API that follows the normal shared XOR mutable rules of Rust. -#[allow(missing_debug_implementations)] -#[unstable(feature = "shared", reason = "needs an RFC to flesh out design", - issue = "27730")] -pub struct Shared<T: ?Sized> { +#[stable(feature = "nonnull", since = "1.24.0")] +pub struct NonNull<T: ?Sized> { pointer: NonZero<*const T>, } -/// `Shared` pointers are not `Send` because the data they reference may be aliased. +#[stable(feature = "nonnull", since = "1.24.0")] +impl<T: ?Sized> fmt::Debug for NonNull<T> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Pointer::fmt(&self.as_ptr(), f) + } +} + +/// `NonNull` pointers are not `Send` because the data they reference may be aliased. // NB: This impl is unnecessary, but should provide better error messages. -#[unstable(feature = "shared", issue = "27730")] -impl<T: ?Sized> !Send for Shared<T> { } +#[stable(feature = "nonnull", since = "1.24.0")] +impl<T: ?Sized> !Send for NonNull<T> { } -/// `Shared` pointers are not `Sync` because the data they reference may be aliased. +/// `NonNull` pointers are not `Sync` because the data they reference may be aliased. // NB: This impl is unnecessary, but should provide better error messages. -#[unstable(feature = "shared", issue = "27730")] -impl<T: ?Sized> !Sync for Shared<T> { } +#[stable(feature = "nonnull", since = "1.24.0")] +impl<T: ?Sized> !Sync for NonNull<T> { } -#[unstable(feature = "shared", issue = "27730")] -impl<T: Sized> Shared<T> { - /// Creates a new `Shared` that is dangling, but well-aligned. +impl<T: Sized> NonNull<T> { + /// Creates a new `NonNull` that is dangling, but well-aligned. /// /// This is useful for initializing types which lazily allocate, like /// `Vec::new` does. - pub fn empty() -> Self { + #[stable(feature = "nonnull", since = "1.24.0")] + pub fn dangling() -> Self { unsafe { let ptr = mem::align_of::<T>() as *mut T; - Shared::new_unchecked(ptr) + NonNull::new_unchecked(ptr) } } } -#[unstable(feature = "shared", issue = "27730")] -impl<T: ?Sized> Shared<T> { - /// Creates a new `Shared`. +impl<T: ?Sized> NonNull<T> { + /// Creates a new `NonNull`. /// /// # Safety /// /// `ptr` must be non-null. - #[unstable(feature = "shared", issue = "27730")] + #[stable(feature = "nonnull", since = "1.24.0")] pub const unsafe fn new_unchecked(ptr: *mut T) -> Self { - Shared { pointer: NonZero::new_unchecked(ptr) } + NonNull { pointer: NonZero::new_unchecked(ptr) } } - /// Creates a new `Shared` if `ptr` is non-null. + /// Creates a new `NonNull` if `ptr` is non-null. + #[stable(feature = "nonnull", since = "1.24.0")] pub fn new(ptr: *mut T) -> Option<Self> { - NonZero::new(ptr as *const T).map(|nz| Shared { pointer: nz }) + NonZero::new(ptr as *const T).map(|nz| NonNull { pointer: nz }) } /// Acquires the underlying `*mut` pointer. + #[stable(feature = "nonnull", since = "1.24.0")] pub fn as_ptr(self) -> *mut T { self.pointer.get() as *mut T } @@ -2520,7 +2545,8 @@ impl<T: ?Sized> Shared<T> { /// /// The resulting lifetime is bound to self so this behaves "as if" /// it were actually an instance of T that is getting borrowed. If a longer - /// (unbound) lifetime is needed, use `&*my_ptr.ptr()`. + /// (unbound) lifetime is needed, use `&*my_ptr.as_ptr()`. + #[stable(feature = "nonnull", since = "1.24.0")] pub unsafe fn as_ref(&self) -> &T { &*self.as_ptr() } @@ -2529,56 +2555,50 @@ impl<T: ?Sized> Shared<T> { /// /// The resulting lifetime is bound to self so this behaves "as if" /// it were actually an instance of T that is getting borrowed. If a longer - /// (unbound) lifetime is needed, use `&mut *my_ptr.ptr_mut()`. + /// (unbound) lifetime is needed, use `&mut *my_ptr.as_ptr()`. + #[stable(feature = "nonnull", since = "1.24.0")] pub unsafe fn as_mut(&mut self) -> &mut T { &mut *self.as_ptr() } - - /// Acquires the underlying pointer as a `*mut` pointer. - #[rustc_deprecated(since = "1.19", reason = "renamed to `as_ptr` for ergonomics/consistency")] - #[unstable(feature = "shared", issue = "27730")] - pub unsafe fn as_mut_ptr(&self) -> *mut T { - self.as_ptr() - } } -#[unstable(feature = "shared", issue = "27730")] -impl<T: ?Sized> Clone for Shared<T> { +#[stable(feature = "nonnull", since = "1.24.0")] +impl<T: ?Sized> Clone for NonNull<T> { fn clone(&self) -> Self { *self } } -#[unstable(feature = "shared", issue = "27730")] -impl<T: ?Sized> Copy for Shared<T> { } +#[stable(feature = "nonnull", since = "1.24.0")] +impl<T: ?Sized> Copy for NonNull<T> { } -#[unstable(feature = "shared", issue = "27730")] -impl<T: ?Sized, U: ?Sized> CoerceUnsized<Shared<U>> for Shared<T> where T: Unsize<U> { } +#[stable(feature = "nonnull", since = "1.24.0")] +impl<T: ?Sized, U: ?Sized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> { } -#[unstable(feature = "shared", issue = "27730")] -impl<T: ?Sized> fmt::Pointer for Shared<T> { +#[stable(feature = "nonnull", since = "1.24.0")] +impl<T: ?Sized> fmt::Pointer for NonNull<T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Pointer::fmt(&self.as_ptr(), f) } } -#[unstable(feature = "shared", issue = "27730")] -impl<T: ?Sized> From<Unique<T>> for Shared<T> { +#[stable(feature = "nonnull", since = "1.24.0")] +impl<T: ?Sized> From<Unique<T>> for NonNull<T> { fn from(unique: Unique<T>) -> Self { - Shared { pointer: unique.pointer } + NonNull { pointer: unique.pointer } } } -#[unstable(feature = "shared", issue = "27730")] -impl<'a, T: ?Sized> From<&'a mut T> for Shared<T> { +#[stable(feature = "nonnull", since = "1.24.0")] +impl<'a, T: ?Sized> From<&'a mut T> for NonNull<T> { fn from(reference: &'a mut T) -> Self { - Shared { pointer: NonZero::from(reference) } + NonNull { pointer: NonZero::from(reference) } } } -#[unstable(feature = "shared", issue = "27730")] -impl<'a, T: ?Sized> From<&'a T> for Shared<T> { +#[stable(feature = "nonnull", since = "1.24.0")] +impl<'a, T: ?Sized> From<&'a T> for NonNull<T> { fn from(reference: &'a T) -> Self { - Shared { pointer: NonZero::from(reference) } + NonNull { pointer: NonZero::from(reference) } } } diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 2ace3d2aee8..3801db94e15 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -909,6 +909,35 @@ impl<T: Default, E> Result<T, E> { } } +impl<T, E> Result<Option<T>, E> { + /// Transposes a `Result` of an `Option` into an `Option` of a `Result`. + /// + /// `Ok(None)` will be mapped to `None`. + /// `Ok(Some(_))` and `Err(_)` will be mapped to `Some(Ok(_))` and `Some(Err(_))`. + /// + /// # Examples + /// + /// ``` + /// #![feature(transpose_result)] + /// + /// #[derive(Debug, Eq, PartialEq)] + /// struct SomeErr; + /// + /// let x: Result<Option<i32>, SomeErr> = Ok(Some(5)); + /// let y: Option<Result<i32, SomeErr>> = Some(Ok(5)); + /// assert_eq!(x.transpose(), y); + /// ``` + #[inline] + #[unstable(feature = "transpose_result", issue = "47338")] + pub fn transpose(self) -> Option<Result<T, E>> { + match self { + Ok(Some(x)) => Some(Ok(x)), + Ok(None) => None, + Err(e) => Some(Err(e)), + } + } +} + // This is a separate function to reduce the code size of the methods #[inline(never)] #[cold] diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index e6b79314aa9..244bf476caf 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -22,7 +22,7 @@ // a lot of stuff defined here. Let's keep it clean. // // Since slices don't support inherent methods; all operations -// on them are defined on traits, which are then reexported from +// on them are defined on traits, which are then re-exported from // the prelude for convenience. So there are a lot of traits here. // // The layout of this file is thus: @@ -104,6 +104,9 @@ pub trait SliceExt { #[stable(feature = "core", since = "1.6.0")] fn chunks(&self, size: usize) -> Chunks<Self::Item>; + #[unstable(feature = "exact_chunks", issue = "47115")] + fn exact_chunks(&self, size: usize) -> ExactChunks<Self::Item>; + #[stable(feature = "core", since = "1.6.0")] fn get<I>(&self, index: I) -> Option<&I::Output> where I: SliceIndex<Self>; @@ -181,6 +184,9 @@ pub trait SliceExt { #[stable(feature = "core", since = "1.6.0")] fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<Self::Item>; + #[unstable(feature = "exact_chunks", issue = "47115")] + fn exact_chunks_mut(&mut self, size: usize) -> ExactChunksMut<Self::Item>; + #[stable(feature = "core", since = "1.6.0")] fn swap(&mut self, a: usize, b: usize); @@ -357,6 +363,14 @@ impl<T> SliceExt for [T] { } #[inline] + fn exact_chunks(&self, chunk_size: usize) -> ExactChunks<T> { + assert!(chunk_size != 0); + let rem = self.len() % chunk_size; + let len = self.len() - rem; + ExactChunks { v: &self[..len], chunk_size: chunk_size} + } + + #[inline] fn get<I>(&self, index: I) -> Option<&I::Output> where I: SliceIndex<[T]> { @@ -540,6 +554,14 @@ impl<T> SliceExt for [T] { } #[inline] + fn exact_chunks_mut(&mut self, chunk_size: usize) -> ExactChunksMut<T> { + assert!(chunk_size != 0); + let rem = self.len() % chunk_size; + let len = self.len() - rem; + ExactChunksMut { v: &mut self[..len], chunk_size: chunk_size} + } + + #[inline] fn swap(&mut self, a: usize, b: usize) { unsafe { // Can't take two mutable loans from one vector, so instead just cast @@ -1215,6 +1237,43 @@ macro_rules! iterator { } accum } + + #[inline] + #[rustc_inherit_overflow_checks] + fn position<P>(&mut self, mut predicate: P) -> Option<usize> where + Self: Sized, + P: FnMut(Self::Item) -> bool, + { + // The addition might panic on overflow + let n = self.len(); + self.try_fold(0, move |i, x| { + if predicate(x) { Err(i) } + else { Ok(i + 1) } + }).err() + .map(|i| { + unsafe { assume(i < n) }; + i + }) + } + + #[inline] + fn rposition<P>(&mut self, mut predicate: P) -> Option<usize> where + P: FnMut(Self::Item) -> bool, + Self: Sized + ExactSizeIterator + DoubleEndedIterator + { + // No need for an overflow check here, because `ExactSizeIterator` + // implies that the number of elements fits into a `usize`. + let n = self.len(); + self.try_rfold(n, move |i, x| { + let i = i - 1; + if predicate(x) { Err(i) } + else { Ok(i) } + }).err() + .map(|i| { + unsafe { assume(i < n) }; + i + }) + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -2378,6 +2437,209 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksMut<'a, T> { fn may_have_side_effect() -> bool { false } } +/// An iterator over a slice in (non-overlapping) chunks (`chunk_size` elements at a +/// time). +/// +/// When the slice len is not evenly divided by the chunk size, the last +/// up to `chunk_size-1` elements will be omitted. +/// +/// This struct is created by the [`exact_chunks`] method on [slices]. +/// +/// [`exact_chunks`]: ../../std/primitive.slice.html#method.exact_chunks +/// [slices]: ../../std/primitive.slice.html +#[derive(Debug)] +#[unstable(feature = "exact_chunks", issue = "47115")] +pub struct ExactChunks<'a, T:'a> { + v: &'a [T], + chunk_size: usize +} + +// FIXME(#26925) Remove in favor of `#[derive(Clone)]` +#[unstable(feature = "exact_chunks", issue = "47115")] +impl<'a, T> Clone for ExactChunks<'a, T> { + fn clone(&self) -> ExactChunks<'a, T> { + ExactChunks { + v: self.v, + chunk_size: self.chunk_size, + } + } +} + +#[unstable(feature = "exact_chunks", issue = "47115")] +impl<'a, T> Iterator for ExactChunks<'a, T> { + type Item = &'a [T]; + + #[inline] + fn next(&mut self) -> Option<&'a [T]> { + if self.v.len() < self.chunk_size { + None + } else { + let (fst, snd) = self.v.split_at(self.chunk_size); + self.v = snd; + Some(fst) + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + let n = self.v.len() / self.chunk_size; + (n, Some(n)) + } + + #[inline] + fn count(self) -> usize { + self.len() + } + + #[inline] + fn nth(&mut self, n: usize) -> Option<Self::Item> { + let (start, overflow) = n.overflowing_mul(self.chunk_size); + if start >= self.v.len() || overflow { + self.v = &[]; + None + } else { + let (_, snd) = self.v.split_at(start); + self.v = snd; + self.next() + } + } + + #[inline] + fn last(mut self) -> Option<Self::Item> { + self.next_back() + } +} + +#[unstable(feature = "exact_chunks", issue = "47115")] +impl<'a, T> DoubleEndedIterator for ExactChunks<'a, T> { + #[inline] + fn next_back(&mut self) -> Option<&'a [T]> { + if self.v.len() < self.chunk_size { + None + } else { + let (fst, snd) = self.v.split_at(self.v.len() - self.chunk_size); + self.v = fst; + Some(snd) + } + } +} + +#[unstable(feature = "exact_chunks", issue = "47115")] +impl<'a, T> ExactSizeIterator for ExactChunks<'a, T> { + fn is_empty(&self) -> bool { + self.v.is_empty() + } +} + +#[unstable(feature = "fused", issue = "35602")] +impl<'a, T> FusedIterator for ExactChunks<'a, T> {} + +#[doc(hidden)] +unsafe impl<'a, T> TrustedRandomAccess for ExactChunks<'a, T> { + unsafe fn get_unchecked(&mut self, i: usize) -> &'a [T] { + let start = i * self.chunk_size; + from_raw_parts(self.v.as_ptr().offset(start as isize), self.chunk_size) + } + fn may_have_side_effect() -> bool { false } +} + +/// An iterator over a slice in (non-overlapping) mutable chunks (`chunk_size` +/// elements at a time). When the slice len is not evenly divided by the chunk +/// size, the last up to `chunk_size-1` elements will be omitted. +/// +/// This struct is created by the [`exact_chunks_mut`] method on [slices]. +/// +/// [`exact_chunks_mut`]: ../../std/primitive.slice.html#method.exact_chunks_mut +/// [slices]: ../../std/primitive.slice.html +#[derive(Debug)] +#[unstable(feature = "exact_chunks", issue = "47115")] +pub struct ExactChunksMut<'a, T:'a> { + v: &'a mut [T], + chunk_size: usize +} + +#[unstable(feature = "exact_chunks", issue = "47115")] +impl<'a, T> Iterator for ExactChunksMut<'a, T> { + type Item = &'a mut [T]; + + #[inline] + fn next(&mut self) -> Option<&'a mut [T]> { + if self.v.len() < self.chunk_size { + None + } else { + let tmp = mem::replace(&mut self.v, &mut []); + let (head, tail) = tmp.split_at_mut(self.chunk_size); + self.v = tail; + Some(head) + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + let n = self.v.len() / self.chunk_size; + (n, Some(n)) + } + + #[inline] + fn count(self) -> usize { + self.len() + } + + #[inline] + fn nth(&mut self, n: usize) -> Option<&'a mut [T]> { + let (start, overflow) = n.overflowing_mul(self.chunk_size); + if start >= self.v.len() || overflow { + self.v = &mut []; + None + } else { + let tmp = mem::replace(&mut self.v, &mut []); + let (_, snd) = tmp.split_at_mut(start); + self.v = snd; + self.next() + } + } + + #[inline] + fn last(mut self) -> Option<Self::Item> { + self.next_back() + } +} + +#[unstable(feature = "exact_chunks", issue = "47115")] +impl<'a, T> DoubleEndedIterator for ExactChunksMut<'a, T> { + #[inline] + fn next_back(&mut self) -> Option<&'a mut [T]> { + if self.v.len() < self.chunk_size { + None + } else { + let tmp = mem::replace(&mut self.v, &mut []); + let tmp_len = tmp.len(); + let (head, tail) = tmp.split_at_mut(tmp_len - self.chunk_size); + self.v = head; + Some(tail) + } + } +} + +#[unstable(feature = "exact_chunks", issue = "47115")] +impl<'a, T> ExactSizeIterator for ExactChunksMut<'a, T> { + fn is_empty(&self) -> bool { + self.v.is_empty() + } +} + +#[unstable(feature = "fused", issue = "35602")] +impl<'a, T> FusedIterator for ExactChunksMut<'a, T> {} + +#[doc(hidden)] +unsafe impl<'a, T> TrustedRandomAccess for ExactChunksMut<'a, T> { + unsafe fn get_unchecked(&mut self, i: usize) -> &'a mut [T] { + let start = i * self.chunk_size; + from_raw_parts_mut(self.v.as_mut_ptr().offset(start as isize), self.chunk_size) + } + fn may_have_side_effect() -> bool { false } +} + // // Free functions // diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index c4b85b82981..1c32452f846 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -41,7 +41,7 @@ #![feature(trusted_len)] #![feature(try_from)] #![feature(try_trait)] -#![feature(unique)] +#![feature(exact_chunks)] extern crate core; extern crate test; diff --git a/src/libcore/tests/ptr.rs b/src/libcore/tests/ptr.rs index 98436f0e1d1..00f87336f3c 100644 --- a/src/libcore/tests/ptr.rs +++ b/src/libcore/tests/ptr.rs @@ -249,9 +249,9 @@ fn test_set_memory() { } #[test] -fn test_unsized_unique() { +fn test_unsized_nonnull() { let xs: &[i32] = &[1, 2, 3]; - let ptr = unsafe { Unique::new_unchecked(xs as *const [i32] as *mut [i32]) }; + let ptr = unsafe { NonNull::new_unchecked(xs as *const [i32] as *mut [i32]) }; let ys = unsafe { ptr.as_ref() }; let zs: &[i32] = &[1, 2, 3]; assert!(ys == zs); diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs index 40e5fe5758a..13740b95802 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -10,6 +10,25 @@ use core::result::Result::{Ok, Err}; + +#[test] +fn test_position() { + let b = [1, 2, 3, 5, 5]; + assert!(b.iter().position(|&v| v == 9) == None); + assert!(b.iter().position(|&v| v == 5) == Some(3)); + assert!(b.iter().position(|&v| v == 3) == Some(2)); + assert!(b.iter().position(|&v| v == 0) == None); +} + +#[test] +fn test_rposition() { + let b = [1, 2, 3, 5, 5]; + assert!(b.iter().rposition(|&v| v == 9) == None); + assert!(b.iter().rposition(|&v| v == 5) == Some(4)); + assert!(b.iter().rposition(|&v| v == 3) == Some(2)); + assert!(b.iter().rposition(|&v| v == 0) == None); +} + #[test] fn test_binary_search() { let b: [i32; 0] = []; @@ -117,12 +136,12 @@ fn test_chunks_count() { fn test_chunks_nth() { let v: &[i32] = &[0, 1, 2, 3, 4, 5]; let mut c = v.chunks(2); - assert_eq!(c.nth(1).unwrap()[1], 3); - assert_eq!(c.next().unwrap()[0], 4); + assert_eq!(c.nth(1).unwrap(), &[2, 3]); + assert_eq!(c.next().unwrap(), &[4, 5]); let v2: &[i32] = &[0, 1, 2, 3, 4]; let mut c2 = v2.chunks(3); - assert_eq!(c2.nth(1).unwrap()[1], 4); + assert_eq!(c2.nth(1).unwrap(), &[3, 4]); assert_eq!(c2.next(), None); } @@ -168,12 +187,12 @@ fn test_chunks_mut_count() { fn test_chunks_mut_nth() { let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5]; let mut c = v.chunks_mut(2); - assert_eq!(c.nth(1).unwrap()[1], 3); - assert_eq!(c.next().unwrap()[0], 4); + assert_eq!(c.nth(1).unwrap(), &[2, 3]); + assert_eq!(c.next().unwrap(), &[4, 5]); let v2: &mut [i32] = &mut [0, 1, 2, 3, 4]; let mut c2 = v2.chunks_mut(3); - assert_eq!(c2.nth(1).unwrap()[1], 4); + assert_eq!(c2.nth(1).unwrap(), &[3, 4]); assert_eq!(c2.next(), None); } @@ -181,11 +200,11 @@ fn test_chunks_mut_nth() { fn test_chunks_mut_last() { let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5]; let c = v.chunks_mut(2); - assert_eq!(c.last().unwrap()[1], 5); + assert_eq!(c.last().unwrap(), &[4, 5]); let v2: &mut [i32] = &mut [0, 1, 2, 3, 4]; let c2 = v2.chunks_mut(2); - assert_eq!(c2.last().unwrap()[0], 4); + assert_eq!(c2.last().unwrap(), &[4]); } #[test] @@ -203,6 +222,110 @@ fn test_chunks_mut_zip() { } #[test] +fn test_exact_chunks_count() { + let v: &[i32] = &[0, 1, 2, 3, 4, 5]; + let c = v.exact_chunks(3); + assert_eq!(c.count(), 2); + + let v2: &[i32] = &[0, 1, 2, 3, 4]; + let c2 = v2.exact_chunks(2); + assert_eq!(c2.count(), 2); + + let v3: &[i32] = &[]; + let c3 = v3.exact_chunks(2); + assert_eq!(c3.count(), 0); +} + +#[test] +fn test_exact_chunks_nth() { + let v: &[i32] = &[0, 1, 2, 3, 4, 5]; + let mut c = v.exact_chunks(2); + assert_eq!(c.nth(1).unwrap(), &[2, 3]); + assert_eq!(c.next().unwrap(), &[4, 5]); + + let v2: &[i32] = &[0, 1, 2, 3, 4, 5, 6]; + let mut c2 = v2.exact_chunks(3); + assert_eq!(c2.nth(1).unwrap(), &[3, 4, 5]); + assert_eq!(c2.next(), None); +} + +#[test] +fn test_exact_chunks_last() { + let v: &[i32] = &[0, 1, 2, 3, 4, 5]; + let c = v.exact_chunks(2); + assert_eq!(c.last().unwrap(), &[4, 5]); + + let v2: &[i32] = &[0, 1, 2, 3, 4]; + let c2 = v2.exact_chunks(2); + assert_eq!(c2.last().unwrap(), &[2, 3]); +} + +#[test] +fn test_exact_chunks_zip() { + let v1: &[i32] = &[0, 1, 2, 3, 4]; + let v2: &[i32] = &[6, 7, 8, 9, 10]; + + let res = v1.exact_chunks(2) + .zip(v2.exact_chunks(2)) + .map(|(a, b)| a.iter().sum::<i32>() + b.iter().sum::<i32>()) + .collect::<Vec<_>>(); + assert_eq!(res, vec![14, 22]); +} + +#[test] +fn test_exact_chunks_mut_count() { + let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5]; + let c = v.exact_chunks_mut(3); + assert_eq!(c.count(), 2); + + let v2: &mut [i32] = &mut [0, 1, 2, 3, 4]; + let c2 = v2.exact_chunks_mut(2); + assert_eq!(c2.count(), 2); + + let v3: &mut [i32] = &mut []; + let c3 = v3.exact_chunks_mut(2); + assert_eq!(c3.count(), 0); +} + +#[test] +fn test_exact_chunks_mut_nth() { + let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5]; + let mut c = v.exact_chunks_mut(2); + assert_eq!(c.nth(1).unwrap(), &[2, 3]); + assert_eq!(c.next().unwrap(), &[4, 5]); + + let v2: &mut [i32] = &mut [0, 1, 2, 3, 4, 5, 6]; + let mut c2 = v2.exact_chunks_mut(3); + assert_eq!(c2.nth(1).unwrap(), &[3, 4, 5]); + assert_eq!(c2.next(), None); +} + +#[test] +fn test_exact_chunks_mut_last() { + let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5]; + let c = v.exact_chunks_mut(2); + assert_eq!(c.last().unwrap(), &[4, 5]); + + let v2: &mut [i32] = &mut [0, 1, 2, 3, 4]; + let c2 = v2.exact_chunks_mut(2); + assert_eq!(c2.last().unwrap(), &[2, 3]); +} + +#[test] +fn test_exact_chunks_mut_zip() { + let v1: &mut [i32] = &mut [0, 1, 2, 3, 4]; + let v2: &[i32] = &[6, 7, 8, 9, 10]; + + for (a, b) in v1.exact_chunks_mut(2).zip(v2.exact_chunks(2)) { + let sum = b.iter().sum::<i32>(); + for v in a { + *v += sum; + } + } + assert_eq!(v1, [13, 14, 19, 20, 4]); +} + +#[test] fn test_windows_count() { let v: &[i32] = &[0, 1, 2, 3, 4, 5]; let c = v.windows(3); diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 7b48e7801df..1d7cde81265 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -2003,7 +2003,69 @@ that refers to itself. That is permitting, since the closure would be invoking itself via a virtual call, and hence does not directly reference its own *type*. -"##, } +"##, + +E0692: r##" +A `repr(transparent)` type was also annotated with other, incompatible +representation hints. + +Erroneous code example: + +```compile_fail,E0692 +#![feature(repr_transparent)] + +#[repr(transparent, C)] // error: incompatible representation hints +struct Grams(f32); +``` + +A type annotated as `repr(transparent)` delegates all representation concerns to +another type, so adding more representation hints is contradictory. Remove +either the `transparent` hint or the other hints, like this: + +``` +#![feature(repr_transparent)] + +#[repr(transparent)] +struct Grams(f32); +``` + +Alternatively, move the other attributes to the contained type: + +``` +#![feature(repr_transparent)] + +#[repr(C)] +struct Foo { + x: i32, + // ... +} + +#[repr(transparent)] +struct FooWrapper(Foo); +``` + +Note that introducing another `struct` just to have a place for the other +attributes may have unintended side effects on the representation: + +``` +#![feature(repr_transparent)] + +#[repr(transparent)] +struct Grams(f32); + +#[repr(C)] +struct Float(f32); + +#[repr(transparent)] +struct Grams2(Float); // this is not equivalent to `Grams` above +``` + +Here, `Grams2` is a not equivalent to `Grams` -- the former transparently wraps +a (non-transparent) struct containing a single float, while `Grams` is a +transparent wrapper around a float. This can make a difference for the ABI. +"##, + +} register_diagnostics! { diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index 4b528a0fdc7..a073910fdc8 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -92,6 +92,7 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { let mut int_reprs = 0; let mut is_c = false; let mut is_simd = false; + let mut is_transparent = false; for hint in &hints { let name = if let Some(name) = hint.name() { @@ -137,6 +138,14 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { continue } } + "transparent" => { + is_transparent = true; + if target != Target::Struct { + ("a", "struct") + } else { + continue + } + } "i8" | "u8" | "i16" | "u16" | "i32" | "u32" | "i64" | "u64" | "isize" | "usize" => { @@ -155,14 +164,22 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { .emit(); } + // Just point at all repr hints if there are any incompatibilities. + // This is not ideal, but tracking precisely which ones are at fault is a huge hassle. + let hint_spans = hints.iter().map(|hint| hint.span); + + // Error on repr(transparent, <anything else>). + if is_transparent && hints.len() > 1 { + let hint_spans: Vec<_> = hint_spans.clone().collect(); + span_err!(self.tcx.sess, hint_spans, E0692, + "transparent struct cannot have other repr hints"); + } // Warn on repr(u8, u16), repr(C, simd), and c-like-enum-repr(C, u8) if (int_reprs > 1) || (is_simd && is_c) || (int_reprs == 1 && is_c && is_c_like_enum(item)) { - // Just point at all repr hints. This is not ideal, but tracking - // precisely which ones are at fault is a huge hassle. - let spans: Vec<_> = hints.iter().map(|hint| hint.span).collect(); - span_warn!(self.tcx.sess, spans, E0566, + let hint_spans: Vec<_> = hint_spans.collect(); + span_warn!(self.tcx.sess, hint_spans, E0566, "conflicting representation hints"); } } diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 84d45906d24..32b55a05124 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1502,8 +1502,8 @@ impl<'a> LoweringContext<'a> { fn_def_id: Option<DefId>, impl_trait_return_allow: bool) -> P<hir::FnDecl> { - // NOTE: The two last paramters here have to do with impl Trait. If fn_def_id is Some, - // then impl Trait arguments are lowered into generic paramters on the given + // NOTE: The two last parameters here have to do with impl Trait. If fn_def_id is Some, + // then impl Trait arguments are lowered into generic parameters on the given // fn_def_id, otherwise impl Trait is disallowed. (for now) // // Furthermore, if impl_trait_return_allow is true, then impl Trait may be used in @@ -2046,7 +2046,8 @@ impl<'a> LoweringContext<'a> { }; // Correctly resolve `self` imports - if path.segments.last().unwrap().identifier.name == keywords::SelfValue.name() { + if path.segments.len() > 1 && + path.segments.last().unwrap().identifier.name == keywords::SelfValue.name() { let _ = path.segments.pop(); if ident.name == keywords::SelfValue.name() { *name = path.segments.last().unwrap().identifier.name; @@ -2119,7 +2120,7 @@ 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 reexport by accident when `pub`, e.g. in documentation. + // a re-export by accident when `pub`, e.g. in documentation. let path = P(self.lower_path(id, &prefix, ParamMode::Explicit, true)); *vis = hir::Inherited; hir::ItemUse(path, hir::UseKind::ListStem) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 8d43b9b4aa7..3da2855929d 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -34,13 +34,14 @@ use util::nodemap::{NodeMap, FxHashSet}; use syntax_pos::{Span, DUMMY_SP}; use syntax::codemap::{self, Spanned}; use syntax::abi::Abi; -use syntax::ast::{Ident, Name, NodeId, DUMMY_NODE_ID, AsmDialect}; +use syntax::ast::{self, Ident, Name, NodeId, DUMMY_NODE_ID, AsmDialect}; use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, MetaItem}; use syntax::ext::hygiene::SyntaxContext; use syntax::ptr::P; use syntax::symbol::{Symbol, keywords}; use syntax::tokenstream::TokenStream; use syntax::util::ThinVec; +use syntax::util::parser::ExprPrecedence; use ty::AdtKind; use rustc_data_structures::indexed_vec; @@ -958,6 +959,31 @@ impl BinOp_ { } } +impl Into<ast::BinOpKind> for BinOp_ { + fn into(self) -> ast::BinOpKind { + match self { + BiAdd => ast::BinOpKind::Add, + BiSub => ast::BinOpKind::Sub, + BiMul => ast::BinOpKind::Mul, + BiDiv => ast::BinOpKind::Div, + BiRem => ast::BinOpKind::Rem, + BiAnd => ast::BinOpKind::And, + BiOr => ast::BinOpKind::Or, + BiBitXor => ast::BinOpKind::BitXor, + BiBitAnd => ast::BinOpKind::BitAnd, + BiBitOr => ast::BinOpKind::BitOr, + BiShl => ast::BinOpKind::Shl, + BiShr => ast::BinOpKind::Shr, + BiEq => ast::BinOpKind::Eq, + BiLt => ast::BinOpKind::Lt, + BiLe => ast::BinOpKind::Le, + BiNe => ast::BinOpKind::Ne, + BiGe => ast::BinOpKind::Ge, + BiGt => ast::BinOpKind::Gt, + } + } +} + pub type BinOp = Spanned<BinOp_>; #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] @@ -1166,6 +1192,42 @@ pub struct Expr { pub hir_id: HirId, } +impl Expr { + pub fn precedence(&self) -> ExprPrecedence { + match self.node { + ExprBox(_) => ExprPrecedence::Box, + ExprArray(_) => ExprPrecedence::Array, + ExprCall(..) => ExprPrecedence::Call, + ExprMethodCall(..) => ExprPrecedence::MethodCall, + ExprTup(_) => ExprPrecedence::Tup, + ExprBinary(op, ..) => ExprPrecedence::Binary(op.node.into()), + ExprUnary(..) => ExprPrecedence::Unary, + ExprLit(_) => ExprPrecedence::Lit, + ExprType(..) | ExprCast(..) => ExprPrecedence::Cast, + ExprIf(..) => ExprPrecedence::If, + ExprWhile(..) => ExprPrecedence::While, + ExprLoop(..) => ExprPrecedence::Loop, + ExprMatch(..) => ExprPrecedence::Match, + ExprClosure(..) => ExprPrecedence::Closure, + ExprBlock(..) => ExprPrecedence::Block, + ExprAssign(..) => ExprPrecedence::Assign, + ExprAssignOp(..) => ExprPrecedence::AssignOp, + ExprField(..) => ExprPrecedence::Field, + ExprTupField(..) => ExprPrecedence::TupField, + ExprIndex(..) => ExprPrecedence::Index, + ExprPath(..) => ExprPrecedence::Path, + ExprAddrOf(..) => ExprPrecedence::AddrOf, + ExprBreak(..) => ExprPrecedence::Break, + ExprAgain(..) => ExprPrecedence::Continue, + ExprRet(..) => ExprPrecedence::Ret, + ExprInlineAsm(..) => ExprPrecedence::InlineAsm, + ExprStruct(..) => ExprPrecedence::Struct, + ExprRepeat(..) => ExprPrecedence::Repeat, + ExprYield(..) => ExprPrecedence::Yield, + } + } +} + impl fmt::Debug for Expr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "expr({}: {})", self.id, diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index a8e55674ae5..4cfa7a470a4 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -1104,7 +1104,7 @@ impl<'a> State<'a> { } pub fn print_expr_maybe_paren(&mut self, expr: &hir::Expr, prec: i8) -> io::Result<()> { - let needs_par = expr_precedence(expr) < prec; + let needs_par = expr.precedence().order() < prec; if needs_par { self.popen()?; } @@ -2318,55 +2318,6 @@ fn stmt_ends_with_semi(stmt: &hir::Stmt_) -> bool { } } - -fn expr_precedence(expr: &hir::Expr) -> i8 { - use syntax::util::parser::*; - - match expr.node { - hir::ExprClosure(..) => PREC_CLOSURE, - - hir::ExprBreak(..) | - hir::ExprAgain(..) | - hir::ExprRet(..) | - hir::ExprYield(..) => PREC_JUMP, - - // Binop-like expr kinds, handled by `AssocOp`. - hir::ExprBinary(op, _, _) => bin_op_to_assoc_op(op.node).precedence() as i8, - - hir::ExprCast(..) => AssocOp::As.precedence() as i8, - hir::ExprType(..) => AssocOp::Colon.precedence() as i8, - - hir::ExprAssign(..) | - hir::ExprAssignOp(..) => AssocOp::Assign.precedence() as i8, - - // Unary, prefix - hir::ExprBox(..) | - hir::ExprAddrOf(..) | - hir::ExprUnary(..) => PREC_PREFIX, - - // Unary, postfix - hir::ExprCall(..) | - hir::ExprMethodCall(..) | - hir::ExprField(..) | - hir::ExprTupField(..) | - hir::ExprIndex(..) | - hir::ExprInlineAsm(..) => PREC_POSTFIX, - - // Never need parens - hir::ExprArray(..) | - hir::ExprRepeat(..) | - hir::ExprTup(..) | - hir::ExprLit(..) | - hir::ExprPath(..) | - hir::ExprIf(..) | - hir::ExprWhile(..) | - hir::ExprLoop(..) | - hir::ExprMatch(..) | - hir::ExprBlock(..) | - hir::ExprStruct(..) => PREC_PAREN, - } -} - fn bin_op_to_assoc_op(op: hir::BinOp_) -> AssocOp { use hir::BinOp_::*; match op { diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index c477a0d383e..541c1356dd4 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -1067,6 +1067,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { sub_region: Region<'tcx>, sup_origin: SubregionOrigin<'tcx>, sup_region: Region<'tcx>) { + let mut err = self.report_inference_failure(var_origin); self.tcx.note_and_explain_region(region_scope_tree, &mut err, diff --git a/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs b/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs index d4ea899dc74..7b0f2933580 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs @@ -53,7 +53,7 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { /// /// It will later be extended to trait objects. pub(super) fn try_report_anon_anon_conflict(&self) -> Option<ErrorReported> { - let NiceRegionError { span, sub, sup, .. } = *self; + let (span, sub, sup) = self.get_regions(); // Determine whether the sub and sup consist of both anonymous (elided) regions. let anon_reg_sup = self.is_suitable_region(sup)?; diff --git a/src/librustc/infer/error_reporting/nice_region_error/mod.rs b/src/librustc/infer/error_reporting/nice_region_error/mod.rs index edc38b6bb14..59b36a50a2b 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/mod.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/mod.rs @@ -18,46 +18,64 @@ use util::common::ErrorReported; mod different_lifetimes; mod find_anon_type; mod named_anon_conflict; +mod outlives_closure; mod util; impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { pub fn try_report_nice_region_error(&self, error: &RegionResolutionError<'tcx>) -> bool { - let (span, sub, sup) = match *error { - ConcreteFailure(ref origin, sub, sup) => (origin.span(), sub, sup), - SubSupConflict(_, ref origin, sub, _, sup) => (origin.span(), sub, sup), - _ => return false, // inapplicable - }; + match *error { + ConcreteFailure(..) | SubSupConflict(..) => {} + _ => return false, // inapplicable + } if let Some(tables) = self.in_progress_tables { let tables = tables.borrow(); - NiceRegionError::new(self.tcx, span, sub, sup, Some(&tables)).try_report().is_some() + NiceRegionError::new(self.tcx, error.clone(), Some(&tables)).try_report().is_some() } else { - NiceRegionError::new(self.tcx, span, sub, sup, None).try_report().is_some() + NiceRegionError::new(self.tcx, error.clone(), None).try_report().is_some() } } } pub struct NiceRegionError<'cx, 'gcx: 'tcx, 'tcx: 'cx> { tcx: TyCtxt<'cx, 'gcx, 'tcx>, - span: Span, - sub: ty::Region<'tcx>, - sup: ty::Region<'tcx>, + error: Option<RegionResolutionError<'tcx>>, + regions: Option<(Span, ty::Region<'tcx>, ty::Region<'tcx>)>, tables: Option<&'cx ty::TypeckTables<'tcx>>, } impl<'cx, 'gcx, 'tcx> NiceRegionError<'cx, 'gcx, 'tcx> { pub fn new( tcx: TyCtxt<'cx, 'gcx, 'tcx>, + error: RegionResolutionError<'tcx>, + tables: Option<&'cx ty::TypeckTables<'tcx>>, + ) -> Self { + Self { tcx, error: Some(error), regions: None, tables } + } + + pub fn new_from_span( + tcx: TyCtxt<'cx, 'gcx, 'tcx>, span: Span, sub: ty::Region<'tcx>, sup: ty::Region<'tcx>, tables: Option<&'cx ty::TypeckTables<'tcx>>, ) -> Self { - Self { tcx, span, sub, sup, tables } + Self { tcx, error: None, regions: Some((span, sub, sup)), tables } } pub fn try_report(&self) -> Option<ErrorReported> { self.try_report_named_anon_conflict() .or_else(|| self.try_report_anon_anon_conflict()) + .or_else(|| self.try_report_outlives_closure()) + } + + pub fn get_regions(&self) -> (Span, ty::Region<'tcx>, ty::Region<'tcx>) { + match (&self.error, self.regions) { + (&Some(ConcreteFailure(ref origin, sub, sup)), None) => (origin.span(), sub, sup), + (&Some(SubSupConflict(_, ref origin, sub, _, sup)), None) => (origin.span(), sub, sup), + (None, Some((span, sub, sup))) => (span, sub, sup), + (Some(_), Some(_)) => panic!("incorrectly built NiceRegionError"), + _ => panic!("trying to report on an incorrect lifetime failure"), + } } } diff --git a/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs index 9d0ddfd4be0..c106fd0c3d2 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs @@ -18,7 +18,7 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { /// When given a `ConcreteFailure` for a function with arguments containing a named region and /// an anonymous region, emit an descriptive diagnostic error. pub(super) fn try_report_named_anon_conflict(&self) -> Option<ErrorReported> { - let NiceRegionError { span, sub, sup, .. } = *self; + let (span, sub, sup) = self.get_regions(); debug!( "try_report_named_anon_conflict(sub={:?}, sup={:?})", @@ -118,4 +118,17 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { .emit(); return Some(ErrorReported); } + + // This method returns whether the given Region is Named + pub(super) fn is_named_region(&self, region: ty::Region<'tcx>) -> bool { + match *region { + ty::ReStatic => true, + ty::ReFree(ref free_region) => match free_region.bound_region { + ty::BrNamed(..) => true, + _ => false, + }, + ty::ReEarlyBound(_) => true, + _ => false, + } + } } diff --git a/src/librustc/infer/error_reporting/nice_region_error/outlives_closure.rs b/src/librustc/infer/error_reporting/nice_region_error/outlives_closure.rs new file mode 100644 index 00000000000..95f44b813c5 --- /dev/null +++ b/src/librustc/infer/error_reporting/nice_region_error/outlives_closure.rs @@ -0,0 +1,124 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Error Reporting for Anonymous Region Lifetime Errors +//! where both the regions are anonymous. + +use infer::error_reporting::nice_region_error::NiceRegionError; +use infer::SubregionOrigin; +use ty::RegionKind; +use hir::{Expr, ExprClosure}; +use hir::map::NodeExpr; +use util::common::ErrorReported; +use infer::lexical_region_resolve::RegionResolutionError::SubSupConflict; + +impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { + /// Print the error message for lifetime errors when binding excapes a closure. + /// + /// Consider a case where we have + /// + /// ```no_run + /// fn with_int<F>(f: F) where F: FnOnce(&isize) { + /// let x = 3; + /// f(&x); + /// } + /// fn main() { + /// let mut x = None; + /// with_int(|y| x = Some(y)); + /// } + /// ``` + /// + /// the output will be + /// + /// ```text + /// let mut x = None; + /// ----- borrowed data cannot be stored into here... + /// with_int(|y| x = Some(y)); + /// --- ^ cannot be stored outside of its closure + /// | + /// ...because it cannot outlive this closure + /// ``` + pub(super) fn try_report_outlives_closure(&self) -> Option<ErrorReported> { + if let Some(SubSupConflict(origin, + ref sub_origin, + _, + ref sup_origin, + sup_region)) = self.error { + + // #45983: when trying to assign the contents of an argument to a binding outside of a + // closure, provide a specific message pointing this out. + if let (&SubregionOrigin::BindingTypeIsNotValidAtDecl(ref external_span), + &RegionKind::ReFree(ref free_region)) = (&sub_origin, sup_region) { + let hir = &self.tcx.hir; + if let Some(node_id) = hir.as_local_node_id(free_region.scope) { + match hir.get(node_id) { + NodeExpr(Expr { + node: ExprClosure(_, _, _, closure_span, false), + .. + }) => { + let sup_sp = sup_origin.span(); + let origin_sp = origin.span(); + let mut err = self.tcx.sess.struct_span_err( + sup_sp, + "borrowed data cannot be stored outside of its closure"); + err.span_label(sup_sp, "cannot be stored outside of its closure"); + if origin_sp == sup_sp || origin_sp.contains(sup_sp) { +// // sup_sp == origin.span(): +// +// let mut x = None; +// ----- borrowed data cannot be stored into here... +// with_int(|y| x = Some(y)); +// --- ^ cannot be stored outside of its closure +// | +// ...because it cannot outlive this closure +// +// // origin.contains(&sup_sp): +// +// let mut f: Option<&u32> = None; +// ----- borrowed data cannot be stored into here... +// closure_expecting_bound(|x: &'x u32| { +// ------------ ... because it cannot outlive this closure +// f = Some(x); +// ^ cannot be stored outside of its closure + err.span_label(*external_span, + "borrowed data cannot be stored into here..."); + err.span_label(*closure_span, + "...because it cannot outlive this closure"); + } else { +// FIXME: the wording for this case could be much improved +// +// let mut lines_to_use: Vec<&CrateId> = Vec::new(); +// - cannot infer an appropriate lifetime... +// let push_id = |installed_id: &CrateId| { +// ------- ------------------------ borrowed data cannot outlive this closure +// | +// ...so that variable is valid at time of its declaration +// lines_to_use.push(installed_id); +// ^^^^^^^^^^^^ cannot be stored outside of its closure + err.span_label(origin_sp, + "cannot infer an appropriate lifetime..."); + err.span_label(*external_span, + "...so that variable is valid at time of its \ + declaration"); + err.span_label(*closure_span, + "borrowed data cannot outlive this closure"); + } + err.emit(); + return Some(ErrorReported); + } + _ => {} + } + } + } + } + None + } +} + diff --git a/src/librustc/infer/error_reporting/nice_region_error/util.rs b/src/librustc/infer/error_reporting/nice_region_error/util.rs index f8b6f7d0afa..8aadec64554 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/util.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/util.rs @@ -198,16 +198,4 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { } false } - - // This method returns whether the given Region is Named - pub(super) fn is_named_region(&self, region: Region<'tcx>) -> bool { - match *region { - ty::ReFree(ref free_region) => match free_region.bound_region { - ty::BrNamed(..) => true, - _ => false, - }, - ty::ReEarlyBound(_) => true, - _ => false, - } - } } diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 075ee0b8c7c..d727dfb0c4b 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -44,6 +44,7 @@ #![feature(box_syntax)] #![feature(conservative_impl_trait)] #![feature(const_fn)] +#![feature(copy_closures, clone_closures)] #![feature(core_intrinsics)] #![feature(drain_filter)] #![feature(dyn_trait)] diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 7410386c6f4..143d2c2ea28 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -127,7 +127,7 @@ declare_lint! { declare_lint! { pub PUB_USE_OF_PRIVATE_EXTERN_CRATE, Deny, - "detect public reexports of private extern crates" + "detect public re-exports of private extern crates" } declare_lint! { diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index f4abc54ad2e..b2a9859f68a 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -97,12 +97,13 @@ macro_rules! declare_lint { /// Declare a static `LintArray` and return it as an expression. #[macro_export] -macro_rules! lint_array { ($( $lint:expr ),*) => ( - { - static ARRAY: LintArray = &[ $( &$lint ),* ]; - ARRAY - } -) } +macro_rules! lint_array { + ($( $lint:expr ),*,) => { lint_array!( $( $lint ),* ) }; + ($( $lint:expr ),*) => {{ + static ARRAY: LintArray = &[ $( &$lint ),* ]; + ARRAY + }} +} pub type LintArray = &'static [&'static &'static Lint]; diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index 1376886968f..e2de0b6bd01 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -26,9 +26,9 @@ pub enum AccessLevel { // public, then type `T` is reachable. Its values can be obtained by other crates // even if the type itself is not nameable. Reachable, - // Public items + items accessible to other crates with help of `pub use` reexports + // Public items + items accessible to other crates with help of `pub use` re-exports Exported, - // Items accessible to other crates directly, without help of reexports + // Items accessible to other crates directly, without help of re-exports Public, } diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index 58067931d56..57ed41f2f06 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -277,6 +277,13 @@ macro_rules! make_mir_visitor { fn super_mir(&mut self, mir: & $($mutability)* Mir<'tcx>) { + if let Some(yield_ty) = &$($mutability)* mir.yield_ty { + self.visit_ty(yield_ty, TyContext::YieldTy(SourceInfo { + span: mir.span, + scope: ARGUMENT_VISIBILITY_SCOPE, + })); + } + // for best performance, we want to use an iterator rather // than a for-loop, to avoid calling Mir::invalidate for // each basic block. @@ -852,6 +859,8 @@ pub enum TyContext { /// The return type of the function. ReturnTy(SourceInfo), + YieldTy(SourceInfo), + /// A type found at some location. Location(Location), } diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 8c8108b0604..cd4e3cfed7a 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1045,6 +1045,8 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options, options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, build_debugging_options, "Z", "debugging", DB_OPTIONS, db_type_desc, dbsetters, + codegen_backend: Option<String> = (None, parse_opt_string, [TRACKED], + "the backend to use"), verbose: bool = (false, parse_bool, [UNTRACKED], "in general, enable more debug printouts"), span_free_formats: bool = (false, parse_bool, [UNTRACKED], @@ -1172,7 +1174,7 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "emit noalias metadata for mutable references"), dump_mir: Option<String> = (None, parse_opt_string, [UNTRACKED], "dump MIR state at various points in translation"), - dump_mir_dir: Option<String> = (None, parse_opt_string, [UNTRACKED], + dump_mir_dir: String = (String::from("mir_dump"), parse_string, [UNTRACKED], "the directory the MIR is dumped into"), dump_mir_graphviz: bool = (false, parse_bool, [UNTRACKED], "in addition to `.mir` files, create graphviz `.dot` files"), @@ -1236,6 +1238,9 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, overriding the default for the current target"), human_readable_cgu_names: bool = (false, parse_bool, [TRACKED], "generate human-readable, predictable names for codegen units"), + dep_info_omit_d_target: bool = (false, parse_bool, [TRACKED], + "in dep-info output, omit targets for tracking dependencies of the dep-info files \ + themselves"), } pub fn default_lib_output() -> CrateType { @@ -2793,7 +2798,7 @@ mod tests { assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash()); opts.debugging_opts.dump_mir = Some(String::from("abc")); assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash()); - opts.debugging_opts.dump_mir_dir = Some(String::from("abc")); + opts.debugging_opts.dump_mir_dir = String::from("abc"); assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash()); opts.debugging_opts.dump_mir_graphviz = true; assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash()); diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 3ae7d01823c..94fcfb7e2aa 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -11,7 +11,7 @@ pub use self::code_stats::{CodeStats, DataTypeKind, FieldInfo}; pub use self::code_stats::{SizeKind, TypeSizeInfo, VariantInfo}; -use hir::def_id::{CrateNum, DefIndex}; +use hir::def_id::CrateNum; use ich::Fingerprint; use lint; @@ -558,18 +558,16 @@ impl Session { /// Returns the symbol name for the registrar function, /// given the crate Svh and the function DefIndex. - pub fn generate_plugin_registrar_symbol(&self, disambiguator: CrateDisambiguator, - index: DefIndex) + pub fn generate_plugin_registrar_symbol(&self, + disambiguator: CrateDisambiguator) -> String { - format!("__rustc_plugin_registrar__{}_{}", disambiguator.to_fingerprint().to_hex(), - index.to_proc_macro_index()) + format!("__rustc_plugin_registrar_{}__", disambiguator.to_fingerprint().to_hex()) } - pub fn generate_derive_registrar_symbol(&self, disambiguator: CrateDisambiguator, - index: DefIndex) + pub fn generate_derive_registrar_symbol(&self, + disambiguator: CrateDisambiguator) -> String { - format!("__rustc_derive_registrar__{}_{}", disambiguator.to_fingerprint().to_hex(), - index.to_proc_macro_index()) + format!("__rustc_derive_registrar_{}__", disambiguator.to_fingerprint().to_hex()) } pub fn sysroot<'a>(&'a self) -> &'a Path { diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 54da23821f5..e649f1b49df 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -717,93 +717,40 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self.tcx.hir.span_if_local(did) }).map(|sp| self.tcx.sess.codemap().def_span(sp)); // the sp could be an fn def - let found_ty_count = - match found_trait_ref.skip_binder().substs.type_at(1).sty { - ty::TyTuple(ref tys, _) => tys.len(), - _ => 1, - }; - let (expected_tys, expected_ty_count) = - match expected_trait_ref.skip_binder().substs.type_at(1).sty { - ty::TyTuple(ref tys, _) => - (tys.iter().map(|t| &t.sty).collect(), tys.len()), - ref sty => (vec![sty], 1), - }; - if found_ty_count == expected_ty_count { + let found = match found_trait_ref.skip_binder().substs.type_at(1).sty { + ty::TyTuple(ref tys, _) => tys.iter() + .map(|_| ArgKind::empty()).collect::<Vec<_>>(), + _ => vec![ArgKind::empty()], + }; + let expected = match expected_trait_ref.skip_binder().substs.type_at(1).sty { + ty::TyTuple(ref tys, _) => tys.iter() + .map(|t| match t.sty { + ty::TypeVariants::TyTuple(ref tys, _) => ArgKind::Tuple( + span, + tys.iter() + .map(|ty| ("_".to_owned(), format!("{}", ty.sty))) + .collect::<Vec<_>>() + ), + _ => ArgKind::Arg("_".to_owned(), format!("{}", t.sty)), + }).collect(), + ref sty => vec![ArgKind::Arg("_".to_owned(), format!("{}", sty))], + }; + if found.len()== expected.len() { self.report_closure_arg_mismatch(span, found_span, found_trait_ref, expected_trait_ref) } else { - let expected_tuple = if expected_ty_count == 1 { - expected_tys.first().and_then(|t| { - if let &&ty::TyTuple(ref tuptys, _) = t { - Some(tuptys.len()) - } else { - None - } - }) - } else { - None - }; - - // FIXME(#44150): Expand this to "N args expected but a N-tuple found." - // Type of the 1st expected argument is somehow provided as type of a - // found one in that case. - // - // ``` - // [1i32, 2, 3].sort_by(|(a, b)| ..) - // // ^^^^^^^ -------- - // // expected_trait_ref: std::ops::FnMut<(&i32, &i32)> - // // found_trait_ref: std::ops::FnMut<(&i32,)> - // ``` - - let (closure_span, closure_args) = found_did + let (closure_span, found) = found_did .and_then(|did| self.tcx.hir.get_if_local(did)) - .and_then(|node| { - if let hir::map::NodeExpr( - &hir::Expr { - node: hir::ExprClosure(_, ref decl, id, span, _), - .. - }) = node - { - let ty_snips = decl.inputs.iter() - .map(|ty| { - self.tcx.sess.codemap().span_to_snippet(ty.span).ok() - .and_then(|snip| { - // filter out dummy spans - if snip == "," || snip == "|" { - None - } else { - Some(snip) - } - }) - }) - .collect::<Vec<Option<String>>>(); - - let body = self.tcx.hir.body(id); - let pat_snips = body.arguments.iter() - .map(|arg| - self.tcx.sess.codemap().span_to_snippet(arg.pat.span).ok()) - .collect::<Option<Vec<String>>>(); - - Some((span, pat_snips, ty_snips)) - } else { - None - } - }) - .map(|(span, pat, ty)| (Some(span), Some((pat, ty)))) - .unwrap_or((None, None)); - let closure_args = closure_args.and_then(|(pat, ty)| Some((pat?, ty))); - - self.report_arg_count_mismatch( - span, - closure_span.or(found_span), - expected_ty_count, - expected_tuple, - found_ty_count, - closure_args, - found_trait_ty.is_closure() - ) + .map(|node| self.get_fn_like_arguments(node)) + .unwrap_or((found_span.unwrap(), found)); + + self.report_arg_count_mismatch(span, + closure_span, + expected, + found, + found_trait_ty.is_closure()) } } @@ -845,94 +792,135 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } } + fn get_fn_like_arguments(&self, node: hir::map::Node) -> (Span, Vec<ArgKind>) { + if let hir::map::NodeExpr(&hir::Expr { + node: hir::ExprClosure(_, ref _decl, id, span, _), + .. + }) = node { + (self.tcx.sess.codemap().def_span(span), self.tcx.hir.body(id).arguments.iter() + .map(|arg| { + if let hir::Pat { + node: hir::PatKind::Tuple(args, _), + span, + .. + } = arg.pat.clone().into_inner() { + ArgKind::Tuple( + span, + args.iter().map(|pat| { + let snippet = self.tcx.sess.codemap() + .span_to_snippet(pat.span).unwrap(); + (snippet, "_".to_owned()) + }).collect::<Vec<_>>(), + ) + } else { + let name = self.tcx.sess.codemap().span_to_snippet(arg.pat.span).unwrap(); + ArgKind::Arg(name, "_".to_owned()) + } + }) + .collect::<Vec<ArgKind>>()) + } else if let hir::map::NodeItem(&hir::Item { + span, + node: hir::ItemFn(ref decl, ..), + .. + }) = node { + (self.tcx.sess.codemap().def_span(span), decl.inputs.iter() + .map(|arg| match arg.clone().into_inner().node { + hir::TyTup(ref tys) => ArgKind::Tuple( + arg.span, + tys.iter() + .map(|_| ("_".to_owned(), "_".to_owned())) + .collect::<Vec<_>>(), + ), + _ => ArgKind::Arg("_".to_owned(), "_".to_owned()) + }).collect::<Vec<ArgKind>>()) + } else { + panic!("non-FnLike node found: {:?}", node); + } + } + fn report_arg_count_mismatch( &self, span: Span, - found_span: Option<Span>, - expected: usize, - expected_tuple: Option<usize>, - found: usize, - closure_args: Option<(Vec<String>, Vec<Option<String>>)>, - is_closure: bool + found_span: Span, + expected_args: Vec<ArgKind>, + found_args: Vec<ArgKind>, + is_closure: bool, ) -> DiagnosticBuilder<'tcx> { - use std::borrow::Cow; - let kind = if is_closure { "closure" } else { "function" }; - let args_str = |n, distinct| format!( - "{} {}argument{}", - n, - if distinct && n >= 2 { "distinct " } else { "" }, - if n == 1 { "" } else { "s" }, - ); - - let expected_str = if let Some(n) = expected_tuple { - assert!(expected == 1); - if closure_args.as_ref().map(|&(ref pats, _)| pats.len()) == Some(n) { - Cow::from("a single tuple as argument") - } else { - // be verbose when numbers differ - Cow::from(format!("a single {}-tuple as argument", n)) + let args_str = |arguments: &Vec<ArgKind>, other: &Vec<ArgKind>| { + let arg_length = arguments.len(); + let distinct = match &other[..] { + &[ArgKind::Tuple(..)] => true, + _ => false, + }; + match (arg_length, arguments.get(0)) { + (1, Some(&ArgKind::Tuple(_, ref fields))) => { + format!("a single {}-tuple as argument", fields.len()) + } + _ => format!("{} {}argument{}", + arg_length, + if distinct && arg_length > 1 { "distinct " } else { "" }, + if arg_length == 1 { "" } else { "s" }), } - } else { - Cow::from(args_str(expected, false)) }; - let found_str = if expected_tuple.is_some() { - args_str(found, true) - } else { - args_str(found, false) - }; + let expected_str = args_str(&expected_args, &found_args); + let found_str = args_str(&found_args, &expected_args); - - let mut err = struct_span_err!(self.tcx.sess, span, E0593, + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0593, "{} is expected to take {}, but it takes {}", kind, expected_str, found_str, ); - err.span_label( - span, - format!( - "expected {} that takes {}", - kind, - expected_str, - ) - ); - - if let Some(span) = found_span { - if let (Some(expected_tuple), Some((pats, tys))) = (expected_tuple, closure_args) { - if expected_tuple != found || pats.len() != found { - err.span_label(span, format!("takes {}", found_str)); - } else { - let sugg = format!( - "|({}){}|", - pats.join(", "), - - // add type annotations if available - if tys.iter().any(|ty| ty.is_some()) { - Cow::from(format!( - ": ({})", - tys.into_iter().map(|ty| if let Some(ty) = ty { - ty - } else { - "_".to_string() - }).collect::<Vec<String>>().join(", ") - )) - } else { - Cow::from("") - }, - ); - - err.span_suggestion( - span, - "consider changing the closure to accept a tuple", - sugg - ); - } - } else { - err.span_label(span, format!("takes {}", found_str)); + err.span_label(span, format!( "expected {} that takes {}", kind, expected_str)); + err.span_label(found_span, format!("takes {}", found_str)); + + if let &[ArgKind::Tuple(_, ref fields)] = &found_args[..] { + if fields.len() == expected_args.len() { + let sugg = fields.iter() + .map(|(name, _)| name.to_owned()) + .collect::<Vec<String>>().join(", "); + err.span_suggestion(found_span, + "change the closure to take multiple arguments instead of \ + a single tuple", + format!("|{}|", sugg)); + } + } + if let &[ArgKind::Tuple(_, ref fields)] = &expected_args[..] { + if fields.len() == found_args.len() && is_closure { + let sugg = format!( + "|({}){}|", + found_args.iter() + .map(|arg| match arg { + ArgKind::Arg(name, _) => name.to_owned(), + _ => "_".to_owned(), + }) + .collect::<Vec<String>>() + .join(", "), + // add type annotations if available + if found_args.iter().any(|arg| match arg { + ArgKind::Arg(_, ty) => ty != "_", + _ => false, + }) { + format!(": ({})", + fields.iter() + .map(|(_, ty)| ty.to_owned()) + .collect::<Vec<String>>() + .join(", ")) + } else { + "".to_owned() + }, + ); + err.span_suggestion(found_span, + "change the closure to accept a tuple instead of individual \ + arguments", + sugg); } } @@ -1241,7 +1229,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } ObligationCauseCode::ItemObligation(item_def_id) => { let item_name = tcx.item_path_str(item_def_id); - err.note(&format!("required by `{}`", item_name)); + let msg = format!("required by `{}`", item_name); + if let Some(sp) = tcx.hir.span_if_local(item_def_id) { + let sp = tcx.sess.codemap().def_span(sp); + err.span_note(sp, &msg); + } else { + err.note(&msg); + } } ObligationCauseCode::ObjectCastObligation(object_ty) => { err.note(&format!("required for the cast to the object type `{}`", @@ -1325,3 +1319,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { suggested_limit)); } } + +enum ArgKind { + Arg(String, String), + Tuple(Span, Vec<(String, String)>), +} + +impl ArgKind { + fn empty() -> ArgKind { + ArgKind::Arg("_".to_owned(), "_".to_owned()) + } +} diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 81444bc09f2..12343207476 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1516,8 +1516,9 @@ bitflags! { const IS_C = 1 << 0; const IS_PACKED = 1 << 1; const IS_SIMD = 1 << 2; + const IS_TRANSPARENT = 1 << 3; // Internal only for now. If true, don't reorder fields. - const IS_LINEAR = 1 << 3; + const IS_LINEAR = 1 << 4; // Any of these flags being set prevent field reordering optimisation. const IS_UNOPTIMISABLE = ReprFlags::IS_C.bits | @@ -1557,6 +1558,7 @@ impl ReprOptions { flags.insert(match r { attr::ReprC => ReprFlags::IS_C, attr::ReprPacked => ReprFlags::IS_PACKED, + attr::ReprTransparent => ReprFlags::IS_TRANSPARENT, attr::ReprSimd => ReprFlags::IS_SIMD, attr::ReprInt(i) => { size = Some(i); @@ -1584,6 +1586,8 @@ impl ReprOptions { #[inline] pub fn packed(&self) -> bool { self.flags.contains(ReprFlags::IS_PACKED) } #[inline] + pub fn transparent(&self) -> bool { self.flags.contains(ReprFlags::IS_TRANSPARENT) } + #[inline] pub fn linear(&self) -> bool { self.flags.contains(ReprFlags::IS_LINEAR) } pub fn discr_type(&self) -> attr::IntType { diff --git a/src/librustc_apfloat/ieee.rs b/src/librustc_apfloat/ieee.rs index 3e76b60b84a..7abd02b6656 100644 --- a/src/librustc_apfloat/ieee.rs +++ b/src/librustc_apfloat/ieee.rs @@ -1434,7 +1434,7 @@ impl<S: Semantics> Float for IeeeFloat<S> { let max_change = S::MAX_EXP as i32 - (S::MIN_EXP as i32 - sig_bits) + 1; // Clamp to one past the range ends to let normalize handle overflow. - let exp_change = cmp::min(cmp::max(exp as i32, (-max_change - 1)), max_change); + let exp_change = cmp::min(cmp::max(exp as i32, -max_change - 1), max_change); self.exp = self.exp.saturating_add(exp_change as ExpInt); self = self.normalize(round, Loss::ExactlyZero).value; if self.is_nan() { diff --git a/src/librustc_back/target/aarch64_unknown_cloudabi.rs b/src/librustc_back/target/aarch64_unknown_cloudabi.rs index d5e8194c3f7..59c82e06a67 100644 --- a/src/librustc_back/target/aarch64_unknown_cloudabi.rs +++ b/src/librustc_back/target/aarch64_unknown_cloudabi.rs @@ -15,6 +15,7 @@ pub fn target() -> TargetResult { let mut base = super::cloudabi_base::opts(); base.max_atomic_width = Some(128); base.abi_blacklist = super::arm_base::abi_blacklist(); + base.linker = "aarch64-unknown-cloudabi-cc".to_string(); Ok(Target { llvm_target: "aarch64-unknown-cloudabi".to_string(), diff --git a/src/librustc_back/target/armv7_unknown_cloudabi_eabihf.rs b/src/librustc_back/target/armv7_unknown_cloudabi_eabihf.rs index 4dad8e1713b..faa2c4fdceb 100644 --- a/src/librustc_back/target/armv7_unknown_cloudabi_eabihf.rs +++ b/src/librustc_back/target/armv7_unknown_cloudabi_eabihf.rs @@ -17,6 +17,7 @@ pub fn target() -> TargetResult { base.max_atomic_width = Some(64); base.features = "+v7,+vfp3,+neon".to_string(); base.abi_blacklist = super::arm_base::abi_blacklist(); + base.linker = "armv7-unknown-cloudabi-eabihf-cc".to_string(); Ok(Target { llvm_target: "armv7-unknown-cloudabi-eabihf".to_string(), diff --git a/src/librustc_back/target/i686_unknown_cloudabi.rs b/src/librustc_back/target/i686_unknown_cloudabi.rs index b9aa6176d87..e244f443d3e 100644 --- a/src/librustc_back/target/i686_unknown_cloudabi.rs +++ b/src/librustc_back/target/i686_unknown_cloudabi.rs @@ -15,6 +15,7 @@ pub fn target() -> TargetResult { let mut base = super::cloudabi_base::opts(); base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); + base.linker = "i686-unknown-cloudabi-cc".to_string(); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); base.stack_probes = true; diff --git a/src/librustc_back/target/windows_base.rs b/src/librustc_back/target/windows_base.rs index e6aa745d54e..cc40b8b0529 100644 --- a/src/librustc_back/target/windows_base.rs +++ b/src/librustc_back/target/windows_base.rs @@ -59,6 +59,15 @@ pub fn opts() -> TargetOptions { "-lmingw32".to_string(), "-lgcc".to_string(), // alas, mingw* libraries above depend on libgcc "-lmsvcrt".to_string(), + // mingw's msvcrt is a weird hybrid import library and static library. + // And it seems that the linker fails to use import symbols from msvcrt + // that are required from functions in msvcrt in certain cases. For example + // `_fmode` that is used by an implementation of `__p__fmode` in x86_64. + // Listing the library twice seems to fix that, and seems to also be done + // by mingw's gcc (Though not sure if it's done on purpose, or by mistake). + // + // See https://github.com/rust-lang/rust/pull/47483 + "-lmsvcrt".to_string(), "-luser32".to_string(), "-lkernel32".to_string(), ]); diff --git a/src/librustc_back/target/x86_64_unknown_cloudabi.rs b/src/librustc_back/target/x86_64_unknown_cloudabi.rs index f9a563174d4..1ce3c6444f1 100644 --- a/src/librustc_back/target/x86_64_unknown_cloudabi.rs +++ b/src/librustc_back/target/x86_64_unknown_cloudabi.rs @@ -15,6 +15,7 @@ pub fn target() -> TargetResult { let mut base = super::cloudabi_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); + base.linker = "x86_64-unknown-cloudabi-cc".to_string(); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); base.stack_probes = true; diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 4529e4bab75..d003ef74f05 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -842,10 +842,32 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { if let mc::NoteClosureEnv(upvar_id) = err.cmt.note { let node_id = self.tcx.hir.hir_to_node_id(upvar_id.var_id); let sp = self.tcx.hir.span(node_id); - match self.tcx.sess.codemap().span_to_snippet(sp) { - Ok(snippet) => { + let fn_closure_msg = "`Fn` closures cannot capture their enclosing \ + environment for modifications"; + match (self.tcx.sess.codemap().span_to_snippet(sp), &err.cmt.cat) { + (_, &Categorization::Upvar(mc::Upvar { + kind: ty::ClosureKind::Fn, .. + })) => { + db.note(fn_closure_msg); + // we should point at the cause for this closure being + // identified as `Fn` (like in signature of method this + // closure was passed into) + } + (Ok(ref snippet), ref cat) => { let msg = &format!("consider making `{}` mutable", snippet); - db.span_suggestion(sp, msg, format!("mut {}", snippet)); + let suggestion = format!("mut {}", snippet); + + if let &Categorization::Deref(ref cmt, _) = cat { + if let Categorization::Upvar(mc::Upvar { + kind: ty::ClosureKind::Fn, .. + }) = cmt.cat { + db.note(fn_closure_msg); + } else { + db.span_suggestion(sp, msg, suggestion); + } + } else { + db.span_suggestion(sp, msg, suggestion); + } } _ => { db.span_help(sp, "consider making this binding mutable"); diff --git a/src/librustc_const_eval/_match.rs b/src/librustc_const_eval/_match.rs index 33d9bfa6e6b..a7c382eba50 100644 --- a/src/librustc_const_eval/_match.rs +++ b/src/librustc_const_eval/_match.rs @@ -561,19 +561,25 @@ fn max_slice_length<'p, 'a: 'p, 'tcx: 'a, I>( /// (1) all_constructors will only return constructors that are statically /// possible. eg. it will only return Ok for Result<T, !> /// -/// Whether a vector `v` of patterns is 'useful' in relation to a set of such -/// vectors `m` is defined as there being a set of inputs that will match `v` -/// but not any of the sets in `m`. +/// This finds whether a (row) vector `v` of patterns is 'useful' in relation +/// to a set of such vectors `m` - this is defined as there being a set of +/// inputs that will match `v` but not any of the sets in `m`. +/// +/// All the patterns at each column of the `matrix ++ v` matrix must +/// have the same type, except that wildcard (PatternKind::Wild) patterns +/// with type TyErr are also allowed, even if the "type of the column" +/// is not TyErr. That is used to represent private fields, as using their +/// real type would assert that they are inhabited. /// /// This is used both for reachability checking (if a pattern isn't useful in /// relation to preceding patterns, it is not reachable) and exhaustiveness /// checking (if a wildcard pattern is useful in relation to a matrix, the /// matrix isn't exhaustive). pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>, - matrix: &Matrix<'p, 'tcx>, - v: &[&'p Pattern<'tcx>], - witness: WitnessPreference) - -> Usefulness<'tcx> { + matrix: &Matrix<'p, 'tcx>, + v: &[&'p Pattern<'tcx>], + witness: WitnessPreference) + -> Usefulness<'tcx> { let &Matrix(ref rows) = matrix; debug!("is_useful({:?}, {:?})", matrix, v); @@ -596,6 +602,25 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>, assert!(rows.iter().all(|r| r.len() == v.len())); let pcx = PatternContext { + // TyErr is used to represent the type of wildcard patterns matching + // against inaccessible (private) fields of structs, so that we won't + // be able to observe whether the types of the struct's fields are + // inhabited. + // + // If the field is truely inaccessible, then all the patterns + // matching against it must be wildcard patterns, so its type + // does not matter. + // + // However, if we are matching against non-wildcard patterns, we + // need to know the real type of the field so we can specialize + // against it. This primarily occurs through constants - they + // can include contents for fields that are inaccessible at the + // location of the match. In that case, the field's type is + // inhabited - by the constant - so we can just use it. + // + // FIXME: this might lead to "unstable" behavior with macro hygiene + // introducing uninhabited patterns for inaccessible fields. We + // need to figure out how to model that. ty: rows.iter().map(|r| r[0].ty).find(|ty| !ty.references_error()) .unwrap_or(v[0].ty), max_slice_length: max_slice_length(cx, rows.iter().map(|r| r[0]).chain(Some(v[0]))) @@ -861,13 +886,13 @@ fn constructor_sub_pattern_tys<'a, 'tcx: 'a>(cx: &MatchCheckCtxt<'a, 'tcx>, if is_visible { field.ty(cx.tcx, substs) } else { - // Treat all non-visible fields as nil. They + // Treat all non-visible fields as TyErr. They // can't appear in any other pattern from // this match (because they are private), // so their type does not matter - but // we don't want to know they are // uninhabited. - cx.tcx.mk_nil() + cx.tcx.types.err } }).collect() } diff --git a/src/librustc_data_structures/array_vec.rs b/src/librustc_data_structures/array_vec.rs index 57fc78ef531..511c407d45a 100644 --- a/src/librustc_data_structures/array_vec.rs +++ b/src/librustc_data_structures/array_vec.rs @@ -12,7 +12,7 @@ use std::marker::Unsize; use std::iter::Extend; -use std::ptr::{self, drop_in_place, Shared}; +use std::ptr::{self, drop_in_place, NonNull}; use std::ops::{Deref, DerefMut, Range}; use std::hash::{Hash, Hasher}; use std::slice; @@ -146,7 +146,7 @@ impl<A: Array> ArrayVec<A> { tail_start: end, tail_len: len - end, iter: range_slice.iter(), - array_vec: Shared::from(self), + array_vec: NonNull::from(self), } } } @@ -232,7 +232,7 @@ pub struct Drain<'a, A: Array> tail_start: usize, tail_len: usize, iter: slice::Iter<'a, ManuallyDrop<A::Element>>, - array_vec: Shared<ArrayVec<A>>, + array_vec: NonNull<ArrayVec<A>>, } impl<'a, A: Array> Iterator for Drain<'a, A> { diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 24048e606df..a35ef2f7ce7 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -21,7 +21,6 @@ html_root_url = "https://doc.rust-lang.org/nightly/")] #![deny(warnings)] -#![feature(shared)] #![feature(collections_range)] #![feature(nonzero)] #![feature(unboxed_closures)] diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 73c1b698087..468a08b1fd9 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -31,16 +31,14 @@ use rustc_incremental; use rustc_resolve::{MakeGlobMap, Resolver}; use rustc_metadata::creader::CrateLoader; use rustc_metadata::cstore::{self, CStore}; -use rustc_trans as trans; use rustc_trans_utils::trans_crate::TransCrate; use rustc_typeck as typeck; use rustc_privacy; use rustc_plugin::registry::Registry; use rustc_plugin as plugin; -use rustc_passes::{self, ast_validation, no_asm, loops, consts, static_recursion, hir_stats}; +use rustc_passes::{self, ast_validation, loops, consts, static_recursion, hir_stats}; use rustc_const_eval::{self, check_match}; use super::Compilation; -use ::DefaultTransCrate; use serialize::json; @@ -68,7 +66,8 @@ use pretty::ReplaceBodyWithLoop; use profile; -pub fn compile_input(sess: &Session, +pub fn compile_input(trans: Box<TransCrate>, + sess: &Session, cstore: &CStore, input_path: &Option<PathBuf>, input: &Input, @@ -76,8 +75,6 @@ pub fn compile_input(sess: &Session, output: &Option<PathBuf>, addl_plugins: Option<Vec<String>>, control: &CompileController) -> CompileResult { - use rustc::session::config::CrateType; - macro_rules! controller_entry_point { ($point: ident, $tsess: expr, $make_state: expr, $phase_result: expr) => {{ let state = &mut $make_state; @@ -94,22 +91,6 @@ pub fn compile_input(sess: &Session, }} } - if cfg!(not(feature="llvm")) { - for cty in sess.opts.crate_types.iter() { - match *cty { - CrateType::CrateTypeRlib | CrateType::CrateTypeDylib | - CrateType::CrateTypeExecutable => {}, - _ => { - sess.parse_sess.span_diagnostic.warn( - &format!("LLVM unsupported, so output type {} is not supported", cty) - ); - }, - } - } - - sess.abort_if_errors(); - } - if sess.profile_queries() { profile::begin(); } @@ -117,7 +98,7 @@ pub fn compile_input(sess: &Session, // We need nested scopes here, because the intermediate results can keep // large chunks of memory alive and we want to free them as soon as // possible to keep the peak memory usage low - let (outputs, trans, dep_graph) = { + let (outputs, ongoing_trans, dep_graph) = { let krate = match phase_1_parse_input(control, sess, input) { Ok(krate) => krate, Err(mut parse_error) => { @@ -217,7 +198,8 @@ pub fn compile_input(sess: &Session, None }; - phase_3_run_analysis_passes(control, + phase_3_run_analysis_passes(&*trans, + control, sess, cstore, hir_map, @@ -254,7 +236,7 @@ pub fn compile_input(sess: &Session, tcx.print_debug_stats(); } - let trans = phase_4_translate_to_llvm::<DefaultTransCrate>(tcx, rx); + let ongoing_trans = phase_4_translate_to_llvm(&*trans, tcx, rx); if log_enabled!(::log::Level::Info) { println!("Post-trans"); @@ -268,7 +250,7 @@ pub fn compile_input(sess: &Session, } } - Ok((outputs.clone(), trans, tcx.dep_graph.clone())) + Ok((outputs.clone(), ongoing_trans, tcx.dep_graph.clone())) })?? }; @@ -276,25 +258,7 @@ pub fn compile_input(sess: &Session, sess.code_stats.borrow().print_type_sizes(); } - let (phase5_result, trans) = - phase_5_run_llvm_passes::<DefaultTransCrate>(sess, &dep_graph, trans); - - controller_entry_point!(after_llvm, - sess, - CompileState::state_after_llvm(input, sess, outdir, output, &trans), - phase5_result); - phase5_result?; - - // Run the linker on any artifacts that resulted from the LLVM run. - // This should produce either a finished executable or library. - time(sess.time_passes(), "linking", || { - DefaultTransCrate::link_binary(sess, &trans, &outputs) - }); - - // Now that we won't touch anything in the incremental compilation directory - // any more, we can finalize it (which involves renaming it) - #[cfg(feature="llvm")] - rustc_incremental::finalize_session_directory(sess, trans.link.crate_hash); + trans.join_trans_and_link(ongoing_trans, sess, &dep_graph, &outputs)?; if sess.opts.debugging_opts.perf_stats { sess.print_perf_stats(); @@ -340,7 +304,6 @@ pub struct CompileController<'a> { pub after_expand: PhaseController<'a>, pub after_hir_lowering: PhaseController<'a>, pub after_analysis: PhaseController<'a>, - pub after_llvm: PhaseController<'a>, pub compilation_done: PhaseController<'a>, // FIXME we probably want to group the below options together and offer a @@ -366,7 +329,6 @@ impl<'a> CompileController<'a> { after_expand: PhaseController::basic(), after_hir_lowering: PhaseController::basic(), after_analysis: PhaseController::basic(), - after_llvm: PhaseController::basic(), compilation_done: PhaseController::basic(), make_glob_map: MakeGlobMap::No, keep_ast: false, @@ -415,7 +377,6 @@ pub struct CompileState<'a, 'tcx: 'a> { pub resolutions: Option<&'a Resolutions>, pub analysis: Option<&'a ty::CrateAnalysis>, pub tcx: Option<TyCtxt<'a, 'tcx, 'tcx>>, - pub trans: Option<&'a trans::CrateTranslation>, } impl<'a, 'tcx> CompileState<'a, 'tcx> { @@ -440,7 +401,6 @@ impl<'a, 'tcx> CompileState<'a, 'tcx> { resolutions: None, analysis: None, tcx: None, - trans: None, } } @@ -528,19 +488,6 @@ impl<'a, 'tcx> CompileState<'a, 'tcx> { } } - fn state_after_llvm(input: &'a Input, - session: &'tcx Session, - out_dir: &'a Option<PathBuf>, - out_file: &'a Option<PathBuf>, - trans: &'a trans::CrateTranslation) - -> Self { - CompileState { - trans: Some(trans), - out_file: out_file.as_ref().map(|s| &**s), - ..CompileState::empty(input, session, out_dir) - } - } - fn state_when_compilation_done(input: &'a Input, session: &'tcx Session, out_dir: &'a Option<PathBuf>, @@ -853,10 +800,6 @@ pub fn phase_2_configure_and_expand<F>(sess: &Session, } time(time_passes, - "checking for inline asm in case the target doesn't support it", - || no_asm::check_crate(sess, &krate)); - - time(time_passes, "AST validation", || ast_validation::check_crate(sess, &krate)); @@ -937,7 +880,6 @@ pub fn default_provide(providers: &mut ty::maps::Providers) { reachable::provide(providers); resolve_lifetime::provide(providers); rustc_privacy::provide(providers); - DefaultTransCrate::provide(providers); typeck::provide(providers); ty::provide(providers); traits::provide(providers); @@ -951,13 +893,13 @@ pub fn default_provide(providers: &mut ty::maps::Providers) { pub fn default_provide_extern(providers: &mut ty::maps::Providers) { cstore::provide_extern(providers); - DefaultTransCrate::provide_extern(providers); } /// Run the resolution, typechecking, region checking and other /// miscellaneous analysis passes on the crate. Return various /// structures carrying the results of the analysis. -pub fn phase_3_run_analysis_passes<'tcx, F, R>(control: &CompileController, +pub fn phase_3_run_analysis_passes<'tcx, F, R>(trans: &TransCrate, + control: &CompileController, sess: &'tcx Session, cstore: &'tcx CrateStore, hir_map: hir_map::Map<'tcx>, @@ -1010,10 +952,12 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(control: &CompileController, let mut local_providers = ty::maps::Providers::default(); default_provide(&mut local_providers); + trans.provide(&mut local_providers); (control.provide)(&mut local_providers); let mut extern_providers = local_providers; default_provide_extern(&mut extern_providers); + trans.provide_extern(&mut extern_providers); (control.provide_extern)(&mut extern_providers); let (tx, rx) = mpsc::channel(); @@ -1105,9 +1049,10 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(control: &CompileController, /// Run the translation phase to LLVM, after which the AST and analysis can /// be discarded. -pub fn phase_4_translate_to_llvm<'a, 'tcx, Trans: TransCrate>(tcx: TyCtxt<'a, 'tcx, 'tcx>, +pub fn phase_4_translate_to_llvm<'a, 'tcx>(trans: &TransCrate, + tcx: TyCtxt<'a, 'tcx, 'tcx>, rx: mpsc::Receiver<Box<Any + Send>>) - -> <Trans as TransCrate>::OngoingCrateTranslation { + -> Box<Any> { let time_passes = tcx.sess.time_passes(); time(time_passes, @@ -1116,7 +1061,7 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx, Trans: TransCrate>(tcx: TyCtxt<'a, 't let translation = time(time_passes, "translation", move || { - Trans::trans_crate(tcx, rx) + trans.trans_crate(tcx, rx) }); if tcx.sess.profile_queries() { profile::dump("profile_queries".to_string()) @@ -1125,25 +1070,6 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx, Trans: TransCrate>(tcx: TyCtxt<'a, 't translation } -/// Run LLVM itself, producing a bitcode file, assembly file or object file -/// as a side effect. -pub fn phase_5_run_llvm_passes<Trans: TransCrate>(sess: &Session, - dep_graph: &DepGraph, - trans: <Trans as TransCrate>::OngoingCrateTranslation) - -> (CompileResult, <Trans as TransCrate>::TranslatedCrate) { - let trans = Trans::join_trans(trans, sess, dep_graph); - - if sess.opts.debugging_opts.incremental_info { - Trans::dump_incremental_data(&trans); - } - - time(sess.time_passes(), - "serialize work products", - move || rustc_incremental::save_work_products(sess, dep_graph)); - - (sess.compile_status(), trans) -} - fn escape_dep_filename(filename: &FileName) -> String { // Apparently clang and gcc *only* escape spaces: // http://llvm.org/klaus/clang/commit/9d50634cfc268ecc9a7250226dd5ca0e945240d4 @@ -1166,6 +1092,9 @@ fn write_out_deps(sess: &Session, outputs: &OutputFilenames, crate_name: &str) { out_filenames.push(p); } } + OutputType::DepInfo if sess.opts.debugging_opts.dep_info_omit_d_target => { + // Don't add the dep-info output when omitting it from dep-info targets + } _ => { out_filenames.push(file); } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 237656eb43c..de5559c8b14 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -48,7 +48,7 @@ extern crate rustc_mir; extern crate rustc_resolve; extern crate rustc_save_analysis; #[cfg(feature="llvm")] -extern crate rustc_trans; +pub extern crate rustc_trans; extern crate rustc_trans_utils; extern crate rustc_typeck; extern crate serialize; @@ -66,7 +66,7 @@ use rustc_save_analysis as save; use rustc_save_analysis::DumpHandler; use rustc::session::{self, config, Session, build_session, CompileResult}; use rustc::session::CompileIncomplete; -use rustc::session::config::{Input, PrintRequest, OutputType, ErrorOutputType}; +use rustc::session::config::{Input, PrintRequest, ErrorOutputType}; use rustc::session::config::nightly_options; use rustc::session::{early_error, early_warn}; use rustc::lint::Lint; @@ -106,9 +106,32 @@ mod test; pub mod profile; pub mod driver; pub mod pretty; -pub mod target_features; mod derive_registrar; +pub mod target_features { + use syntax::ast; + use syntax::symbol::Symbol; + use rustc::session::Session; + use rustc_trans_utils::trans_crate::TransCrate; + + /// Add `target_feature = "..."` cfgs for a variety of platform + /// specific features (SSE, NEON etc.). + /// + /// This is performed by checking whether a whitelisted set of + /// features is available on the target machine, by querying LLVM. + pub fn add_configuration(cfg: &mut ast::CrateConfig, sess: &Session, trans: &TransCrate) { + let tf = Symbol::intern("target_feature"); + + for feat in trans.target_features(sess) { + cfg.insert((tf, Some(feat))); + } + + if sess.crt_static_feature() { + cfg.insert((tf, Some(Symbol::intern("crt-static")))); + } + } +} + const BUG_REPORT_URL: &'static str = "https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.\ md#bug-reports"; @@ -159,25 +182,51 @@ pub use rustc_trans_utils::trans_crate::MetadataOnlyTransCrate as DefaultTransCr pub use rustc_trans::LlvmTransCrate as DefaultTransCrate; #[cfg(not(feature="llvm"))] -mod rustc_trans { - use syntax_pos::symbol::Symbol; - use rustc::session::Session; - use rustc::session::config::PrintRequest; +pub mod rustc_trans { pub use rustc_trans_utils::trans_crate::MetadataOnlyTransCrate as LlvmTransCrate; - pub use rustc_trans_utils::trans_crate::TranslatedCrate as CrateTranslation; - pub fn init(_sess: &Session) {} pub fn print_version() {} pub fn print_passes() {} - pub fn print(_req: PrintRequest, _sess: &Session) {} - pub fn target_features(_sess: &Session) -> Vec<Symbol> { vec![] } - - pub mod back { - pub mod write { - pub const RELOC_MODEL_ARGS: [(&'static str, ()); 0] = []; - pub const CODE_GEN_MODEL_ARGS: [(&'static str, ()); 0] = []; - pub const TLS_MODEL_ARGS: [(&'static str, ()); 0] = []; +} + +fn load_backend_from_dylib(sess: &Session, backend_name: &str) -> Box<TransCrate> { + use std::path::Path; + use rustc_metadata::dynamic_lib::DynamicLibrary; + + match DynamicLibrary::open(Some(Path::new(backend_name))) { + Ok(lib) => { + unsafe { + let trans = { + let __rustc_codegen_backend: unsafe fn(&Session) -> Box<TransCrate>; + __rustc_codegen_backend = match lib.symbol("__rustc_codegen_backend") { + Ok(f) => ::std::mem::transmute::<*mut u8, _>(f), + Err(e) => sess.fatal(&format!("Couldnt load codegen backend as it\ + doesn't export the __rustc_backend_new symbol: {:?}", e)), + }; + __rustc_codegen_backend(sess) + }; + ::std::mem::forget(lib); + trans + } + } + Err(err) => { + sess.fatal(&format!("Couldnt load codegen backend {:?}: {:?}", backend_name, err)); + } + } +} + +pub fn get_trans(sess: &Session) -> Box<TransCrate> { + let trans_name = sess.opts.debugging_opts.codegen_backend.clone(); + match trans_name.as_ref().map(|s|&**s) { + None => DefaultTransCrate::new(&sess), + Some("llvm") => rustc_trans::LlvmTransCrate::new(&sess), + Some("metadata_only") => { + rustc_trans_utils::trans_crate::MetadataOnlyTransCrate::new(&sess) + } + Some(filename) if filename.contains(".") => { + load_backend_from_dylib(&sess, &filename) } + Some(trans_name) => sess.fatal(&format!("Unknown codegen backend {}", trans_name)), } } @@ -222,30 +271,36 @@ pub fn run_compiler<'a>(args: &[String], }, }; - let cstore = CStore::new(DefaultTransCrate::metadata_loader()); - let loader = file_loader.unwrap_or(box RealFileLoader); let codemap = Rc::new(CodeMap::with_file_loader(loader, sopts.file_path_mapping())); let mut sess = session::build_session_with_codemap( sopts, input_file_path.clone(), descriptions, codemap, emitter_dest, ); - rustc_trans::init(&sess); + + let trans = get_trans(&sess); + rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); let mut cfg = config::build_configuration(&sess, cfg); - target_features::add_configuration(&mut cfg, &sess); + target_features::add_configuration(&mut cfg, &sess, &*trans); sess.parse_sess.config = cfg; - do_or_return!(callbacks.late_callback(&matches, + let plugins = sess.opts.debugging_opts.extra_plugins.clone(); + + let cstore = CStore::new(trans.metadata_loader()); + + do_or_return!(callbacks.late_callback(&*trans, + &matches, &sess, &cstore, &input, &odir, &ofile), Some(sess)); - let plugins = sess.opts.debugging_opts.extra_plugins.clone(); let control = callbacks.build_controller(&sess, &matches); - (driver::compile_input(&sess, + + (driver::compile_input(trans, + &sess, &cstore, &input_file_path, &input, @@ -338,6 +393,7 @@ pub trait CompilerCalls<'a> { // be called just before actual compilation starts (and before build_controller // is called), after all arguments etc. have been completely handled. fn late_callback(&mut self, + _: &TransCrate, _: &getopts::Matches, _: &Session, _: &CrateStore, @@ -517,13 +573,18 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls { let mut sess = build_session(sopts.clone(), None, descriptions.clone()); - rustc_trans::init(&sess); rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); let mut cfg = config::build_configuration(&sess, cfg.clone()); - target_features::add_configuration(&mut cfg, &sess); + let trans = get_trans(&sess); + target_features::add_configuration(&mut cfg, &sess, &*trans); sess.parse_sess.config = cfg; - let should_stop = - RustcDefaultCalls::print_crate_info(&sess, None, odir, ofile); + let should_stop = RustcDefaultCalls::print_crate_info( + &*trans, + &sess, + None, + odir, + ofile + ); if should_stop == Compilation::Stop { return None; @@ -536,6 +597,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls { } fn late_callback(&mut self, + trans: &TransCrate, matches: &getopts::Matches, sess: &Session, cstore: &CrateStore, @@ -543,7 +605,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls { odir: &Option<PathBuf>, ofile: &Option<PathBuf>) -> Compilation { - RustcDefaultCalls::print_crate_info(sess, Some(input), odir, ofile) + RustcDefaultCalls::print_crate_info(trans, sess, Some(input), odir, ofile) .and_then(|| RustcDefaultCalls::list_metadata(sess, cstore, matches, input)) } @@ -607,11 +669,6 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls { control.after_hir_lowering.stop = Compilation::Stop; } - if !sess.opts.output_types.keys().any(|&i| i == OutputType::Exe || - i == OutputType::Metadata) { - control.after_llvm.stop = Compilation::Stop; - } - if save_analysis(sess) { enable_save_analysis(&mut control); } @@ -681,11 +738,13 @@ impl RustcDefaultCalls { } - fn print_crate_info(sess: &Session, + fn print_crate_info(trans: &TransCrate, + sess: &Session, input: Option<&Input>, odir: &Option<PathBuf>, ofile: &Option<PathBuf>) -> Compilation { + use rustc::session::config::PrintRequest::*; // PrintRequest::NativeStaticLibs is special - printed during linking // (empty iterator returns true) if sess.opts.prints.iter().all(|&p| p==PrintRequest::NativeStaticLibs) { @@ -707,15 +766,14 @@ impl RustcDefaultCalls { }; for req in &sess.opts.prints { match *req { - PrintRequest::TargetList => { + TargetList => { let mut targets = rustc_back::target::get_targets().collect::<Vec<String>>(); targets.sort(); println!("{}", targets.join("\n")); }, - PrintRequest::Sysroot => println!("{}", sess.sysroot().display()), - PrintRequest::TargetSpec => println!("{}", sess.target.target.to_json().pretty()), - PrintRequest::FileNames | - PrintRequest::CrateName => { + Sysroot => println!("{}", sess.sysroot().display()), + TargetSpec => println!("{}", sess.target.target.to_json().pretty()), + FileNames | CrateName => { let input = match input { Some(input) => input, None => early_error(ErrorOutputType::default(), "no input file provided"), @@ -741,7 +799,7 @@ impl RustcDefaultCalls { .to_string_lossy()); } } - PrintRequest::Cfg => { + Cfg => { let allow_unstable_cfg = UnstableFeatures::from_environment() .is_nightly_build(); @@ -781,29 +839,8 @@ impl RustcDefaultCalls { println!("{}", cfg); } } - PrintRequest::RelocationModels => { - println!("Available relocation models:"); - for &(name, _) in rustc_trans::back::write::RELOC_MODEL_ARGS.iter() { - println!(" {}", name); - } - println!(""); - } - PrintRequest::CodeModels => { - println!("Available code models:"); - for &(name, _) in rustc_trans::back::write::CODE_GEN_MODEL_ARGS.iter(){ - println!(" {}", name); - } - println!(""); - } - PrintRequest::TlsModels => { - println!("Available TLS models:"); - for &(name, _) in rustc_trans::back::write::TLS_MODEL_ARGS.iter(){ - println!(" {}", name); - } - println!(""); - } - PrintRequest::TargetCPUs | PrintRequest::TargetFeatures => { - rustc_trans::print(*req, sess); + RelocationModels | CodeModels | TlsModels | TargetCPUs | TargetFeatures => { + trans.print(*req, sess); } // Any output here interferes with Cargo's parsing of other printed output PrintRequest::NativeStaticLibs => {} @@ -1281,6 +1318,7 @@ pub fn diagnostics_registry() -> errors::registry::Registry { all_errors.extend_from_slice(&rustc_privacy::DIAGNOSTICS); #[cfg(feature="llvm")] all_errors.extend_from_slice(&rustc_trans::DIAGNOSTICS); + all_errors.extend_from_slice(&rustc_trans_utils::DIAGNOSTICS); all_errors.extend_from_slice(&rustc_const_eval::DIAGNOSTICS); all_errors.extend_from_slice(&rustc_metadata::DIAGNOSTICS); all_errors.extend_from_slice(&rustc_passes::DIAGNOSTICS); diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 6ce6929af5c..af3d1e4d4d0 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -228,7 +228,8 @@ impl PpSourceMode { } PpmTyped => { let control = &driver::CompileController::basic(); - abort_on_err(driver::phase_3_run_analysis_passes(control, + abort_on_err(driver::phase_3_run_analysis_passes(&*::DefaultTransCrate::new(&sess), + control, sess, cstore, hir_map.clone(), @@ -1080,7 +1081,8 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session, let mut out = Vec::new(); let control = &driver::CompileController::basic(); - abort_on_err(driver::phase_3_run_analysis_passes(control, + abort_on_err(driver::phase_3_run_analysis_passes(&*::DefaultTransCrate::new(&sess), + control, sess, cstore, hir_map.clone(), diff --git a/src/librustc_driver/target_features.rs b/src/librustc_driver/target_features.rs deleted file mode 100644 index 96264472b5f..00000000000 --- a/src/librustc_driver/target_features.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use syntax::ast; -use rustc::session::Session; -use syntax::symbol::Symbol; -use rustc_trans; - -/// Add `target_feature = "..."` cfgs for a variety of platform -/// specific features (SSE, NEON etc.). -/// -/// This is performed by checking whether a whitelisted set of -/// features is available on the target machine, by querying LLVM. -pub fn add_configuration(cfg: &mut ast::CrateConfig, sess: &Session) { - let tf = Symbol::intern("target_feature"); - - for feat in rustc_trans::target_features(sess) { - cfg.insert((tf, Some(feat))); - } - - if sess.crt_static_feature() { - cfg.insert((tf, Some(Symbol::intern("crt-static")))); - } -} diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 371f0e79a3a..306e7e9c16d 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -16,7 +16,6 @@ use std::sync::mpsc; use driver; use rustc_lint; use rustc_resolve::MakeGlobMap; -use rustc_trans; use rustc::middle::region; use rustc::ty::subst::{Kind, Subst}; use rustc::traits::{ObligationCause, Reveal}; @@ -29,7 +28,6 @@ use rustc_metadata::cstore::CStore; use rustc::hir::map as hir_map; use rustc::session::{self, config}; use rustc::session::config::{OutputFilenames, OutputTypes}; -use rustc_trans_utils::trans_crate::TransCrate; use std::rc::Rc; use syntax::ast; use syntax::abi::Abi; @@ -104,12 +102,11 @@ fn test_env<F>(source_string: &str, options.unstable_features = UnstableFeatures::Allow; let diagnostic_handler = errors::Handler::with_emitter(true, false, emitter); - let cstore = Rc::new(CStore::new(::DefaultTransCrate::metadata_loader())); let sess = session::build_session_(options, None, diagnostic_handler, Rc::new(CodeMap::new(FilePathMapping::empty()))); - rustc_trans::init(&sess); + let cstore = Rc::new(CStore::new(::get_trans(&sess).metadata_loader())); rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); let input = config::Input::Str { name: FileName::Anon, diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 1c3d4af9e18..58f851aea38 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -1187,8 +1187,8 @@ impl EmitterWriter { let sub_len = parts[0].snippet.trim().chars().fold(0, |acc, ch| { acc + unicode_width::UnicodeWidthChar::width(ch).unwrap_or(0) }); - let underline_start = span_start_pos.col.0 + start; - let underline_end = span_start_pos.col.0 + start + sub_len; + let underline_start = span_start_pos.col_display + start; + let underline_end = span_start_pos.col_display + start + sub_len; for p in underline_start..underline_end { buffer.putc(row_num, max_line_num_len + 3 + p, diff --git a/src/librustc_trans/assert_module_sources.rs b/src/librustc_incremental/assert_module_sources.rs index 745197d64f2..46ba94f2061 100644 --- a/src/librustc_trans/assert_module_sources.rs +++ b/src/librustc_incremental/assert_module_sources.rs @@ -40,7 +40,7 @@ const CFG: &'static str = "cfg"; #[derive(Debug, PartialEq, Clone, Copy)] enum Disposition { Reused, Translated } -pub(crate) fn assert_module_sources<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { +pub fn assert_module_sources<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { tcx.dep_graph.with_ignore(|| { if tcx.sess.opts.incremental.is_none() { return; diff --git a/src/librustc_incremental/lib.rs b/src/librustc_incremental/lib.rs index 0b827a0ee98..b53ee1daada 100644 --- a/src/librustc_incremental/lib.rs +++ b/src/librustc_incremental/lib.rs @@ -32,6 +32,7 @@ extern crate syntax; extern crate syntax_pos; mod assert_dep_graph; +pub mod assert_module_sources; mod persist; pub use assert_dep_graph::assert_dep_graph; diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index c5c27c92ab4..de55710bdf3 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1154,9 +1154,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems { let msg = "function is marked #[no_mangle], but not exported"; let mut err = cx.struct_span_lint(PRIVATE_NO_MANGLE_FNS, it.span, msg); let insertion_span = it.span.with_hi(it.span.lo()); - err.span_suggestion(insertion_span, - "try making it public", - "pub ".to_owned()); + if it.vis == hir::Visibility::Inherited { + err.span_suggestion(insertion_span, + "try making it public", + "pub ".to_owned()); + } err.emit(); } if generics.is_type_parameterized() { @@ -1177,9 +1179,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems { let msg = "static is marked #[no_mangle], but not exported"; let mut err = cx.struct_span_lint(PRIVATE_NO_MANGLE_STATICS, it.span, msg); let insertion_span = it.span.with_hi(it.span.lo()); - err.span_suggestion(insertion_span, - "try making it public", - "pub ".to_owned()); + if it.vis == hir::Visibility::Inherited { + err.span_suggestion(insertion_span, + "try making it public", + "pub ".to_owned()); + } err.emit(); } } diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index bf5d16696f9..2267d2b89cc 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -416,7 +416,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { } match def.adt_kind() { AdtKind::Struct => { - if !def.repr.c() { + if !def.repr.c() && !def.repr.transparent() { return FfiUnsafe("found struct without foreign-function-safe \ representation annotation in foreign module, \ consider adding a #[repr(C)] attribute to the type"); @@ -427,13 +427,24 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { adding a member to this struct"); } - // We can't completely trust repr(C) markings; make sure the - // fields are actually safe. + // We can't completely trust repr(C) and repr(transparent) markings; + // make sure the fields are actually safe. let mut all_phantom = true; for field in &def.non_enum_variant().fields { let field_ty = cx.fully_normalize_associated_types_in( &field.ty(cx, substs) ); + // repr(transparent) types are allowed to have arbitrary ZSTs, not just + // PhantomData -- skip checking all ZST fields + if def.repr.transparent() { + let is_zst = (cx, cx.param_env(field.did)) + .layout_of(field_ty) + .map(|layout| layout.is_zst()) + .unwrap_or(false); + if is_zst { + continue; + } + } let r = self.check_type_for_ffi(cache, field_ty); match r { FfiSafe => { diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 4e066ecf999..ef6475f9ee4 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -302,6 +302,18 @@ impl EarlyLintPass for UnusedParens { Assign(_, ref value) => (value, "assigned value", false), AssignOp(.., ref value) => (value, "assigned value", false), InPlace(_, ref value) => (value, "emplacement value", false), + Call(_, ref args) => { + for arg in args { + self.check_unused_parens_core(cx, arg, "function argument", false) + } + return; + }, + MethodCall(_, ref args) => { + for arg in &args[1..] { // first "argument" is self (which sometimes needs parens) + self.check_unused_parens_core(cx, arg, "method argument", false) + } + return; + } _ => return, }; self.check_unused_parens_core(cx, &value, msg, struct_lit_needs_parens); diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs index 2cfb151ae85..b97e37f4c8f 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_llvm/ffi.rs @@ -1661,7 +1661,6 @@ extern "C" { pub fn LLVMRustArchiveMemberFree(Member: RustArchiveMemberRef); pub fn LLVMRustSetDataLayoutFromTargetMachine(M: ModuleRef, TM: TargetMachineRef); - pub fn LLVMRustGetModuleDataLayout(M: ModuleRef) -> TargetDataRef; pub fn LLVMRustBuildOperandBundleDef(Name: *const c_char, Inputs: *const ValueRef, diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 946eecaa45f..246f5c9255e 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -15,7 +15,7 @@ use locator::{self, CratePaths}; use native_libs::relevant_lib; use schema::CrateRoot; -use rustc::hir::def_id::{CrateNum, DefIndex, CRATE_DEF_INDEX}; +use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX}; use rustc::hir::svh::Svh; use rustc::middle::allocator::AllocatorKind; use rustc::middle::cstore::DepKind; @@ -532,8 +532,7 @@ impl<'a> CrateLoader<'a> { Err(err) => self.sess.span_fatal(span, &err), }; - let sym = self.sess.generate_derive_registrar_symbol(root.disambiguator, - root.macro_derive_registrar.unwrap()); + let sym = self.sess.generate_derive_registrar_symbol(root.disambiguator); let registrar = unsafe { let sym = match lib.symbol(&sym) { Ok(f) => f, @@ -588,7 +587,7 @@ impl<'a> CrateLoader<'a> { pub fn find_plugin_registrar(&mut self, span: Span, name: &str) - -> Option<(PathBuf, CrateDisambiguator, DefIndex)> { + -> Option<(PathBuf, CrateDisambiguator)> { let name = Symbol::intern(name); let ekrate = self.read_extension_crate(span, name, name); @@ -603,11 +602,11 @@ impl<'a> CrateLoader<'a> { } let root = ekrate.metadata.get_root(); - match (ekrate.dylib.as_ref(), root.plugin_registrar_fn) { - (Some(dylib), Some(reg)) => { - Some((dylib.to_path_buf(), root.disambiguator, reg)) + match ekrate.dylib.as_ref() { + Some(dylib) => { + Some((dylib.to_path_buf(), root.disambiguator)) } - (None, Some(_)) => { + None => { span_err!(self.sess, span, E0457, "plugin `{}` only found in rlib format, but must be available \ in dylib format", @@ -616,7 +615,6 @@ impl<'a> CrateLoader<'a> { // empty dylib. None } - _ => None, } } diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index bd63396cd35..06728b2e625 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -702,8 +702,8 @@ impl<'a, 'tcx> CrateMetadata { let vis = self.get_visibility(child_index); let is_import = false; callback(def::Export { def, ident, vis, span, is_import }); - // For non-reexport structs and variants add their constructors to children. - // Reexport lists automatically contain constructors when necessary. + // For non-re-export structs and variants add their constructors to children. + // Re-export lists automatically contain constructors when necessary. match def { Def::Struct(..) => { if let Some(ctor_def_id) = self.get_struct_ctor_def_id(child_index) { diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs index cc332acb5b0..c0ce32cc970 100644 --- a/src/librustc_metadata/native_libs.rs +++ b/src/librustc_metadata/native_libs.rs @@ -92,9 +92,19 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for Collector<'a, 'tcx> { let cfg = items.iter().find(|k| { k.check_name("cfg") }).and_then(|a| a.meta_item_list()); - let cfg = cfg.map(|list| { - list[0].meta_item().unwrap().clone() - }); + let cfg = if let Some(list) = cfg { + if list.is_empty() { + self.tcx.sess.span_err(m.span(), "`cfg()` must have an argument"); + return; + } else if let cfg @ Some(..) = list[0].meta_item() { + cfg.cloned() + } else { + self.tcx.sess.span_err(list[0].span(), "invalid argument for `cfg(..)`"); + return; + } + } else { + None + }; let foreign_items = fm.items.iter() .map(|it| self.tcx.hir.local_def_id(it.id)) .collect(); diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml index 195335dd64c..ea05a513f7e 100644 --- a/src/librustc_mir/Cargo.toml +++ b/src/librustc_mir/Cargo.toml @@ -24,4 +24,3 @@ syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } byteorder = { version = "1.1", features = ["i128"] } rustc_apfloat = { path = "../librustc_apfloat" } -rustc_trans_utils = { path = "../librustc_trans_utils" } diff --git a/src/librustc_mir/borrow_check/nll/constraint_generation.rs b/src/librustc_mir/borrow_check/nll/constraint_generation.rs index 7ca4ebd1cb2..3a39eb5c908 100644 --- a/src/librustc_mir/borrow_check/nll/constraint_generation.rs +++ b/src/librustc_mir/borrow_check/nll/constraint_generation.rs @@ -69,6 +69,7 @@ impl<'cg, 'cx, 'gcx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'gcx fn visit_ty(&mut self, ty: &ty::Ty<'tcx>, ty_context: TyContext) { match ty_context { TyContext::ReturnTy(source_info) | + TyContext::YieldTy(source_info) | TyContext::LocalDecl { source_info, .. } => { span_bug!(source_info.span, "should not be visiting outside of the CFG: {:?}", diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs index da136a34b99..9a2f98d4622 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs @@ -989,7 +989,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { if let (Some(f), Some(o)) = (fr_name, outlived_fr_name) { let tables = infcx.tcx.typeck_tables_of(mir_def_id); - let nice = NiceRegionError::new(infcx.tcx, blame_span, o, f, Some(tables)); + let nice = NiceRegionError::new_from_span(infcx.tcx, blame_span, o, f, Some(tables)); if let Some(ErrorReported) = nice.try_report() { return; } diff --git a/src/librustc_mir/borrow_check/nll/renumber.rs b/src/librustc_mir/borrow_check/nll/renumber.rs index 4aee48b979d..c54acda8a62 100644 --- a/src/librustc_mir/borrow_check/nll/renumber.rs +++ b/src/librustc_mir/borrow_check/nll/renumber.rs @@ -9,7 +9,7 @@ // except according to those terms. use rustc::ty::subst::Substs; -use rustc::ty::{self, ClosureSubsts, Ty, TypeFoldable}; +use rustc::ty::{self, ClosureSubsts, GeneratorInterior, Ty, TypeFoldable}; use rustc::mir::{BasicBlock, Location, Mir, Statement, StatementKind}; use rustc::mir::visit::{MutVisitor, TyContext}; use rustc::infer::{InferCtxt, NLLRegionVariableOrigin}; @@ -90,6 +90,21 @@ impl<'a, 'gcx, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'gcx, 'tcx> { *constant = self.renumber_regions(ty_context, &*constant); } + fn visit_generator_interior(&mut self, + interior: &mut GeneratorInterior<'tcx>, + location: Location) { + debug!( + "visit_generator_interior(interior={:?}, location={:?})", + interior, + location, + ); + + let ty_context = TyContext::Location(location); + *interior = self.renumber_regions(ty_context, interior); + + debug!("visit_generator_interior: interior={:?}", interior); + } + fn visit_closure_substs(&mut self, substs: &mut ClosureSubsts<'tcx>, location: Location) { debug!( "visit_closure_substs(substs={:?}, location={:?})", diff --git a/src/librustc_mir/borrow_check/nll/type_check/input_output.rs b/src/librustc_mir/borrow_check/nll/type_check/input_output.rs index 9e88a632f5c..b1aeae0b76b 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/input_output.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/input_output.rs @@ -60,6 +60,15 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { self.equate_normalized_input_or_output(start_position, input_ty, mir_input_ty); } + assert!( + mir.yield_ty.is_some() && universal_regions.yield_ty.is_some() || + mir.yield_ty.is_none() && universal_regions.yield_ty.is_none() + ); + if let Some(mir_yield_ty) = mir.yield_ty { + let ur_yield_ty = universal_regions.yield_ty.unwrap(); + self.equate_normalized_input_or_output(start_position, ur_yield_ty, mir_yield_ty); + } + // Return types are a bit more complex. They may contain existential `impl Trait` // types. debug!( diff --git a/src/librustc_mir/borrow_check/nll/universal_regions.rs b/src/librustc_mir/borrow_check/nll/universal_regions.rs index 45604d52958..e47e3c728df 100644 --- a/src/librustc_mir/borrow_check/nll/universal_regions.rs +++ b/src/librustc_mir/borrow_check/nll/universal_regions.rs @@ -96,6 +96,8 @@ pub struct UniversalRegions<'tcx> { /// our special inference variable there, we would mess that up. pub region_bound_pairs: Vec<(ty::Region<'tcx>, GenericKind<'tcx>)>, + pub yield_ty: Option<Ty<'tcx>>, + relations: UniversalRegionRelations, } @@ -505,6 +507,13 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> { num_universals ); + let yield_ty = match defining_ty { + DefiningTy::Generator(def_id, substs, _) => { + Some(substs.generator_yield_ty(def_id, self.infcx.tcx)) + } + _ => None, + }; + UniversalRegions { indices, fr_static, @@ -516,6 +525,7 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> { unnormalized_output_ty, unnormalized_input_tys, region_bound_pairs: self.region_bound_pairs, + yield_ty: yield_ty, relations: self.relations, } } @@ -584,13 +594,9 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> { DefiningTy::FnDef(_, substs) => substs, - // When we encounter other sorts of constant - // expressions, such as the `22` in `[foo; 22]`, we can - // get the type `usize` here. For now, just return an - // empty vector of substs in this case, since there are no - // generics in scope in such expressions right now. + // When we encounter a constant body, just return whatever + // substitutions are in scope for that constant. DefiningTy::Const(_) => { - assert!(identity_substs.is_empty()); identity_substs } }; @@ -654,9 +660,8 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> { sig.inputs_and_output() } - // This happens on things like `[foo; 22]`. Hence, no - // inputs, one output, but it seems like we need a more - // general way to handle this category of MIR. + // For a constant body, there are no inputs, and one + // "output" (the type of the constant). DefiningTy::Const(ty) => ty::Binder::dummy(tcx.mk_type_list(iter::once(ty))), } } @@ -799,10 +804,12 @@ impl<'tcx> UniversalRegionIndices<'tcx> { /// during initialization. Relies on the `indices` map having been /// fully initialized. pub fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid { - match r { - ty::ReEarlyBound(..) | ty::ReStatic => *self.indices.get(&r).unwrap(), - ty::ReVar(..) => r.to_region_vid(), - _ => bug!("cannot convert `{:?}` to a region vid", r), + if let ty::ReVar(..) = r { + r.to_region_vid() + } else { + *self.indices.get(&r).unwrap_or_else(|| { + bug!("cannot convert `{:?}` to a region vid", r) + }) } } diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs index b2357b77157..bdcbfc0bdd8 100644 --- a/src/librustc_mir/build/matches/test.rs +++ b/src/librustc_mir/build/matches/test.rs @@ -174,12 +174,50 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { } } + /// Convert a byte array or byte slice to a byte slice. + fn to_slice_operand(&mut self, + block: BasicBlock, + source_info: SourceInfo, + operand: Operand<'tcx>) + -> Operand<'tcx> + { + let tcx = self.hir.tcx(); + let ty = operand.ty(&self.local_decls, tcx); + debug!("to_slice_operand({:?}, {:?}: {:?})", block, operand, ty); + match ty.sty { + ty::TyRef(region, mt) => match mt.ty.sty { + ty::TyArray(ety, _) => { + let ty = tcx.mk_imm_ref(region, tcx.mk_slice(ety)); + let temp = self.temp(ty, source_info.span); + self.cfg.push_assign(block, source_info, &temp, + Rvalue::Cast(CastKind::Unsize, operand, ty)); + Operand::Move(temp) + } + ty::TySlice(_) => operand, + _ => { + span_bug!(source_info.span, + "bad operand {:?}: {:?} to `to_slice_operand`", operand, ty) + } + } + _ => { + span_bug!(source_info.span, + "bad operand {:?}: {:?} to `to_slice_operand`", operand, ty) + } + } + + } + /// Generates the code to perform a test. pub fn perform_test(&mut self, block: BasicBlock, place: &Place<'tcx>, test: &Test<'tcx>) -> Vec<BasicBlock> { + debug!("perform_test({:?}, {:?}: {:?}, {:?})", + block, + place, + place.ty(&self.local_decls, self.hir.tcx()), + test); let source_info = self.source_info(test.span); match test.kind { TestKind::Switch { adt_def, ref variants } => { @@ -258,45 +296,35 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { ret } - TestKind::Eq { value, mut ty } => { + TestKind::Eq { value, ty } => { + let tcx = self.hir.tcx(); let mut val = Operand::Copy(place.clone()); // If we're using b"..." as a pattern, we need to insert an // unsizing coercion, as the byte string has the type &[u8; N]. - let expect = if let ConstVal::ByteStr(bytes) = value.val { - let tcx = self.hir.tcx(); - - // Unsize the place to &[u8], too, if necessary. - if let ty::TyRef(region, mt) = ty.sty { - if let ty::TyArray(_, _) = mt.ty.sty { - ty = tcx.mk_imm_ref(region, tcx.mk_slice(tcx.types.u8)); - let val_slice = self.temp(ty, test.span); - self.cfg.push_assign(block, source_info, &val_slice, - Rvalue::Cast(CastKind::Unsize, val, ty)); - val = Operand::Move(val_slice); - } - } - - assert!(ty.is_slice()); - + // + // We want to do this even when the scrutinee is a reference to an + // array, so we can call `<[u8]>::eq` rather than having to find an + // `<[u8; N]>::eq`. + let (expect, val) = if let ConstVal::ByteStr(bytes) = value.val { let array_ty = tcx.mk_array(tcx.types.u8, bytes.data.len() as u64); let array_ref = tcx.mk_imm_ref(tcx.types.re_static, array_ty); let array = self.literal_operand(test.span, array_ref, Literal::Value { value }); - let slice = self.temp(ty, test.span); - self.cfg.push_assign(block, source_info, &slice, - Rvalue::Cast(CastKind::Unsize, array, ty)); - Operand::Move(slice) + let val = self.to_slice_operand(block, source_info, val); + let slice = self.to_slice_operand(block, source_info, array); + (slice, val) } else { - self.literal_operand(test.span, ty, Literal::Value { + (self.literal_operand(test.span, ty, Literal::Value { value - }) + }), val) }; // Use PartialEq::eq for &str and &[u8] slices, instead of BinOp::Eq. let fail = self.cfg.start_new_block(); + let ty = expect.ty(&self.local_decls, tcx); if let ty::TyRef(_, mt) = ty.sty { assert!(ty.is_slice()); let eq_def_id = self.hir.tcx().lang_items().eq_trait().unwrap(); diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index f76aea19677..f543a33b130 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -131,7 +131,7 @@ impl<'tcx> fmt::Display for BorrowData<'tcx> { } impl ReserveOrActivateIndex { - fn reserved(i: BorrowIndex) -> Self { ReserveOrActivateIndex::new((i.index() * 2)) } + fn reserved(i: BorrowIndex) -> Self { ReserveOrActivateIndex::new(i.index() * 2) } fn active(i: BorrowIndex) -> Self { ReserveOrActivateIndex::new((i.index() * 2) + 1) } pub(crate) fn is_reservation(self) -> bool { self.index() % 2 == 0 } diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 5379bf3f5a7..1699ad0f19c 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -57,7 +57,6 @@ extern crate core; // for NonZero extern crate log_settings; extern crate rustc_apfloat; extern crate byteorder; -extern crate rustc_trans_utils; mod diagnostics; diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index 024334f1c84..072c3398134 100644 --- a/src/librustc_mir/monomorphize/item.rs +++ b/src/librustc_mir/monomorphize/item.rs @@ -26,6 +26,7 @@ use std::fmt::{self, Write}; use std::iter; use rustc::mir::mono::Linkage; use syntax_pos::symbol::Symbol; +use syntax::codemap::Span; pub use rustc::mir::mono::MonoItem; pub fn linkage_by_name(name: &str) -> Option<Linkage> { @@ -244,6 +245,18 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug { result } } + + fn local_span(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option<Span> { + match *self.as_mono_item() { + MonoItem::Fn(Instance { def, .. }) => { + tcx.hir.as_local_node_id(def.def_id()) + } + MonoItem::Static(node_id) | + MonoItem::GlobalAsm(node_id) => { + Some(node_id) + } + }.map(|node_id| tcx.hir.span(node_id)) + } } impl<'a, 'tcx> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> { diff --git a/src/librustc_mir/monomorphize/mod.rs b/src/librustc_mir/monomorphize/mod.rs index fcf0d71dccb..95ebb6c970a 100644 --- a/src/librustc_mir/monomorphize/mod.rs +++ b/src/librustc_mir/monomorphize/mod.rs @@ -22,6 +22,54 @@ pub mod collector; pub mod item; pub mod partitioning; +#[inline(never)] // give this a place in the profiler +pub fn assert_symbols_are_distinct<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trans_items: I) + where I: Iterator<Item=&'a MonoItem<'tcx>> +{ + let mut symbols: Vec<_> = trans_items.map(|trans_item| { + (trans_item, trans_item.symbol_name(tcx)) + }).collect(); + + (&mut symbols[..]).sort_by(|&(_, ref sym1), &(_, ref sym2)|{ + sym1.cmp(sym2) + }); + + for pair in (&symbols[..]).windows(2) { + let sym1 = &pair[0].1; + let sym2 = &pair[1].1; + + if *sym1 == *sym2 { + let trans_item1 = pair[0].0; + let trans_item2 = pair[1].0; + + let span1 = trans_item1.local_span(tcx); + let span2 = trans_item2.local_span(tcx); + + // Deterministically select one of the spans for error reporting + let span = match (span1, span2) { + (Some(span1), Some(span2)) => { + Some(if span1.lo().0 > span2.lo().0 { + span1 + } else { + span2 + }) + } + (Some(span), None) | + (None, Some(span)) => Some(span), + _ => None + }; + + let error_message = format!("symbol `{}` is already defined", sym1); + + if let Some(span) = span { + tcx.sess.span_fatal(span, &error_message) + } else { + tcx.sess.fatal(&error_message) + } + } + } +} + fn fn_once_adapter_instance<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, closure_did: DefId, diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 89e3e7e0b60..c206d0ea9b5 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -28,7 +28,7 @@ use std::fmt; use std::iter; use transform::{add_moves_for_packed_drops, add_call_guards}; -use transform::{no_landing_pads, simplify}; +use transform::{remove_noop_landing_pads, no_landing_pads, simplify}; use util::elaborate_drops::{self, DropElaborator, DropStyle, DropFlagMode}; use util::patch::MirPatch; @@ -118,6 +118,7 @@ fn make_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, add_moves_for_packed_drops::add_moves_for_packed_drops( tcx, &mut result, instance.def_id()); no_landing_pads::no_landing_pads(tcx, &mut result); + remove_noop_landing_pads::remove_noop_landing_pads(tcx, &mut result); simplify::simplify_cfg(&mut result); add_call_guards::CriticalCallEdges.add_call_guards(&mut result); debug!("make_shim({:?}) = {:?}", instance, result); diff --git a/src/librustc_mir/transform/remove_noop_landing_pads.rs b/src/librustc_mir/transform/remove_noop_landing_pads.rs index 23274cdedf2..e7cab469bc2 100644 --- a/src/librustc_mir/transform/remove_noop_landing_pads.rs +++ b/src/librustc_mir/transform/remove_noop_landing_pads.rs @@ -20,17 +20,24 @@ use util::patch::MirPatch; /// code for these. pub struct RemoveNoopLandingPads; +pub fn remove_noop_landing_pads<'a, 'tcx>( + tcx: TyCtxt<'a, 'tcx, 'tcx>, + mir: &mut Mir<'tcx>) +{ + if tcx.sess.no_landing_pads() { + return + } + debug!("remove_noop_landing_pads({:?})", mir); + + RemoveNoopLandingPads.remove_nop_landing_pads(mir) +} + impl MirPass for RemoveNoopLandingPads { fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, _src: MirSource, mir: &mut Mir<'tcx>) { - if tcx.sess.no_landing_pads() { - return - } - - debug!("remove_noop_landing_pads({:?})", mir); - self.remove_nop_landing_pads(mir); + remove_noop_landing_pads(tcx, mir); } } diff --git a/src/librustc_mir/util/liveness.rs b/src/librustc_mir/util/liveness.rs index 765d50b4006..6251b64bb27 100644 --- a/src/librustc_mir/util/liveness.rs +++ b/src/librustc_mir/util/liveness.rs @@ -407,10 +407,7 @@ fn dump_matched_mir_node<'a, 'tcx>( result: &LivenessResult, ) { let mut file_path = PathBuf::new(); - if let Some(ref file_dir) = tcx.sess.opts.debugging_opts.dump_mir_dir { - let p = Path::new(file_dir); - file_path.push(p); - }; + file_path.push(Path::new(&tcx.sess.opts.debugging_opts.dump_mir_dir)); let item_id = tcx.hir.as_local_node_id(source.def_id).unwrap(); let file_name = format!("rustc.node{}{}-liveness.mir", item_id, pass_name); file_path.push(&file_name); diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index 37f59773cd6..6ab5fee79c6 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -189,11 +189,7 @@ fn dump_path( }; let mut file_path = PathBuf::new(); - - if let Some(ref file_dir) = tcx.sess.opts.debugging_opts.dump_mir_dir { - let p = Path::new(file_dir); - file_path.push(p); - }; + file_path.push(Path::new(&tcx.sess.opts.debugging_opts.dump_mir_dir)); let item_name = tcx.hir .def_path(source.def_id) @@ -522,7 +518,7 @@ pub fn write_mir_intro<'a, 'gcx, 'tcx>( w: &mut Write, ) -> io::Result<()> { write_mir_sig(tcx, src, mir, w)?; - writeln!(w, " {{")?; + writeln!(w, "{{")?; // construct a scope tree and write it out let mut scope_tree: FxHashMap<VisibilityScope, Vec<VisibilityScope>> = FxHashMap(); @@ -585,13 +581,20 @@ fn write_mir_sig(tcx: TyCtxt, src: MirSource, mir: &Mir, w: &mut Write) -> io::R write!(w, "{:?}: {}", Place::Local(arg), mir.local_decls[arg].ty)?; } - write!(w, ") -> {}", mir.return_ty()) + write!(w, ") -> {}", mir.return_ty())?; } (hir::BodyOwnerKind::Const, _) | (hir::BodyOwnerKind::Static(_), _) | (_, Some(_)) => { assert_eq!(mir.arg_count, 0); - write!(w, ": {} =", mir.return_ty()) + write!(w, ": {} =", mir.return_ty())?; } } + + if let Some(yield_ty) = mir.yield_ty { + writeln!(w)?; + writeln!(w, "yields {}", yield_ty)?; + } + + Ok(()) } fn write_temp_decls(mir: &Mir, w: &mut Write) -> io::Result<()> { diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index c41591bbc37..3f49128d2e8 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -149,6 +149,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> { ExprKind::Continue(Some(ident)) => { self.check_label(ident.node, ident.span); } + ExprKind::InlineAsm(..) if !self.session.target.target.options.allow_asm => { + span_err!(self.session, expr.span, E0472, "asm! is unsupported on this target"); + } _ => {} } @@ -215,13 +218,16 @@ impl<'a> Visitor<'a> for AstValidator<'a> { fn visit_item(&mut self, item: &'a Item) { match item.node { - ItemKind::Impl(.., Some(..), ref ty, ref impl_items) => { + ItemKind::Impl(unsafety, polarity, _, _, Some(..), ref ty, ref impl_items) => { self.invalid_visibility(&item.vis, item.span, None); if ty.node == TyKind::Err { self.err_handler() .struct_span_err(item.span, "`impl Trait for .. {}` is an obsolete syntax") .help("use `auto trait Trait {}` instead").emit(); } + if unsafety == Unsafety::Unsafe && polarity == ImplPolarity::Negative { + span_err!(self.session, item.span, E0198, "negative impls cannot be unsafe"); + } for impl_item in impl_items { self.invalid_visibility(&impl_item.vis, impl_item.span, None); if let ImplItemKind::Method(ref sig, _) = impl_item.node { @@ -229,10 +235,19 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } } } - ItemKind::Impl(.., None, _, _) => { + ItemKind::Impl(unsafety, polarity, defaultness, _, None, _, _) => { self.invalid_visibility(&item.vis, item.span, Some("place qualifiers on individual impl items instead")); + if unsafety == Unsafety::Unsafe { + span_err!(self.session, item.span, E0197, "inherent impls cannot be unsafe"); + } + if polarity == ImplPolarity::Negative { + self.err_handler().span_err(item.span, "inherent impls cannot be negative"); + } + if defaultness == Defaultness::Default { + self.err_handler().span_err(item.span, "inherent impls cannot be default"); + } } ItemKind::ForeignMod(..) => { self.invalid_visibility(&item.vis, diff --git a/src/librustc_passes/diagnostics.rs b/src/librustc_passes/diagnostics.rs index cbfdace7e0f..743f7b7326e 100644 --- a/src/librustc_passes/diagnostics.rs +++ b/src/librustc_passes/diagnostics.rs @@ -82,6 +82,52 @@ extern { ``` "##, +E0197: r##" +Inherent implementations (one that do not implement a trait but provide +methods associated with a type) are always safe because they are not +implementing an unsafe trait. Removing the `unsafe` keyword from the inherent +implementation will resolve this error. + +```compile_fail,E0197 +struct Foo; + +// this will cause this error +unsafe impl Foo { } +// converting it to this will fix it +impl Foo { } +``` +"##, + +E0198: r##" +A negative implementation is one that excludes a type from implementing a +particular trait. Not being able to use a trait is always a safe operation, +so negative implementations are always safe and never need to be marked as +unsafe. + +```compile_fail +#![feature(optin_builtin_traits)] + +struct Foo; + +// unsafe is unnecessary +unsafe impl !Clone for Foo { } +``` + +This will compile: + +```ignore (ignore auto_trait future compatibility warning) +#![feature(optin_builtin_traits)] + +struct Foo; + +auto trait Enterprise {} + +impl !Enterprise for Foo { } +``` + +Please note that negative impls are only allowed for auto traits. +"##, + E0265: r##" This error indicates that a static or constant references itself. All statics and constants need to resolve to a value in an acyclic manner. diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs index 754c3bbd074..73c71ec0b2f 100644 --- a/src/librustc_passes/lib.rs +++ b/src/librustc_passes/lib.rs @@ -42,7 +42,6 @@ pub mod consts; pub mod hir_stats; pub mod loops; mod mir_stats; -pub mod no_asm; pub mod static_recursion; #[cfg(not(stage0))] // remove after the next snapshot diff --git a/src/librustc_passes/no_asm.rs b/src/librustc_passes/no_asm.rs deleted file mode 100644 index 4dbf57a99bc..00000000000 --- a/src/librustc_passes/no_asm.rs +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -/// Run over the whole crate and check for ExprInlineAsm. -/// Inline asm isn't allowed on virtual ISA based targets, so we reject it -/// here. - -use rustc::session::Session; - -use syntax::ast; -use syntax::visit::Visitor; -use syntax::visit; - -pub fn check_crate(sess: &Session, krate: &ast::Crate) { - if sess.target.target.options.allow_asm { - return; - } - - visit::walk_crate(&mut CheckNoAsm { sess: sess }, krate); -} - -#[derive(Copy, Clone)] -struct CheckNoAsm<'a> { - sess: &'a Session, -} - -impl<'a> Visitor<'a> for CheckNoAsm<'a> { - fn visit_expr(&mut self, e: &'a ast::Expr) { - match e.node { - ast::ExprKind::InlineAsm(_) => { - span_err!(self.sess, - e.span, - E0472, - "asm! is unsupported on this target") - } - _ => {} - } - visit::walk_expr(self, e) - } -} diff --git a/src/librustc_plugin/load.rs b/src/librustc_plugin/load.rs index 8a4ec03b20e..a46b85d93cb 100644 --- a/src/librustc_plugin/load.rs +++ b/src/librustc_plugin/load.rs @@ -100,8 +100,8 @@ impl<'a> PluginLoader<'a> { fn load_plugin(&mut self, span: Span, name: &str, args: Vec<ast::NestedMetaItem>) { let registrar = self.reader.find_plugin_registrar(span, name); - if let Some((lib, disambiguator, index)) = registrar { - let symbol = self.sess.generate_plugin_registrar_symbol(disambiguator, index); + if let Some((lib, disambiguator)) = registrar { + let symbol = self.sess.generate_plugin_registrar_symbol(disambiguator); let fun = self.dylink_registrar(span, lib, symbol); self.plugins.push(PluginRegistrar { fun, diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index b525ab852a7..b46882f054d 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -219,7 +219,7 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> { hir::ItemExternCrate(..) => {} // All nested items are checked by visit_item hir::ItemMod(..) => {} - // Reexports are handled in visit_mod + // Re-exports are handled in visit_mod hir::ItemUse(..) => {} // The interface is empty hir::ItemGlobalAsm(..) => {} @@ -1049,7 +1049,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { fn visit_item(&mut self, item: &'tcx hir::Item) { match item.node { - // contents of a private mod can be reexported, so we need + // contents of a private mod can be re-exported, so we need // to check internals. hir::ItemMod(_) => {} diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 10bd72ac4a0..c55bf395d71 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -683,7 +683,7 @@ impl<'a> Resolver<'a> { let (def, vis) = (binding.def(), binding.vis); self.macro_exports.push(Export { ident, def, vis, span, is_import: true }); } else { - span_err!(self.session, span, E0470, "reexported macro not found"); + span_err!(self.session, span, E0470, "re-exported macro not found"); } } used @@ -729,7 +729,7 @@ impl<'a> Resolver<'a> { } } else if attr.check_name("macro_reexport") { let bad_macro_reexport = |this: &mut Self, span| { - span_err!(this.session, span, E0467, "bad macro reexport"); + span_err!(this.session, span, E0467, "bad macro re-export"); }; if let Some(names) = attr.meta_item_list() { for attr in names { diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 564626ac398..8a29155d12d 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -1374,7 +1374,7 @@ arguments. "##, E0467: r##" -Macro reexport declarations were empty or malformed. +Macro re-export declarations were empty or malformed. Erroneous code examples: @@ -1389,12 +1389,12 @@ extern crate core as other_macros_for_good; This is a syntax error at the level of attribute declarations. Currently, `macro_reexport` requires at least one macro name to be listed. -Unlike `macro_use`, listing no names does not reexport all macros from the +Unlike `macro_use`, listing no names does not re-export all macros from the given crate. Decide which macros you would like to export and list them properly. -These are proper reexport declarations: +These are proper re-export declarations: ```ignore (cannot-doctest-multicrate-project) #[macro_reexport(some_macro, another_macro)] @@ -1475,7 +1475,7 @@ extern crate some_crate; //ok! "##, E0470: r##" -A macro listed for reexport was not found. +A macro listed for re-export was not found. Erroneous code example: @@ -1493,7 +1493,7 @@ exported from the given crate. This could be caused by a typo. Did you misspell the macro's name? -Double-check the names of the macros listed for reexport, and that the crate +Double-check the names of the macros listed for re-export, and that the crate in question exports them. A working version: @@ -1621,6 +1621,59 @@ println!("const value: {}", SomeModule::PRIVATE); // ok! ``` "##, +E0659: r##" +An item usage is ambiguous. + +Erroneous code example: + +```compile_fail,E0659 +pub mod moon { + pub fn foo() {} +} + +pub mod earth { + pub fn foo() {} +} + +mod collider { + pub use moon::*; + pub use earth::*; +} + +fn main() { + collider::foo(); // ERROR: `foo` is ambiguous +} +``` + +This error generally appears when two items with the same name are imported into +a module. Here, the `foo` functions are imported and reexported from the +`collider` module and therefore, when we're using `collider::foo()`, both +functions collide. + +To solve this error, the best solution is generally to keep the path before the +item when using it. Example: + +``` +pub mod moon { + pub fn foo() {} +} + +pub mod earth { + pub fn foo() {} +} + +mod collider { + pub use moon; + pub use earth; +} + +fn main() { + collider::moon::foo(); // ok! + collider::earth::foo(); // ok! +} +``` +"##, + } register_diagnostics! { diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 0a29441cef7..d9ae776a4d7 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -898,7 +898,7 @@ impl<'a> LexicalScopeBinding<'a> { } } -#[derive(Clone)] +#[derive(Clone, Debug)] enum PathResult<'a> { Module(Module<'a>), NonModule(PathResolution), @@ -963,7 +963,7 @@ impl<'a> ModuleData<'a> { unresolved_invocations: RefCell::new(FxHashSet()), no_implicit_prelude: false, glob_importers: RefCell::new(Vec::new()), - globs: RefCell::new((Vec::new())), + globs: RefCell::new(Vec::new()), traits: RefCell::new(None), populated: Cell::new(normal_ancestor_id.is_local()), span, @@ -2568,7 +2568,8 @@ impl<'a> Resolver<'a> { let code = source.error_code(def.is_some()); let (base_msg, fallback_label, base_span) = if let Some(def) = def { (format!("expected {}, found {} `{}`", expected, def.kind_name(), path_str), - format!("not a {}", expected), span) + format!("not a {}", expected), + span) } else { let item_str = path[path.len() - 1].node; let item_span = path[path.len() - 1].span; @@ -2585,7 +2586,8 @@ impl<'a> Resolver<'a> { (mod_prefix, format!("`{}`", names_to_string(mod_path))) }; (format!("cannot find {} `{}` in {}{}", expected, item_str, mod_prefix, mod_str), - format!("not found in {}", mod_str), item_span) + format!("not found in {}", mod_str), + item_span) }; let code = DiagnosticId::Error(code.into()); let mut err = this.session.struct_span_err_with_code(base_span, &base_msg, code); @@ -2700,20 +2702,37 @@ impl<'a> Resolver<'a> { } return (err, candidates); }, - _ if ns == ValueNS && is_struct_like(def) => { - if let Def::Struct(def_id) = def { - if let Some((ctor_def, ctor_vis)) - = this.struct_constructors.get(&def_id).cloned() { - if is_expected(ctor_def) && !this.is_accessible(ctor_vis) { - err.span_label(span, format!("constructor is not visible \ - here due to private fields")); - } + (Def::Struct(def_id), _) if ns == ValueNS => { + if let Some((ctor_def, ctor_vis)) + = this.struct_constructors.get(&def_id).cloned() { + let accessible_ctor = this.is_accessible(ctor_vis); + if is_expected(ctor_def) && !accessible_ctor { + err.span_label(span, format!("constructor is not visible \ + here due to private fields")); } + } else { + err.span_label(span, format!("did you mean `{} {{ /* fields */ }}`?", + path_str)); } + return (err, candidates); + } + (Def::Union(..), _) | + (Def::Variant(..), _) | + (Def::VariantCtor(_, CtorKind::Fictive), _) if ns == ValueNS => { err.span_label(span, format!("did you mean `{} {{ /* fields */ }}`?", path_str)); return (err, candidates); } + (Def::SelfTy(..), _) if ns == ValueNS => { + err.span_label(span, fallback_label); + err.note("can't use `Self` as a constructor, you must use the \ + implemented struct"); + return (err, candidates); + } + (Def::TyAlias(_), _) | (Def::AssociatedTy(..), _) if ns == ValueNS => { + err.note("can't use a type alias as a constructor"); + return (err, candidates); + } _ => {} } } @@ -2751,7 +2770,7 @@ impl<'a> Resolver<'a> { let lint = lint::builtin::LEGACY_CONSTRUCTOR_VISIBILITY; self.session.buffer_lint(lint, id, span, "private struct constructors are not usable through \ - reexports in outer modules", + re-exports in outer modules", ); res = Some(PathResolution::new(ctor_def)); } @@ -3783,7 +3802,7 @@ impl<'a> Resolver<'a> { self.session.buffer_lint(lint::builtin::LEGACY_IMPORTS, id, span, &msg); } else { let mut err = - self.session.struct_span_err(span, &format!("`{}` is ambiguous", name)); + struct_span_err!(self.session, span, E0659, "`{}` is ambiguous", name); err.span_note(b1.span, &msg1); match b2.def() { Def::Macro(..) if b2.span == DUMMY_SP => @@ -3965,13 +3984,6 @@ impl<'a> Resolver<'a> { } } -fn is_struct_like(def: Def) -> bool { - match def { - Def::VariantCtor(_, CtorKind::Fictive) => true, - _ => PathSource::Struct.is_expected(def), - } -} - fn is_self_type(path: &[SpannedIdent], namespace: Namespace) -> bool { namespace == TypeNS && path.len() == 1 && path[0].node.name == keywords::SelfType.name() } @@ -4062,7 +4074,7 @@ fn show_candidates(err: &mut DiagnosticBuilder, } /// A somewhat inefficient routine to obtain the name of a module. -fn module_to_string(module: Module) -> String { +fn module_to_string(module: Module) -> Option<String> { let mut names = Vec::new(); fn collect_mod(names: &mut Vec<Ident>, module: Module) { @@ -4080,12 +4092,12 @@ fn module_to_string(module: Module) -> String { collect_mod(&mut names, module); if names.is_empty() { - return "???".to_string(); + return None; } - names_to_string(&names.into_iter() + Some(names_to_string(&names.into_iter() .rev() .map(|n| dummy_spanned(n)) - .collect::<Vec<_>>()) + .collect::<Vec<_>>())) } fn err_path_resolution() -> PathResolution { diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 2b0c839152c..ceb39aea108 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -691,8 +691,7 @@ impl<'a> Resolver<'a> { if let Some(suggestion) = suggestion { if suggestion != name { if let MacroKind::Bang = kind { - err.span_suggestion(span, "you could try the macro", - format!("{}!", suggestion)); + err.span_suggestion(span, "you could try the macro", suggestion.to_string()); } else { err.span_suggestion(span, "try", suggestion.to_string()); } diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 132119e961b..07b08e2e61a 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -46,8 +46,8 @@ pub enum ImportDirectiveSubclass<'a> { }, GlobImport { is_prelude: bool, - max_vis: Cell<ty::Visibility>, // The visibility of the greatest reexport. - // n.b. `max_vis` is only used in `finalize_import` to check for reexport errors. + max_vis: Cell<ty::Visibility>, // The visibility of the greatest re-export. + // n.b. `max_vis` is only used in `finalize_import` to check for re-export errors. }, ExternCrate(Option<Name>), MacroUse, @@ -524,7 +524,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { fn resolve_import(&mut self, directive: &'b ImportDirective<'b>) -> bool { debug!("(resolving import for module) resolving import `{}::...` in `{}`", names_to_string(&directive.module_path[..]), - module_to_string(self.current_module)); + module_to_string(self.current_module).unwrap_or("???".to_string())); self.current_module = directive.parent; @@ -773,10 +773,10 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { None => "".to_owned(), }; let module_str = module_to_string(module); - let msg = if &module_str == "???" { - format!("no `{}` in the root{}", ident, lev_suggestion) - } else { + let msg = if let Some(module_str) = module_str { format!("no `{}` in `{}`{}", ident, module_str, lev_suggestion) + } else { + format!("no `{}` in the root{}", ident, lev_suggestion) }; Some((span, msg)) } else { @@ -803,8 +803,9 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { if !any_successful_reexport { let (ns, binding) = reexport_error.unwrap(); if ns == TypeNS && binding.is_extern_crate() { - let msg = format!("extern crate `{}` is private, and cannot be reexported \ - (error E0365), consider declaring with `pub`", + let msg = format!("extern crate `{}` is private, and cannot be \ + re-exported (error E0365), consider declaring with \ + `pub`", ident); self.session.buffer_lint(PUB_USE_OF_PRIVATE_EXTERN_CRATE, directive.id, @@ -812,12 +813,12 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { &msg); } else if ns == TypeNS { struct_span_err!(self.session, directive.span, E0365, - "`{}` is private, and cannot be reexported", ident) - .span_label(directive.span, format!("reexport of private `{}`", ident)) + "`{}` is private, and cannot be re-exported", ident) + .span_label(directive.span, format!("re-export of private `{}`", ident)) .note(&format!("consider declaring type or module `{}` with `pub`", ident)) .emit(); } else { - let msg = format!("`{}` is private, and cannot be reexported", ident); + let msg = format!("`{}` is private, and cannot be re-exported", ident); let note_msg = format!("consider marking `{}` as `pub` in the imported module", ident); struct_span_err!(self.session, directive.span, E0364, "{}", &msg) @@ -876,7 +877,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { self.record_def(directive.id, PathResolution::new(module.def().unwrap())); } - // Miscellaneous post-processing, including recording reexports, + // Miscellaneous post-processing, including recording re-exports, // reporting conflicts, and reporting unresolved imports. fn finalize_resolutions_in(&mut self, module: Module<'b>) { // Since import resolution is finished, globs will not define any more names. @@ -932,12 +933,12 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { !orig_binding.vis.is_at_least(binding.vis, &*self) { let msg = match directive.subclass { ImportDirectiveSubclass::SingleImport { .. } => { - format!("variant `{}` is private and cannot be reexported", + format!("variant `{}` is private and cannot be re-exported", ident) }, ImportDirectiveSubclass::GlobImport { .. } => { let msg = "enum is private and its variants \ - cannot be reexported".to_owned(); + cannot be re-exported".to_owned(); let error_id = (DiagnosticMessageId::ErrorId(0), // no code?! Some(binding.span), msg.clone()); diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs index 32dc1067d37..5079ce77523 100644 --- a/src/librustc_trans/abi.rs +++ b/src/librustc_trans/abi.rs @@ -12,7 +12,7 @@ use llvm::{self, ValueRef, AttributePlace}; use base; use builder::Builder; use common::{ty_fn_sig, C_usize}; -use context::CrateContext; +use context::CodegenCx; use cabi_x86; use cabi_x86_64; use cabi_x86_win64; @@ -209,8 +209,8 @@ impl Reg { } impl Reg { - pub fn align(&self, ccx: &CrateContext) -> Align { - let dl = ccx.data_layout(); + pub fn align(&self, cx: &CodegenCx) -> Align { + let dl = cx.data_layout(); match self.kind { RegKind::Integer => { match self.size.bits() { @@ -234,18 +234,18 @@ impl Reg { } } - pub fn llvm_type(&self, ccx: &CrateContext) -> Type { + pub fn llvm_type(&self, cx: &CodegenCx) -> Type { match self.kind { - RegKind::Integer => Type::ix(ccx, self.size.bits()), + RegKind::Integer => Type::ix(cx, self.size.bits()), RegKind::Float => { match self.size.bits() { - 32 => Type::f32(ccx), - 64 => Type::f64(ccx), + 32 => Type::f32(cx), + 64 => Type::f64(cx), _ => bug!("unsupported float: {:?}", self) } } RegKind::Vector => { - Type::vector(&Type::i8(ccx), self.size.bytes()) + Type::vector(&Type::i8(cx), self.size.bytes()) } } } @@ -276,12 +276,12 @@ impl From<Reg> for Uniform { } impl Uniform { - pub fn align(&self, ccx: &CrateContext) -> Align { - self.unit.align(ccx) + pub fn align(&self, cx: &CodegenCx) -> Align { + self.unit.align(cx) } - pub fn llvm_type(&self, ccx: &CrateContext) -> Type { - let llunit = self.unit.llvm_type(ccx); + pub fn llvm_type(&self, cx: &CodegenCx) -> Type { + let llunit = self.unit.llvm_type(cx); if self.total <= self.unit.size { return llunit; @@ -298,16 +298,16 @@ impl Uniform { assert_eq!(self.unit.kind, RegKind::Integer); let args: Vec<_> = (0..count).map(|_| llunit) - .chain(iter::once(Type::ix(ccx, rem_bytes * 8))) + .chain(iter::once(Type::ix(cx, rem_bytes * 8))) .collect(); - Type::struct_(ccx, &args, false) + Type::struct_(cx, &args, false) } } pub trait LayoutExt<'tcx> { fn is_aggregate(&self) -> bool; - fn homogeneous_aggregate<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> Option<Reg>; + fn homogeneous_aggregate<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> Option<Reg>; } impl<'tcx> LayoutExt<'tcx> for TyLayout<'tcx> { @@ -321,7 +321,7 @@ impl<'tcx> LayoutExt<'tcx> for TyLayout<'tcx> { } } - fn homogeneous_aggregate<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> Option<Reg> { + fn homogeneous_aggregate<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> Option<Reg> { match self.abi { layout::Abi::Uninhabited => None, @@ -354,7 +354,7 @@ impl<'tcx> LayoutExt<'tcx> for TyLayout<'tcx> { let is_union = match self.fields { layout::FieldPlacement::Array { count, .. } => { if count > 0 { - return self.field(ccx, 0).homogeneous_aggregate(ccx); + return self.field(cx, 0).homogeneous_aggregate(cx); } else { return None; } @@ -368,8 +368,8 @@ impl<'tcx> LayoutExt<'tcx> for TyLayout<'tcx> { return None; } - let field = self.field(ccx, i); - match (result, field.homogeneous_aggregate(ccx)) { + let field = self.field(cx, i); + match (result, field.homogeneous_aggregate(cx)) { // The field itself must be a homogeneous aggregate. (_, None) => return None, // If this is the first field, record the unit. @@ -423,34 +423,34 @@ impl From<Uniform> for CastTarget { } impl CastTarget { - pub fn size(&self, ccx: &CrateContext) -> Size { + pub fn size(&self, cx: &CodegenCx) -> Size { match *self { CastTarget::Uniform(u) => u.total, CastTarget::Pair(a, b) => { - (a.size.abi_align(a.align(ccx)) + b.size) - .abi_align(self.align(ccx)) + (a.size.abi_align(a.align(cx)) + b.size) + .abi_align(self.align(cx)) } } } - pub fn align(&self, ccx: &CrateContext) -> Align { + pub fn align(&self, cx: &CodegenCx) -> Align { match *self { - CastTarget::Uniform(u) => u.align(ccx), + CastTarget::Uniform(u) => u.align(cx), CastTarget::Pair(a, b) => { - ccx.data_layout().aggregate_align - .max(a.align(ccx)) - .max(b.align(ccx)) + cx.data_layout().aggregate_align + .max(a.align(cx)) + .max(b.align(cx)) } } } - pub fn llvm_type(&self, ccx: &CrateContext) -> Type { + pub fn llvm_type(&self, cx: &CodegenCx) -> Type { match *self { - CastTarget::Uniform(u) => u.llvm_type(ccx), + CastTarget::Uniform(u) => u.llvm_type(cx), CastTarget::Pair(a, b) => { - Type::struct_(ccx, &[ - a.llvm_type(ccx), - b.llvm_type(ccx) + Type::struct_(cx, &[ + a.llvm_type(cx), + b.llvm_type(cx) ], false) } } @@ -547,28 +547,28 @@ impl<'a, 'tcx> ArgType<'tcx> { /// Get the LLVM type for an place of the original Rust type of /// this argument/return, i.e. the result of `type_of::type_of`. - pub fn memory_ty(&self, ccx: &CrateContext<'a, 'tcx>) -> Type { - self.layout.llvm_type(ccx) + pub fn memory_ty(&self, cx: &CodegenCx<'a, 'tcx>) -> Type { + self.layout.llvm_type(cx) } /// Store a direct/indirect value described by this ArgType into a /// place for the original Rust type of this argument/return. /// Can be used for both storing formal arguments into Rust variables /// or results of call/invoke instructions into their destinations. - pub fn store(&self, bcx: &Builder<'a, 'tcx>, val: ValueRef, dst: PlaceRef<'tcx>) { + pub fn store(&self, bx: &Builder<'a, 'tcx>, val: ValueRef, dst: PlaceRef<'tcx>) { if self.is_ignore() { return; } - let ccx = bcx.ccx; + let cx = bx.cx; if self.is_indirect() { - OperandValue::Ref(val, self.layout.align).store(bcx, dst) + OperandValue::Ref(val, self.layout.align).store(bx, dst) } else if let PassMode::Cast(cast) = self.mode { // FIXME(eddyb): Figure out when the simpler Store is safe, clang // uses it for i16 -> {i8, i8}, but not for i24 -> {i8, i8, i8}. let can_store_through_cast_ptr = false; if can_store_through_cast_ptr { - let cast_dst = bcx.pointercast(dst.llval, cast.llvm_type(ccx).ptr_to()); - bcx.store(val, cast_dst, self.layout.align); + let cast_dst = bx.pointercast(dst.llval, cast.llvm_type(cx).ptr_to()); + bx.store(val, cast_dst, self.layout.align); } else { // The actual return type is a struct, but the ABI // adaptation code has cast it into some scalar type. The @@ -585,44 +585,41 @@ impl<'a, 'tcx> ArgType<'tcx> { // bitcasting to the struct type yields invalid cast errors. // We instead thus allocate some scratch space... - let scratch_size = cast.size(ccx); - let scratch_align = cast.align(ccx); - let llscratch = bcx.alloca(cast.llvm_type(ccx), "abi_cast", scratch_align); - bcx.lifetime_start(llscratch, scratch_size); + let scratch_size = cast.size(cx); + let scratch_align = cast.align(cx); + let llscratch = bx.alloca(cast.llvm_type(cx), "abi_cast", scratch_align); + bx.lifetime_start(llscratch, scratch_size); // ...where we first store the value... - bcx.store(val, llscratch, scratch_align); + bx.store(val, llscratch, scratch_align); // ...and then memcpy it to the intended destination. - base::call_memcpy(bcx, - bcx.pointercast(dst.llval, Type::i8p(ccx)), - bcx.pointercast(llscratch, Type::i8p(ccx)), - C_usize(ccx, self.layout.size.bytes()), + base::call_memcpy(bx, + bx.pointercast(dst.llval, Type::i8p(cx)), + bx.pointercast(llscratch, Type::i8p(cx)), + C_usize(cx, self.layout.size.bytes()), self.layout.align.min(scratch_align)); - bcx.lifetime_end(llscratch, scratch_size); + bx.lifetime_end(llscratch, scratch_size); } } else { - OperandValue::Immediate(val).store(bcx, dst); + OperandValue::Immediate(val).store(bx, dst); } } - pub fn store_fn_arg(&self, bcx: &Builder<'a, 'tcx>, idx: &mut usize, dst: PlaceRef<'tcx>) { - if self.pad.is_some() { - *idx += 1; - } + pub fn store_fn_arg(&self, bx: &Builder<'a, 'tcx>, idx: &mut usize, dst: PlaceRef<'tcx>) { let mut next = || { - let val = llvm::get_param(bcx.llfn(), *idx as c_uint); + let val = llvm::get_param(bx.llfn(), *idx as c_uint); *idx += 1; val }; match self.mode { PassMode::Ignore => {}, PassMode::Pair(..) => { - OperandValue::Pair(next(), next()).store(bcx, dst); + OperandValue::Pair(next(), next()).store(bx, dst); } PassMode::Direct(_) | PassMode::Indirect(_) | PassMode::Cast(_) => { - self.store(bcx, next(), dst); + self.store(bx, next(), dst); } } } @@ -647,26 +644,26 @@ pub struct FnType<'tcx> { } impl<'a, 'tcx> FnType<'tcx> { - pub fn of_instance(ccx: &CrateContext<'a, 'tcx>, instance: &ty::Instance<'tcx>) + pub fn of_instance(cx: &CodegenCx<'a, 'tcx>, instance: &ty::Instance<'tcx>) -> Self { - let fn_ty = instance.ty(ccx.tcx()); - let sig = ty_fn_sig(ccx, fn_ty); - let sig = ccx.tcx().erase_late_bound_regions_and_normalize(&sig); - FnType::new(ccx, sig, &[]) + let fn_ty = instance.ty(cx.tcx); + let sig = ty_fn_sig(cx, fn_ty); + let sig = cx.tcx.erase_late_bound_regions_and_normalize(&sig); + FnType::new(cx, sig, &[]) } - pub fn new(ccx: &CrateContext<'a, 'tcx>, + pub fn new(cx: &CodegenCx<'a, 'tcx>, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> FnType<'tcx> { - let mut fn_ty = FnType::unadjusted(ccx, sig, extra_args); - fn_ty.adjust_for_abi(ccx, sig.abi); + let mut fn_ty = FnType::unadjusted(cx, sig, extra_args); + fn_ty.adjust_for_abi(cx, sig.abi); fn_ty } - pub fn new_vtable(ccx: &CrateContext<'a, 'tcx>, + pub fn new_vtable(cx: &CodegenCx<'a, 'tcx>, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> FnType<'tcx> { - let mut fn_ty = FnType::unadjusted(ccx, sig, extra_args); + let mut fn_ty = FnType::unadjusted(cx, sig, extra_args); // Don't pass the vtable, it's not an argument of the virtual fn. { let self_arg = &mut fn_ty.args[0]; @@ -681,20 +678,20 @@ impl<'a, 'tcx> FnType<'tcx> { .unwrap_or_else(|| { bug!("FnType::new_vtable: non-pointer self {:?}", self_arg) }).ty; - let fat_ptr_ty = ccx.tcx().mk_mut_ptr(pointee); - self_arg.layout = ccx.layout_of(fat_ptr_ty).field(ccx, 0); + let fat_ptr_ty = cx.tcx.mk_mut_ptr(pointee); + self_arg.layout = cx.layout_of(fat_ptr_ty).field(cx, 0); } - fn_ty.adjust_for_abi(ccx, sig.abi); + fn_ty.adjust_for_abi(cx, sig.abi); fn_ty } - pub fn unadjusted(ccx: &CrateContext<'a, 'tcx>, + pub fn unadjusted(cx: &CodegenCx<'a, 'tcx>, sig: ty::FnSig<'tcx>, extra_args: &[Ty<'tcx>]) -> FnType<'tcx> { debug!("FnType::unadjusted({:?}, {:?})", sig, extra_args); use self::Abi::*; - let cconv = match ccx.sess().target.target.adjust_abi(sig.abi) { + let cconv = match cx.sess().target.target.adjust_abi(sig.abi) { RustIntrinsic | PlatformIntrinsic | Rust | RustCall => llvm::CCallConv, @@ -737,7 +734,7 @@ impl<'a, 'tcx> FnType<'tcx> { extra_args }; - let target = &ccx.sess().target.target; + let target = &cx.sess().target.target; let win_x64_gnu = target.target_os == "windows" && target.arch == "x86_64" && target.target_env == "gnu"; @@ -772,7 +769,7 @@ impl<'a, 'tcx> FnType<'tcx> { } } - if let Some(pointee) = layout.pointee_info_at(ccx, offset) { + if let Some(pointee) = layout.pointee_info_at(cx, offset) { if let Some(kind) = pointee.safe { attrs.pointee_size = pointee.size; attrs.pointee_align = Some(pointee.align); @@ -809,7 +806,7 @@ impl<'a, 'tcx> FnType<'tcx> { }; let arg_of = |ty: Ty<'tcx>, is_return: bool| { - let mut arg = ArgType::new(ccx.layout_of(ty)); + let mut arg = ArgType::new(cx.layout_of(ty)); if arg.layout.is_zst() { // For some forsaken reason, x86_64-pc-windows-gnu // doesn't ignore zero-sized struct arguments. @@ -832,7 +829,7 @@ impl<'a, 'tcx> FnType<'tcx> { adjust_for_rust_scalar(&mut b_attrs, b, arg.layout, - a.value.size(ccx).abi_align(b.value.align(ccx)), + a.value.size(cx).abi_align(b.value.align(cx)), false); arg.mode = PassMode::Pair(a_attrs, b_attrs); return arg; @@ -863,7 +860,7 @@ impl<'a, 'tcx> FnType<'tcx> { } fn adjust_for_abi(&mut self, - ccx: &CrateContext<'a, 'tcx>, + cx: &CodegenCx<'a, 'tcx>, abi: Abi) { if abi == Abi::Unadjusted { return } @@ -878,7 +875,7 @@ impl<'a, 'tcx> FnType<'tcx> { } let size = arg.layout.size; - if size > layout::Pointer.size(ccx) { + if size > layout::Pointer.size(cx) { arg.make_indirect(); } else { // We want to pass small aggregates as immediates, but using @@ -900,38 +897,38 @@ impl<'a, 'tcx> FnType<'tcx> { return; } - match &ccx.sess().target.target.arch[..] { + match &cx.sess().target.target.arch[..] { "x86" => { let flavor = if abi == Abi::Fastcall { cabi_x86::Flavor::Fastcall } else { cabi_x86::Flavor::General }; - cabi_x86::compute_abi_info(ccx, self, flavor); + cabi_x86::compute_abi_info(cx, self, flavor); }, "x86_64" => if abi == Abi::SysV64 { - cabi_x86_64::compute_abi_info(ccx, self); - } else if abi == Abi::Win64 || ccx.sess().target.target.options.is_like_windows { + cabi_x86_64::compute_abi_info(cx, self); + } else if abi == Abi::Win64 || cx.sess().target.target.options.is_like_windows { cabi_x86_win64::compute_abi_info(self); } else { - cabi_x86_64::compute_abi_info(ccx, self); + cabi_x86_64::compute_abi_info(cx, self); }, - "aarch64" => cabi_aarch64::compute_abi_info(ccx, self), - "arm" => cabi_arm::compute_abi_info(ccx, self), - "mips" => cabi_mips::compute_abi_info(ccx, self), - "mips64" => cabi_mips64::compute_abi_info(ccx, self), - "powerpc" => cabi_powerpc::compute_abi_info(ccx, self), - "powerpc64" => cabi_powerpc64::compute_abi_info(ccx, self), - "s390x" => cabi_s390x::compute_abi_info(ccx, self), - "asmjs" => cabi_asmjs::compute_abi_info(ccx, self), - "wasm32" => cabi_asmjs::compute_abi_info(ccx, self), + "aarch64" => cabi_aarch64::compute_abi_info(cx, self), + "arm" => cabi_arm::compute_abi_info(cx, self), + "mips" => cabi_mips::compute_abi_info(cx, self), + "mips64" => cabi_mips64::compute_abi_info(cx, self), + "powerpc" => cabi_powerpc::compute_abi_info(cx, self), + "powerpc64" => cabi_powerpc64::compute_abi_info(cx, self), + "s390x" => cabi_s390x::compute_abi_info(cx, self), + "asmjs" => cabi_asmjs::compute_abi_info(cx, self), + "wasm32" => cabi_asmjs::compute_abi_info(cx, self), "msp430" => cabi_msp430::compute_abi_info(self), - "sparc" => cabi_sparc::compute_abi_info(ccx, self), - "sparc64" => cabi_sparc64::compute_abi_info(ccx, self), + "sparc" => cabi_sparc::compute_abi_info(cx, self), + "sparc64" => cabi_sparc64::compute_abi_info(cx, self), "nvptx" => cabi_nvptx::compute_abi_info(self), "nvptx64" => cabi_nvptx64::compute_abi_info(self), "hexagon" => cabi_hexagon::compute_abi_info(self), - a => ccx.sess().fatal(&format!("unrecognized arch \"{}\" in target specification", a)) + a => cx.sess().fatal(&format!("unrecognized arch \"{}\" in target specification", a)) } if let PassMode::Indirect(ref mut attrs) = self.ret.mode { @@ -939,37 +936,37 @@ impl<'a, 'tcx> FnType<'tcx> { } } - pub fn llvm_type(&self, ccx: &CrateContext<'a, 'tcx>) -> Type { + pub fn llvm_type(&self, cx: &CodegenCx<'a, 'tcx>) -> Type { let mut llargument_tys = Vec::new(); let llreturn_ty = match self.ret.mode { - PassMode::Ignore => Type::void(ccx), + PassMode::Ignore => Type::void(cx), PassMode::Direct(_) | PassMode::Pair(..) => { - self.ret.layout.immediate_llvm_type(ccx) + self.ret.layout.immediate_llvm_type(cx) } - PassMode::Cast(cast) => cast.llvm_type(ccx), + PassMode::Cast(cast) => cast.llvm_type(cx), PassMode::Indirect(_) => { - llargument_tys.push(self.ret.memory_ty(ccx).ptr_to()); - Type::void(ccx) + llargument_tys.push(self.ret.memory_ty(cx).ptr_to()); + Type::void(cx) } }; for arg in &self.args { // add padding if let Some(ty) = arg.pad { - llargument_tys.push(ty.llvm_type(ccx)); + llargument_tys.push(ty.llvm_type(cx)); } let llarg_ty = match arg.mode { PassMode::Ignore => continue, - PassMode::Direct(_) => arg.layout.immediate_llvm_type(ccx), + PassMode::Direct(_) => arg.layout.immediate_llvm_type(cx), PassMode::Pair(..) => { - llargument_tys.push(arg.layout.scalar_pair_element_llvm_type(ccx, 0)); - llargument_tys.push(arg.layout.scalar_pair_element_llvm_type(ccx, 1)); + llargument_tys.push(arg.layout.scalar_pair_element_llvm_type(cx, 0)); + llargument_tys.push(arg.layout.scalar_pair_element_llvm_type(cx, 1)); continue; } - PassMode::Cast(cast) => cast.llvm_type(ccx), - PassMode::Indirect(_) => arg.memory_ty(ccx).ptr_to(), + PassMode::Cast(cast) => cast.llvm_type(cx), + PassMode::Indirect(_) => arg.memory_ty(cx).ptr_to(), }; llargument_tys.push(llarg_ty); } diff --git a/src/librustc_trans/allocator.rs b/src/librustc_trans/allocator.rs index 9abb6d66f9c..fd5aa1364d3 100644 --- a/src/librustc_trans/allocator.rs +++ b/src/librustc_trans/allocator.rs @@ -19,7 +19,7 @@ use rustc_allocator::{ALLOCATOR_METHODS, AllocatorTy}; use ModuleLlvm; use llvm::{self, False, True}; -pub unsafe fn trans(tcx: TyCtxt, mods: &ModuleLlvm, kind: AllocatorKind) { +pub(crate) unsafe fn trans(tcx: TyCtxt, mods: &ModuleLlvm, kind: AllocatorKind) { let llcx = mods.llcx; let llmod = mods.llmod; let usize = match &tcx.sess.target.target.target_pointer_width[..] { diff --git a/src/librustc_trans/asm.rs b/src/librustc_trans/asm.rs index ef76fece088..c7be0c4e67d 100644 --- a/src/librustc_trans/asm.rs +++ b/src/librustc_trans/asm.rs @@ -27,7 +27,7 @@ use libc::{c_uint, c_char}; // Take an inline assembly expression and splat it out via LLVM pub fn trans_inline_asm<'a, 'tcx>( - bcx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'tcx>, ia: &hir::InlineAsm, outputs: Vec<PlaceRef<'tcx>>, mut inputs: Vec<ValueRef> @@ -39,13 +39,13 @@ pub fn trans_inline_asm<'a, 'tcx>( let mut indirect_outputs = vec![]; for (i, (out, place)) in ia.outputs.iter().zip(&outputs).enumerate() { if out.is_rw { - inputs.push(place.load(bcx).immediate()); + inputs.push(place.load(bx).immediate()); ext_constraints.push(i.to_string()); } if out.is_indirect { - indirect_outputs.push(place.load(bcx).immediate()); + indirect_outputs.push(place.load(bx).immediate()); } else { - output_types.push(place.layout.llvm_type(bcx.ccx)); + output_types.push(place.layout.llvm_type(bx.cx)); } } if !indirect_outputs.is_empty() { @@ -58,7 +58,7 @@ pub fn trans_inline_asm<'a, 'tcx>( // Default per-arch clobbers // Basically what clang does - let arch_clobbers = match &bcx.sess().target.target.arch[..] { + let arch_clobbers = match &bx.sess().target.target.arch[..] { "x86" | "x86_64" => vec!["~{dirflag}", "~{fpsr}", "~{flags}"], _ => Vec::new() }; @@ -76,9 +76,9 @@ pub fn trans_inline_asm<'a, 'tcx>( // Depending on how many outputs we have, the return type is different let num_outputs = output_types.len(); let output_type = match num_outputs { - 0 => Type::void(bcx.ccx), + 0 => Type::void(bx.cx), 1 => output_types[0], - _ => Type::struct_(bcx.ccx, &output_types, false) + _ => Type::struct_(bx.cx, &output_types, false) }; let dialect = match ia.dialect { @@ -88,7 +88,7 @@ pub fn trans_inline_asm<'a, 'tcx>( let asm = CString::new(ia.asm.as_str().as_bytes()).unwrap(); let constraint_cstr = CString::new(all_constraints).unwrap(); - let r = bcx.inline_asm_call( + let r = bx.inline_asm_call( asm.as_ptr(), constraint_cstr.as_ptr(), &inputs, @@ -101,28 +101,28 @@ pub fn trans_inline_asm<'a, 'tcx>( // Again, based on how many outputs we have let outputs = ia.outputs.iter().zip(&outputs).filter(|&(ref o, _)| !o.is_indirect); for (i, (_, &place)) in outputs.enumerate() { - let v = if num_outputs == 1 { r } else { bcx.extract_value(r, i as u64) }; - OperandValue::Immediate(v).store(bcx, place); + let v = if num_outputs == 1 { r } else { bx.extract_value(r, i as u64) }; + OperandValue::Immediate(v).store(bx, place); } // Store mark in a metadata node so we can map LLVM errors // back to source locations. See #17552. unsafe { let key = "srcloc"; - let kind = llvm::LLVMGetMDKindIDInContext(bcx.ccx.llcx(), + let kind = llvm::LLVMGetMDKindIDInContext(bx.cx.llcx, key.as_ptr() as *const c_char, key.len() as c_uint); - let val: llvm::ValueRef = C_i32(bcx.ccx, ia.ctxt.outer().as_u32() as i32); + let val: llvm::ValueRef = C_i32(bx.cx, ia.ctxt.outer().as_u32() as i32); llvm::LLVMSetMetadata(r, kind, - llvm::LLVMMDNodeInContext(bcx.ccx.llcx(), &val, 1)); + llvm::LLVMMDNodeInContext(bx.cx.llcx, &val, 1)); } } -pub fn trans_global_asm<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, +pub fn trans_global_asm<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ga: &hir::GlobalAsm) { let asm = CString::new(ga.asm.as_str().as_bytes()).unwrap(); unsafe { - llvm::LLVMRustAppendModuleInlineAsm(ccx.llmod(), asm.as_ptr()); + llvm::LLVMRustAppendModuleInlineAsm(cx.llmod, asm.as_ptr()); } } diff --git a/src/librustc_trans/attributes.rs b/src/librustc_trans/attributes.rs index f3105e03523..6c8088375c4 100644 --- a/src/librustc_trans/attributes.rs +++ b/src/librustc_trans/attributes.rs @@ -24,7 +24,7 @@ use llvm::AttributePlace::Function; use llvm_util; pub use syntax::attr::{self, InlineAttr}; use syntax::ast; -use context::CrateContext; +use context::CodegenCx; /// Mark LLVM function to use provided inline heuristic. #[inline] @@ -67,27 +67,27 @@ pub fn naked(val: ValueRef, is_naked: bool) { Attribute::Naked.toggle_llfn(Function, val, is_naked); } -pub fn set_frame_pointer_elimination(ccx: &CrateContext, llfn: ValueRef) { +pub fn set_frame_pointer_elimination(cx: &CodegenCx, llfn: ValueRef) { // FIXME: #11906: Omitting frame pointers breaks retrieving the value of a // parameter. - if ccx.sess().must_not_eliminate_frame_pointers() { + if cx.sess().must_not_eliminate_frame_pointers() { llvm::AddFunctionAttrStringValue( llfn, llvm::AttributePlace::Function, cstr("no-frame-pointer-elim\0"), cstr("true\0")); } } -pub fn set_probestack(ccx: &CrateContext, llfn: ValueRef) { +pub fn set_probestack(cx: &CodegenCx, llfn: ValueRef) { // Only use stack probes if the target specification indicates that we // should be using stack probes - if !ccx.sess().target.target.options.stack_probes { + if !cx.sess().target.target.options.stack_probes { return } // Currently stack probes seem somewhat incompatible with the address // sanitizer. With asan we're already protected from stack overflow anyway // so we don't really need stack probes regardless. - match ccx.sess().opts.debugging_opts.sanitizer { + match cx.sess().opts.debugging_opts.sanitizer { Some(Sanitizer::Address) => return, _ => {} } @@ -101,13 +101,13 @@ pub fn set_probestack(ccx: &CrateContext, llfn: ValueRef) { /// Composite function which sets LLVM attributes for function depending on its AST (#[attribute]) /// attributes. -pub fn from_fn_attrs(ccx: &CrateContext, llfn: ValueRef, id: DefId) { +pub fn from_fn_attrs(cx: &CodegenCx, llfn: ValueRef, id: DefId) { use syntax::attr::*; - let attrs = ccx.tcx().get_attrs(id); - inline(llfn, find_inline_attr(Some(ccx.sess().diagnostic()), &attrs)); + let attrs = cx.tcx.get_attrs(id); + inline(llfn, find_inline_attr(Some(cx.sess().diagnostic()), &attrs)); - set_frame_pointer_elimination(ccx, llfn); - set_probestack(ccx, llfn); + set_frame_pointer_elimination(cx, llfn); + set_probestack(cx, llfn); for attr in attrs.iter() { if attr.check_name("cold") { @@ -124,7 +124,7 @@ pub fn from_fn_attrs(ccx: &CrateContext, llfn: ValueRef, id: DefId) { } } - let target_features = ccx.tcx().target_features_enabled(id); + let target_features = cx.tcx.target_features_enabled(id); if !target_features.is_empty() { let val = CString::new(target_features.join(",")).unwrap(); llvm::AddFunctionAttrStringValue( diff --git a/src/librustc_trans/back/command.rs b/src/librustc_trans/back/command.rs index ea68e3b28b6..3b765a493e0 100644 --- a/src/librustc_trans/back/command.rs +++ b/src/librustc_trans/back/command.rs @@ -14,22 +14,34 @@ use std::ffi::{OsStr, OsString}; use std::fmt; use std::io; -use std::process::{self, Output, Child}; +use std::mem; +use std::process::{self, Output}; +#[derive(Clone)] pub struct Command { - program: OsString, + program: Program, args: Vec<OsString>, env: Vec<(OsString, OsString)>, } +#[derive(Clone)] +enum Program { + Normal(OsString), + CmdBatScript(OsString), +} + impl Command { pub fn new<P: AsRef<OsStr>>(program: P) -> Command { - Command::_new(program.as_ref()) + Command::_new(Program::Normal(program.as_ref().to_owned())) + } + + pub fn bat_script<P: AsRef<OsStr>>(program: P) -> Command { + Command::_new(Program::CmdBatScript(program.as_ref().to_owned())) } - fn _new(program: &OsStr) -> Command { + fn _new(program: Program) -> Command { Command { - program: program.to_owned(), + program, args: Vec::new(), env: Vec::new(), } @@ -81,12 +93,15 @@ impl Command { self.command().output() } - pub fn spawn(&mut self) -> io::Result<Child> { - self.command().spawn() - } - pub fn command(&self) -> process::Command { - let mut ret = process::Command::new(&self.program); + let mut ret = match self.program { + Program::Normal(ref p) => process::Command::new(p), + Program::CmdBatScript(ref p) => { + let mut c = process::Command::new("cmd"); + c.arg("/c").arg(p); + c + } + }; ret.args(&self.args); ret.envs(self.env.clone()); return ret @@ -94,16 +109,45 @@ impl Command { // extensions - pub fn get_program(&self) -> &OsStr { - &self.program + pub fn take_args(&mut self) -> Vec<OsString> { + mem::replace(&mut self.args, Vec::new()) } - pub fn get_args(&self) -> &[OsString] { - &self.args - } + /// Returns a `true` if we're pretty sure that this'll blow OS spawn limits, + /// or `false` if we should attempt to spawn and see what the OS says. + pub fn very_likely_to_exceed_some_spawn_limit(&self) -> bool { + // We mostly only care about Windows in this method, on Unix the limits + // can be gargantuan anyway so we're pretty unlikely to hit them + if cfg!(unix) { + return false + } - pub fn get_env(&self) -> &[(OsString, OsString)] { - &self.env + // Ok so on Windows to spawn a process is 32,768 characters in its + // command line [1]. Unfortunately we don't actually have access to that + // as it's calculated just before spawning. Instead we perform a + // poor-man's guess as to how long our command line will be. We're + // assuming here that we don't have to escape every character... + // + // Turns out though that `cmd.exe` has even smaller limits, 8192 + // characters [2]. Linkers can often be batch scripts (for example + // Emscripten, Gecko's current build system) which means that we're + // running through batch scripts. These linkers often just forward + // arguments elsewhere (and maybe tack on more), so if we blow 8192 + // bytes we'll typically cause them to blow as well. + // + // Basically as a result just perform an inflated estimate of what our + // command line will look like and test if it's > 8192 (we actually + // test against 6k to artificially inflate our estimate). If all else + // fails we'll fall back to the normal unix logic of testing the OS + // error code if we fail to spawn and automatically re-spawning the + // linker with smaller arguments. + // + // [1]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx + // [2]: https://blogs.msdn.microsoft.com/oldnewthing/20031210-00/?p=41553 + + let estimated_command_line_len = + self.args.iter().map(|a| a.len()).sum::<usize>(); + estimated_command_line_len > 1024 * 6 } } diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 13a319d31bf..923e5549927 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -36,8 +36,8 @@ use std::char; use std::env; use std::ffi::OsString; use std::fmt; -use std::fs::{self, File}; -use std::io::{self, Write, BufWriter}; +use std::fs; +use std::io; use std::path::{Path, PathBuf}; use std::process::{Output, Stdio}; use std::str; @@ -69,13 +69,12 @@ pub fn get_linker(sess: &Session) -> (PathBuf, Command, Vec<(OsString, OsString) // was tagged as #42791) and some more info can be found on #44443 for // emscripten itself. let cmd = |linker: &Path| { - if cfg!(windows) && linker.ends_with(".bat") { - let mut cmd = Command::new("cmd"); - cmd.arg("/c").arg(linker); - cmd - } else { - Command::new(linker) + if let Some(linker) = linker.to_str() { + if cfg!(windows) && linker.ends_with(".bat") { + return Command::bat_script(linker) + } } + Command::new(linker) }; if let Some(ref linker) = sess.opts.cg.linker { @@ -140,10 +139,10 @@ pub fn remove(sess: &Session, path: &Path) { /// Perform the linkage portion of the compilation phase. This will generate all /// of the requested outputs for this compilation session. -pub fn link_binary(sess: &Session, - trans: &CrateTranslation, - outputs: &OutputFilenames, - crate_name: &str) -> Vec<PathBuf> { +pub(crate) fn link_binary(sess: &Session, + trans: &CrateTranslation, + outputs: &OutputFilenames, + crate_name: &str) -> Vec<PathBuf> { let mut out_filenames = Vec::new(); for &crate_type in sess.crate_types.borrow().iter() { // Ignore executable crates if we have -Z no-trans, as they will error. @@ -200,9 +199,9 @@ fn filename_for_metadata(sess: &Session, crate_name: &str, outputs: &OutputFilen out_filename } -pub fn each_linked_rlib(sess: &Session, - info: &CrateInfo, - f: &mut FnMut(CrateNum, &Path)) -> Result<(), String> { +pub(crate) fn each_linked_rlib(sess: &Session, + info: &CrateInfo, + f: &mut FnMut(CrateNum, &Path)) -> Result<(), String> { let crates = info.used_crates_static.iter(); let fmts = sess.dependency_formats.borrow(); let fmts = fmts.get(&config::CrateTypeExecutable) @@ -246,7 +245,7 @@ pub fn each_linked_rlib(sess: &Session, /// It's unusual for a crate to not participate in LTO. Typically only /// compiler-specific and unstable crates have a reason to not participate in /// LTO. -pub fn ignored_for_lto(sess: &Session, info: &CrateInfo, cnum: CrateNum) -> bool { +pub(crate) fn ignored_for_lto(sess: &Session, info: &CrateInfo, cnum: CrateNum) -> bool { // If our target enables builtin function lowering in LLVM then the // crates providing these functions don't participate in LTO (e.g. // no_builtins or compiler builtins crates). @@ -757,26 +756,26 @@ fn exec_linker(sess: &Session, cmd: &mut Command, tmpdir: &Path) // that contains all the arguments. The theory is that this is then // accepted on all linkers and the linker will read all its options out of // there instead of looking at the command line. - match cmd.command().stdout(Stdio::piped()).stderr(Stdio::piped()).spawn() { - Ok(child) => return child.wait_with_output(), - Err(ref e) if command_line_too_big(e) => {} - Err(e) => return Err(e) + if !cmd.very_likely_to_exceed_some_spawn_limit() { + match cmd.command().stdout(Stdio::piped()).stderr(Stdio::piped()).spawn() { + Ok(child) => return child.wait_with_output(), + Err(ref e) if command_line_too_big(e) => {} + Err(e) => return Err(e) + } } - let file = tmpdir.join("linker-arguments"); - let mut cmd2 = Command::new(cmd.get_program()); - cmd2.arg(format!("@{}", file.display())); - for &(ref k, ref v) in cmd.get_env() { - cmd2.env(k, v); - } - let mut f = BufWriter::new(File::create(&file)?); - for arg in cmd.get_args() { - writeln!(f, "{}", Escape { + let mut cmd2 = cmd.clone(); + let mut args = String::new(); + for arg in cmd2.take_args() { + args.push_str(&Escape { arg: arg.to_str().unwrap(), is_like_msvc: sess.target.target.options.is_like_msvc, - })?; + }.to_string()); + args.push_str("\n"); } - f.into_inner()?; + let file = tmpdir.join("linker-arguments"); + fs::write(&file, args.as_bytes())?; + cmd2.arg(format!("@{}", file.display())); return cmd2.output(); #[cfg(unix)] diff --git a/src/librustc_trans/back/lto.rs b/src/librustc_trans/back/lto.rs index 60b24a578c6..b612247ffcd 100644 --- a/src/librustc_trans/back/lto.rs +++ b/src/librustc_trans/back/lto.rs @@ -42,7 +42,7 @@ pub fn crate_type_allows_lto(crate_type: config::CrateType) -> bool { } } -pub enum LtoModuleTranslation { +pub(crate) enum LtoModuleTranslation { Fat { module: Option<ModuleTranslation>, _serialized_bitcode: Vec<SerializedModule>, @@ -65,9 +65,9 @@ impl LtoModuleTranslation { /// points to LLVM data structures owned by this `LtoModuleTranslation`. /// It's intended that the module returned is immediately code generated and /// dropped, and then this LTO module is dropped. - pub unsafe fn optimize(&mut self, - cgcx: &CodegenContext, - timeline: &mut Timeline) + pub(crate) unsafe fn optimize(&mut self, + cgcx: &CodegenContext, + timeline: &mut Timeline) -> Result<ModuleTranslation, FatalError> { match *self { @@ -100,7 +100,7 @@ pub enum LTOMode { JustThisCrate, } -pub fn run(cgcx: &CodegenContext, +pub(crate) fn run(cgcx: &CodegenContext, modules: Vec<ModuleTranslation>, mode: LTOMode, timeline: &mut Timeline) diff --git a/src/librustc_trans/back/symbol_export.rs b/src/librustc_trans/back/symbol_export.rs index fa6fe2e9e93..15ff59c7df9 100644 --- a/src/librustc_trans/back/symbol_export.rs +++ b/src/librustc_trans/back/symbol_export.rs @@ -115,9 +115,8 @@ pub fn provide(providers: &mut Providers) { if let Some(id) = tcx.sess.derive_registrar_fn.get() { let def_id = tcx.hir.local_def_id(id); - let idx = def_id.index; let disambiguator = tcx.sess.local_crate_disambiguator(); - let registrar = tcx.sess.generate_derive_registrar_symbol(disambiguator, idx); + let registrar = tcx.sess.generate_derive_registrar_symbol(disambiguator); local_crate.push((registrar, Some(def_id), SymbolExportLevel::C)); } diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 1ee04a46243..a013af7a460 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -363,7 +363,7 @@ impl CodegenContext { Handler::with_emitter(true, false, Box::new(self.diag_emitter.clone())) } - pub fn config(&self, kind: ModuleKind) -> &ModuleConfig { + pub(crate) fn config(&self, kind: ModuleKind) -> &ModuleConfig { match kind { ModuleKind::Regular => &self.regular_module_config, ModuleKind::Metadata => &self.metadata_module_config, @@ -371,7 +371,7 @@ impl CodegenContext { } } - pub fn save_temp_bitcode(&self, trans: &ModuleTranslation, name: &str) { + pub(crate) fn save_temp_bitcode(&self, trans: &ModuleTranslation, name: &str) { if !self.save_temps { return } @@ -822,7 +822,7 @@ fn binaryen_assemble(cgcx: &CodegenContext, } } -pub struct CompiledModules { +pub(crate) struct CompiledModules { pub modules: Vec<CompiledModule>, pub metadata_module: CompiledModule, pub allocator_module: Option<CompiledModule>, @@ -1162,7 +1162,7 @@ fn produce_final_output_artifacts(sess: &Session, // These are used in linking steps and will be cleaned up afterward. } -pub fn dump_incremental_data(trans: &CrateTranslation) { +pub(crate) fn dump_incremental_data(trans: &CrateTranslation) { println!("[incremental] Re-using {} out of {} modules", trans.modules.iter().filter(|m| m.pre_existing).count(), trans.modules.len()); @@ -1360,15 +1360,10 @@ fn start_executing_work(tcx: TyCtxt, let sess = tcx.sess; // First up, convert our jobserver into a helper thread so we can use normal - // mpsc channels to manage our messages and such. Once we've got the helper - // thread then request `n-1` tokens because all of our work items are ready - // to go. - // - // Note that the `n-1` is here because we ourselves have a token (our - // process) and we'll use that token to execute at least one unit of work. - // - // After we've requested all these tokens then we'll, when we can, get - // tokens on `rx` above which will get managed in the main loop below. + // mpsc channels to manage our messages and such. + // After we've requested tokens then we'll, when we can, + // get tokens on `coordinator_receive` which will + // get managed in the main loop below. let coordinator_send2 = coordinator_send.clone(); let helper = jobserver.into_helper_thread(move |token| { drop(coordinator_send2.send(Box::new(Message::Token(token)))); @@ -2149,7 +2144,7 @@ pub struct OngoingCrateTranslation { } impl OngoingCrateTranslation { - pub fn join(self, sess: &Session, dep_graph: &DepGraph) -> CrateTranslation { + pub(crate) fn join(self, sess: &Session, dep_graph: &DepGraph) -> CrateTranslation { self.shared_emitter_main.check(sess, true); let compiled_modules = match self.future.join() { Ok(Ok(compiled_modules)) => compiled_modules, @@ -2217,9 +2212,9 @@ impl OngoingCrateTranslation { trans } - pub fn submit_pre_translated_module_to_llvm(&self, - tcx: TyCtxt, - mtrans: ModuleTranslation) { + pub(crate) fn submit_pre_translated_module_to_llvm(&self, + tcx: TyCtxt, + mtrans: ModuleTranslation) { self.wait_for_signal_to_translate_item(); self.check_for_errors(tcx.sess); @@ -2252,9 +2247,9 @@ impl OngoingCrateTranslation { } } -pub fn submit_translated_module_to_llvm(tcx: TyCtxt, - mtrans: ModuleTranslation, - cost: u64) { +pub(crate) fn submit_translated_module_to_llvm(tcx: TyCtxt, + mtrans: ModuleTranslation, + cost: u64) { let llvm_work_item = WorkItem::Optimize(mtrans); drop(tcx.tx_to_llvm_workers.send(Box::new(Message::TranslationDone { llvm_work_item, diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 7bb81e9da34..734ad8f3929 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -29,7 +29,6 @@ use super::ModuleTranslation; use super::ModuleKind; use abi; -use assert_module_sources; use back::link; use back::symbol_export; use back::write::{self, OngoingCrateTranslation, create_target_machine}; @@ -57,16 +56,16 @@ use builder::Builder; use callee; use common::{C_bool, C_bytes_in_context, C_i32, C_usize}; use rustc_mir::monomorphize::collector::{self, MonoItemCollectionMode}; -use common::{self, C_struct_in_context, C_array, CrateContext, val_ty}; +use common::{self, C_struct_in_context, C_array, val_ty}; use consts; -use context::{self, LocalCrateContext, SharedCrateContext}; +use context::{self, CodegenCx}; use debuginfo; use declare; use meth; use mir; use monomorphize::Instance; use monomorphize::partitioning::{self, PartitioningStrategy, CodegenUnit, CodegenUnitExt}; -use symbol_names_test; +use rustc_trans_utils::symbol_names_test; use time_graph; use trans_item::{MonoItem, BaseMonoItemExt, MonoItemExt, DefPathBasedNames}; use type_::Type; @@ -94,16 +93,16 @@ pub use rustc_trans_utils::{find_exported_symbols, check_for_rustc_errors_attr}; pub use rustc_mir::monomorphize::item::linkage_by_name; pub struct StatRecorder<'a, 'tcx: 'a> { - ccx: &'a CrateContext<'a, 'tcx>, + cx: &'a CodegenCx<'a, 'tcx>, name: Option<String>, istart: usize, } impl<'a, 'tcx> StatRecorder<'a, 'tcx> { - pub fn new(ccx: &'a CrateContext<'a, 'tcx>, name: String) -> StatRecorder<'a, 'tcx> { - let istart = ccx.stats().borrow().n_llvm_insns; + pub fn new(cx: &'a CodegenCx<'a, 'tcx>, name: String) -> StatRecorder<'a, 'tcx> { + let istart = cx.stats.borrow().n_llvm_insns; StatRecorder { - ccx, + cx, name: Some(name), istart, } @@ -112,8 +111,8 @@ impl<'a, 'tcx> StatRecorder<'a, 'tcx> { impl<'a, 'tcx> Drop for StatRecorder<'a, 'tcx> { fn drop(&mut self) { - if self.ccx.sess().trans_stats() { - let mut stats = self.ccx.stats().borrow_mut(); + if self.cx.sess().trans_stats() { + let mut stats = self.cx.stats.borrow_mut(); let iend = stats.n_llvm_insns; stats.fn_stats.push((self.name.take().unwrap(), iend - self.istart)); stats.n_fns += 1; @@ -158,7 +157,7 @@ pub fn bin_op_to_fcmp_predicate(op: hir::BinOp_) -> llvm::RealPredicate { } pub fn compare_simd_types<'a, 'tcx>( - bcx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'tcx>, lhs: ValueRef, rhs: ValueRef, t: Ty<'tcx>, @@ -168,7 +167,7 @@ pub fn compare_simd_types<'a, 'tcx>( let signed = match t.sty { ty::TyFloat(_) => { let cmp = bin_op_to_fcmp_predicate(op); - return bcx.sext(bcx.fcmp(cmp, lhs, rhs), ret_ty); + return bx.sext(bx.fcmp(cmp, lhs, rhs), ret_ty); }, ty::TyUint(_) => false, ty::TyInt(_) => true, @@ -180,7 +179,7 @@ pub fn compare_simd_types<'a, 'tcx>( // to get the correctly sized type. This will compile to a single instruction // once the IR is converted to assembly if the SIMD instruction is supported // by the target architecture. - bcx.sext(bcx.icmp(cmp, lhs, rhs), ret_ty) + bx.sext(bx.icmp(cmp, lhs, rhs), ret_ty) } /// Retrieve the information we are losing (making dynamic) in an unsizing @@ -189,15 +188,15 @@ pub fn compare_simd_types<'a, 'tcx>( /// The `old_info` argument is a bit funny. It is intended for use /// in an upcast, where the new vtable for an object will be derived /// from the old one. -pub fn unsized_info<'ccx, 'tcx>(ccx: &CrateContext<'ccx, 'tcx>, +pub fn unsized_info<'cx, 'tcx>(cx: &CodegenCx<'cx, 'tcx>, source: Ty<'tcx>, target: Ty<'tcx>, old_info: Option<ValueRef>) -> ValueRef { - let (source, target) = ccx.tcx().struct_lockstep_tails(source, target); + let (source, target) = cx.tcx.struct_lockstep_tails(source, target); match (&source.sty, &target.sty) { (&ty::TyArray(_, len), &ty::TySlice(_)) => { - C_usize(ccx, len.val.to_const_int().unwrap().to_u64().unwrap()) + C_usize(cx, len.val.to_const_int().unwrap().to_u64().unwrap()) } (&ty::TyDynamic(..), &ty::TyDynamic(..)) => { // For now, upcasts are limited to changes in marker @@ -206,10 +205,10 @@ pub fn unsized_info<'ccx, 'tcx>(ccx: &CrateContext<'ccx, 'tcx>, old_info.expect("unsized_info: missing old info for trait upcast") } (_, &ty::TyDynamic(ref data, ..)) => { - let vtable_ptr = ccx.layout_of(ccx.tcx().mk_mut_ptr(target)) - .field(ccx, abi::FAT_PTR_EXTRA); - consts::ptrcast(meth::get_vtable(ccx, source, data.principal()), - vtable_ptr.llvm_type(ccx)) + let vtable_ptr = cx.layout_of(cx.tcx.mk_mut_ptr(target)) + .field(cx, abi::FAT_PTR_EXTRA); + consts::ptrcast(meth::get_vtable(cx, source, data.principal()), + vtable_ptr.llvm_type(cx)) } _ => bug!("unsized_info: invalid unsizing {:?} -> {:?}", source, @@ -219,7 +218,7 @@ pub fn unsized_info<'ccx, 'tcx>(ccx: &CrateContext<'ccx, 'tcx>, /// Coerce `src` to `dst_ty`. `src_ty` must be a thin pointer. pub fn unsize_thin_ptr<'a, 'tcx>( - bcx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'tcx>, src: ValueRef, src_ty: Ty<'tcx>, dst_ty: Ty<'tcx> @@ -232,24 +231,24 @@ pub fn unsize_thin_ptr<'a, 'tcx>( &ty::TyRawPtr(ty::TypeAndMut { ty: b, .. })) | (&ty::TyRawPtr(ty::TypeAndMut { ty: a, .. }), &ty::TyRawPtr(ty::TypeAndMut { ty: b, .. })) => { - assert!(bcx.ccx.shared().type_is_sized(a)); - let ptr_ty = bcx.ccx.layout_of(b).llvm_type(bcx.ccx).ptr_to(); - (bcx.pointercast(src, ptr_ty), unsized_info(bcx.ccx, a, b, None)) + assert!(bx.cx.type_is_sized(a)); + let ptr_ty = bx.cx.layout_of(b).llvm_type(bx.cx).ptr_to(); + (bx.pointercast(src, ptr_ty), unsized_info(bx.cx, a, b, None)) } (&ty::TyAdt(def_a, _), &ty::TyAdt(def_b, _)) if def_a.is_box() && def_b.is_box() => { let (a, b) = (src_ty.boxed_ty(), dst_ty.boxed_ty()); - assert!(bcx.ccx.shared().type_is_sized(a)); - let ptr_ty = bcx.ccx.layout_of(b).llvm_type(bcx.ccx).ptr_to(); - (bcx.pointercast(src, ptr_ty), unsized_info(bcx.ccx, a, b, None)) + assert!(bx.cx.type_is_sized(a)); + let ptr_ty = bx.cx.layout_of(b).llvm_type(bx.cx).ptr_to(); + (bx.pointercast(src, ptr_ty), unsized_info(bx.cx, a, b, None)) } (&ty::TyAdt(def_a, _), &ty::TyAdt(def_b, _)) => { assert_eq!(def_a, def_b); - let src_layout = bcx.ccx.layout_of(src_ty); - let dst_layout = bcx.ccx.layout_of(dst_ty); + let src_layout = bx.cx.layout_of(src_ty); + let dst_layout = bx.cx.layout_of(dst_ty); let mut result = None; for i in 0..src_layout.fields.count() { - let src_f = src_layout.field(bcx.ccx, i); + let src_f = src_layout.field(bx.cx, i); assert_eq!(src_layout.fields.offset(i).bytes(), 0); assert_eq!(dst_layout.fields.offset(i).bytes(), 0); if src_f.is_zst() { @@ -257,15 +256,15 @@ pub fn unsize_thin_ptr<'a, 'tcx>( } assert_eq!(src_layout.size, src_f.size); - let dst_f = dst_layout.field(bcx.ccx, i); + let dst_f = dst_layout.field(bx.cx, i); assert_ne!(src_f.ty, dst_f.ty); assert_eq!(result, None); - result = Some(unsize_thin_ptr(bcx, src, src_f.ty, dst_f.ty)); + result = Some(unsize_thin_ptr(bx, src, src_f.ty, dst_f.ty)); } let (lldata, llextra) = result.unwrap(); // HACK(eddyb) have to bitcast pointers until LLVM removes pointee types. - (bcx.bitcast(lldata, dst_layout.scalar_pair_element_llvm_type(bcx.ccx, 0)), - bcx.bitcast(llextra, dst_layout.scalar_pair_element_llvm_type(bcx.ccx, 1))) + (bx.bitcast(lldata, dst_layout.scalar_pair_element_llvm_type(bx.cx, 0)), + bx.bitcast(llextra, dst_layout.scalar_pair_element_llvm_type(bx.cx, 1))) } _ => bug!("unsize_thin_ptr: called on bad types"), } @@ -273,27 +272,27 @@ pub fn unsize_thin_ptr<'a, 'tcx>( /// Coerce `src`, which is a reference to a value of type `src_ty`, /// to a value of type `dst_ty` and store the result in `dst` -pub fn coerce_unsized_into<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, +pub fn coerce_unsized_into<'a, 'tcx>(bx: &Builder<'a, 'tcx>, src: PlaceRef<'tcx>, dst: PlaceRef<'tcx>) { let src_ty = src.layout.ty; let dst_ty = dst.layout.ty; let coerce_ptr = || { - let (base, info) = match src.load(bcx).val { + let (base, info) = match src.load(bx).val { OperandValue::Pair(base, info) => { // fat-ptr to fat-ptr unsize preserves the vtable // i.e. &'a fmt::Debug+Send => &'a fmt::Debug // So we need to pointercast the base to ensure // the types match up. - let thin_ptr = dst.layout.field(bcx.ccx, abi::FAT_PTR_ADDR); - (bcx.pointercast(base, thin_ptr.llvm_type(bcx.ccx)), info) + let thin_ptr = dst.layout.field(bx.cx, abi::FAT_PTR_ADDR); + (bx.pointercast(base, thin_ptr.llvm_type(bx.cx)), info) } OperandValue::Immediate(base) => { - unsize_thin_ptr(bcx, base, src_ty, dst_ty) + unsize_thin_ptr(bx, base, src_ty, dst_ty) } OperandValue::Ref(..) => bug!() }; - OperandValue::Pair(base, info).store(bcx, dst); + OperandValue::Pair(base, info).store(bx, dst); }; match (&src_ty.sty, &dst_ty.sty) { (&ty::TyRef(..), &ty::TyRef(..)) | @@ -309,18 +308,18 @@ pub fn coerce_unsized_into<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, assert_eq!(def_a, def_b); for i in 0..def_a.variants[0].fields.len() { - let src_f = src.project_field(bcx, i); - let dst_f = dst.project_field(bcx, i); + let src_f = src.project_field(bx, i); + let dst_f = dst.project_field(bx, i); if dst_f.layout.is_zst() { continue; } if src_f.layout.ty == dst_f.layout.ty { - memcpy_ty(bcx, dst_f.llval, src_f.llval, src_f.layout, + memcpy_ty(bx, dst_f.llval, src_f.llval, src_f.layout, src_f.align.min(dst_f.align)); } else { - coerce_unsized_into(bcx, src_f, dst_f); + coerce_unsized_into(bx, src_f, dst_f); } } } @@ -388,47 +387,47 @@ pub fn wants_msvc_seh(sess: &Session) -> bool { sess.target.target.options.is_like_msvc } -pub fn call_assume<'a, 'tcx>(b: &Builder<'a, 'tcx>, val: ValueRef) { - let assume_intrinsic = b.ccx.get_intrinsic("llvm.assume"); - b.call(assume_intrinsic, &[val], None); +pub fn call_assume<'a, 'tcx>(bx: &Builder<'a, 'tcx>, val: ValueRef) { + let assume_intrinsic = bx.cx.get_intrinsic("llvm.assume"); + bx.call(assume_intrinsic, &[val], None); } -pub fn from_immediate(bcx: &Builder, val: ValueRef) -> ValueRef { - if val_ty(val) == Type::i1(bcx.ccx) { - bcx.zext(val, Type::i8(bcx.ccx)) +pub fn from_immediate(bx: &Builder, val: ValueRef) -> ValueRef { + if val_ty(val) == Type::i1(bx.cx) { + bx.zext(val, Type::i8(bx.cx)) } else { val } } -pub fn to_immediate(bcx: &Builder, val: ValueRef, layout: layout::TyLayout) -> ValueRef { +pub fn to_immediate(bx: &Builder, val: ValueRef, layout: layout::TyLayout) -> ValueRef { if let layout::Abi::Scalar(ref scalar) = layout.abi { if scalar.is_bool() { - return bcx.trunc(val, Type::i1(bcx.ccx)); + return bx.trunc(val, Type::i1(bx.cx)); } } val } -pub fn call_memcpy(b: &Builder, +pub fn call_memcpy(bx: &Builder, dst: ValueRef, src: ValueRef, n_bytes: ValueRef, align: Align) { - let ccx = b.ccx; - let ptr_width = &ccx.sess().target.target.target_pointer_width; + let cx = bx.cx; + let ptr_width = &cx.sess().target.target.target_pointer_width; let key = format!("llvm.memcpy.p0i8.p0i8.i{}", ptr_width); - let memcpy = ccx.get_intrinsic(&key); - let src_ptr = b.pointercast(src, Type::i8p(ccx)); - let dst_ptr = b.pointercast(dst, Type::i8p(ccx)); - let size = b.intcast(n_bytes, ccx.isize_ty(), false); - let align = C_i32(ccx, align.abi() as i32); - let volatile = C_bool(ccx, false); - b.call(memcpy, &[dst_ptr, src_ptr, size, align, volatile], None); + let memcpy = cx.get_intrinsic(&key); + let src_ptr = bx.pointercast(src, Type::i8p(cx)); + let dst_ptr = bx.pointercast(dst, Type::i8p(cx)); + let size = bx.intcast(n_bytes, cx.isize_ty, false); + let align = C_i32(cx, align.abi() as i32); + let volatile = C_bool(cx, false); + bx.call(memcpy, &[dst_ptr, src_ptr, size, align, volatile], None); } pub fn memcpy_ty<'a, 'tcx>( - bcx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'tcx>, dst: ValueRef, src: ValueRef, layout: TyLayout<'tcx>, @@ -439,28 +438,28 @@ pub fn memcpy_ty<'a, 'tcx>( return; } - call_memcpy(bcx, dst, src, C_usize(bcx.ccx, size), align); + call_memcpy(bx, dst, src, C_usize(bx.cx, size), align); } -pub fn call_memset<'a, 'tcx>(b: &Builder<'a, 'tcx>, +pub fn call_memset<'a, 'tcx>(bx: &Builder<'a, 'tcx>, ptr: ValueRef, fill_byte: ValueRef, size: ValueRef, align: ValueRef, volatile: bool) -> ValueRef { - let ptr_width = &b.ccx.sess().target.target.target_pointer_width; + let ptr_width = &bx.cx.sess().target.target.target_pointer_width; let intrinsic_key = format!("llvm.memset.p0i8.i{}", ptr_width); - let llintrinsicfn = b.ccx.get_intrinsic(&intrinsic_key); - let volatile = C_bool(b.ccx, volatile); - b.call(llintrinsicfn, &[ptr, fill_byte, size, align, volatile], None) + let llintrinsicfn = bx.cx.get_intrinsic(&intrinsic_key); + let volatile = C_bool(bx.cx, volatile); + bx.call(llintrinsicfn, &[ptr, fill_byte, size, align, volatile], None) } -pub fn trans_instance<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, instance: Instance<'tcx>) { - let _s = if ccx.sess().trans_stats() { +pub fn trans_instance<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, instance: Instance<'tcx>) { + let _s = if cx.sess().trans_stats() { let mut instance_name = String::new(); - DefPathBasedNames::new(ccx.tcx(), true, true) + DefPathBasedNames::new(cx.tcx, true, true) .push_def_path(instance.def_id(), &mut instance_name); - Some(StatRecorder::new(ccx, instance_name)) + Some(StatRecorder::new(cx, instance_name)) } else { None }; @@ -470,16 +469,16 @@ pub fn trans_instance<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, instance: Instance // release builds. info!("trans_instance({})", instance); - let fn_ty = instance.ty(ccx.tcx()); - let sig = common::ty_fn_sig(ccx, fn_ty); - let sig = ccx.tcx().erase_late_bound_regions_and_normalize(&sig); + let fn_ty = instance.ty(cx.tcx); + let sig = common::ty_fn_sig(cx, fn_ty); + let sig = cx.tcx.erase_late_bound_regions_and_normalize(&sig); - let lldecl = match ccx.instances().borrow().get(&instance) { + let lldecl = match cx.instances.borrow().get(&instance) { Some(&val) => val, None => bug!("Instance `{:?}` not already declared", instance) }; - ccx.stats().borrow_mut().n_closures += 1; + cx.stats.borrow_mut().n_closures += 1; // The `uwtable` attribute according to LLVM is: // @@ -497,21 +496,21 @@ pub fn trans_instance<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, instance: Instance // // You can also find more info on why Windows is whitelisted here in: // https://bugzilla.mozilla.org/show_bug.cgi?id=1302078 - if !ccx.sess().no_landing_pads() || - ccx.sess().target.target.options.is_like_windows { + if !cx.sess().no_landing_pads() || + cx.sess().target.target.options.is_like_windows { attributes::emit_uwtable(lldecl, true); } - let mir = ccx.tcx().instance_mir(instance.def); - mir::trans_mir(ccx, lldecl, &mir, instance, sig); + let mir = cx.tcx.instance_mir(instance.def); + mir::trans_mir(cx, lldecl, &mir, instance, sig); } -pub fn set_link_section(ccx: &CrateContext, +pub fn set_link_section(cx: &CodegenCx, llval: ValueRef, attrs: &[ast::Attribute]) { if let Some(sect) = attr::first_attr_value_str_by_name(attrs, "link_section") { if contains_null(§.as_str()) { - ccx.sess().fatal(&format!("Illegal null byte in link_section value: `{}`", §)); + cx.sess().fatal(&format!("Illegal null byte in link_section value: `{}`", §)); } unsafe { let buf = CString::new(sect.as_str().as_bytes()).unwrap(); @@ -522,39 +521,39 @@ pub fn set_link_section(ccx: &CrateContext, /// Create the `main` function which will initialize the rust runtime and call /// users main function. -fn maybe_create_entry_wrapper(ccx: &CrateContext) { - let (main_def_id, span) = match *ccx.sess().entry_fn.borrow() { +fn maybe_create_entry_wrapper(cx: &CodegenCx) { + let (main_def_id, span) = match *cx.sess().entry_fn.borrow() { Some((id, span)) => { - (ccx.tcx().hir.local_def_id(id), span) + (cx.tcx.hir.local_def_id(id), span) } None => return, }; - let instance = Instance::mono(ccx.tcx(), main_def_id); + let instance = Instance::mono(cx.tcx, main_def_id); - if !ccx.codegen_unit().contains_item(&MonoItem::Fn(instance)) { + if !cx.codegen_unit.contains_item(&MonoItem::Fn(instance)) { // We want to create the wrapper in the same codegen unit as Rust's main // function. return; } - let main_llfn = callee::get_fn(ccx, instance); + let main_llfn = callee::get_fn(cx, instance); - let et = ccx.sess().entry_type.get().unwrap(); + let et = cx.sess().entry_type.get().unwrap(); match et { - config::EntryMain => create_entry_fn(ccx, span, main_llfn, main_def_id, true), - config::EntryStart => create_entry_fn(ccx, span, main_llfn, main_def_id, false), + config::EntryMain => create_entry_fn(cx, span, main_llfn, main_def_id, true), + config::EntryStart => create_entry_fn(cx, span, main_llfn, main_def_id, false), config::EntryNone => {} // Do nothing. } - fn create_entry_fn<'ccx>(ccx: &'ccx CrateContext, + fn create_entry_fn<'cx>(cx: &'cx CodegenCx, sp: Span, rust_main: ValueRef, rust_main_def_id: DefId, use_start_lang_item: bool) { - let llfty = Type::func(&[Type::c_int(ccx), Type::i8p(ccx).ptr_to()], &Type::c_int(ccx)); + let llfty = Type::func(&[Type::c_int(cx), Type::i8p(cx).ptr_to()], &Type::c_int(cx)); - let main_ret_ty = ccx.tcx().fn_sig(rust_main_def_id).output(); + let main_ret_ty = cx.tcx.fn_sig(rust_main_def_id).output(); // Given that `main()` has no arguments, // then its return type cannot have // late-bound regions, since late-bound @@ -562,42 +561,42 @@ fn maybe_create_entry_wrapper(ccx: &CrateContext) { // listing. let main_ret_ty = main_ret_ty.no_late_bound_regions().unwrap(); - if declare::get_defined_value(ccx, "main").is_some() { + if declare::get_defined_value(cx, "main").is_some() { // FIXME: We should be smart and show a better diagnostic here. - ccx.sess().struct_span_err(sp, "entry symbol `main` defined multiple times") + cx.sess().struct_span_err(sp, "entry symbol `main` defined multiple times") .help("did you use #[no_mangle] on `fn main`? Use #[start] instead") .emit(); - ccx.sess().abort_if_errors(); + cx.sess().abort_if_errors(); bug!(); } - let llfn = declare::declare_cfn(ccx, "main", llfty); + let llfn = declare::declare_cfn(cx, "main", llfty); // `main` should respect same config for frame pointer elimination as rest of code - attributes::set_frame_pointer_elimination(ccx, llfn); + attributes::set_frame_pointer_elimination(cx, llfn); - let bld = Builder::new_block(ccx, llfn, "top"); + let bx = Builder::new_block(cx, llfn, "top"); - debuginfo::gdb::insert_reference_to_gdb_debug_scripts_section_global(ccx, &bld); + debuginfo::gdb::insert_reference_to_gdb_debug_scripts_section_global(&bx); // Params from native main() used as args for rust start function let param_argc = get_param(llfn, 0); let param_argv = get_param(llfn, 1); - let arg_argc = bld.intcast(param_argc, ccx.isize_ty(), true); + let arg_argc = bx.intcast(param_argc, cx.isize_ty, true); let arg_argv = param_argv; let (start_fn, args) = if use_start_lang_item { - let start_def_id = ccx.tcx().require_lang_item(StartFnLangItem); - let start_fn = callee::resolve_and_get_fn(ccx, start_def_id, ccx.tcx().mk_substs( + let start_def_id = cx.tcx.require_lang_item(StartFnLangItem); + let start_fn = callee::resolve_and_get_fn(cx, start_def_id, cx.tcx.mk_substs( iter::once(Kind::from(main_ret_ty)))); - (start_fn, vec![bld.pointercast(rust_main, Type::i8p(ccx).ptr_to()), + (start_fn, vec![bx.pointercast(rust_main, Type::i8p(cx).ptr_to()), arg_argc, arg_argv]) } else { debug!("using user-defined start fn"); (rust_main, vec![arg_argc, arg_argv]) }; - let result = bld.call(start_fn, &args, None); - bld.ret(bld.intcast(result, Type::c_int(ccx), true)); + let result = bx.call(start_fn, &args, None); + bx.ret(bx.intcast(result, Type::c_int(cx), true)); } } @@ -721,7 +720,6 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let link_meta = link::build_link_meta(crate_hash); let exported_symbol_node_ids = find_exported_symbols(tcx); - let shared_ccx = SharedCrateContext::new(tcx); // Translate the metadata. let llmod_id = "metadata"; let (metadata_llcx, metadata_llmod, metadata) = @@ -770,7 +768,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Run the translation item collector and partition the collected items into // codegen units. let codegen_units = - shared_ccx.tcx().collect_and_partition_translation_items(LOCAL_CRATE).1; + tcx.collect_and_partition_translation_items(LOCAL_CRATE).1; let codegen_units = (*codegen_units).clone(); // Force all codegen_unit queries so they are already either red or green @@ -905,12 +903,12 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, total_trans_time); if tcx.sess.opts.incremental.is_some() { - assert_module_sources::assert_module_sources(tcx); + ::rustc_incremental::assert_module_sources::assert_module_sources(tcx); } symbol_names_test::report_symbol_names(tcx); - if shared_ccx.sess().trans_stats() { + if tcx.sess.trans_stats() { println!("--- trans stats ---"); println!("n_glues_created: {}", all_stats.n_glues_created); println!("n_null_glues: {}", all_stats.n_null_glues); @@ -926,7 +924,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } } - if shared_ccx.sess().count_llvm_insns() { + if tcx.sess.count_llvm_insns() { for (k, v) in all_stats.llvm_insns.iter() { println!("{:7} {}", *v, *k); } @@ -948,54 +946,6 @@ fn assert_and_save_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { || rustc_incremental::save_dep_graph(tcx)); } -#[inline(never)] // give this a place in the profiler -fn assert_symbols_are_distinct<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trans_items: I) - where I: Iterator<Item=&'a MonoItem<'tcx>> -{ - let mut symbols: Vec<_> = trans_items.map(|trans_item| { - (trans_item, trans_item.symbol_name(tcx)) - }).collect(); - - (&mut symbols[..]).sort_by(|&(_, ref sym1), &(_, ref sym2)|{ - sym1.cmp(sym2) - }); - - for pair in (&symbols[..]).windows(2) { - let sym1 = &pair[0].1; - let sym2 = &pair[1].1; - - if *sym1 == *sym2 { - let trans_item1 = pair[0].0; - let trans_item2 = pair[1].0; - - let span1 = trans_item1.local_span(tcx); - let span2 = trans_item2.local_span(tcx); - - // Deterministically select one of the spans for error reporting - let span = match (span1, span2) { - (Some(span1), Some(span2)) => { - Some(if span1.lo().0 > span2.lo().0 { - span1 - } else { - span2 - }) - } - (Some(span), None) | - (None, Some(span)) => Some(span), - _ => None - }; - - let error_message = format!("symbol `{}` is already defined", sym1); - - if let Some(span) = span { - tcx.sess.span_fatal(span, &error_message) - } else { - tcx.sess.fatal(&error_message) - } - } - } -} - fn collect_and_partition_translation_items<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, cnum: CrateNum, @@ -1035,7 +985,7 @@ fn collect_and_partition_translation_items<'a, 'tcx>( collector::collect_crate_mono_items(tcx, collection_mode) }); - assert_symbols_are_distinct(tcx, items.iter()); + ::rustc_mir::monomorphize::assert_symbols_are_distinct(tcx, items.iter()); let strategy = if tcx.sess.opts.incremental.is_some() { PartitioningStrategy::PerModule @@ -1204,27 +1154,25 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, .to_fingerprint().to_hex()); // Instantiate translation items without filling out definitions yet... - let scx = SharedCrateContext::new(tcx); - let lcx = LocalCrateContext::new(&scx, cgu, &llmod_id); + let cx = CodegenCx::new(tcx, cgu, &llmod_id); let module = { - let ccx = CrateContext::new(&scx, &lcx); - let trans_items = ccx.codegen_unit() - .items_in_deterministic_order(ccx.tcx()); + let trans_items = cx.codegen_unit + .items_in_deterministic_order(cx.tcx); for &(trans_item, (linkage, visibility)) in &trans_items { - trans_item.predefine(&ccx, linkage, visibility); + trans_item.predefine(&cx, linkage, visibility); } // ... and now that we have everything pre-defined, fill out those definitions. for &(trans_item, _) in &trans_items { - trans_item.define(&ccx); + trans_item.define(&cx); } // If this codegen unit contains the main function, also create the // wrapper here - maybe_create_entry_wrapper(&ccx); + maybe_create_entry_wrapper(&cx); // Run replace-all-uses-with for statics that need it - for &(old_g, new_g) in ccx.statics_to_rauw().borrow().iter() { + for &(old_g, new_g) in cx.statics_to_rauw.borrow().iter() { unsafe { let bitcast = llvm::LLVMConstPointerCast(new_g, llvm::LLVMTypeOf(old_g)); llvm::LLVMReplaceAllUsesWith(old_g, bitcast); @@ -1234,13 +1182,13 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Create the llvm.used variable // This variable has type [N x i8*] and is stored in the llvm.metadata section - if !ccx.used_statics().borrow().is_empty() { + if !cx.used_statics.borrow().is_empty() { let name = CString::new("llvm.used").unwrap(); let section = CString::new("llvm.metadata").unwrap(); - let array = C_array(Type::i8(&ccx).ptr_to(), &*ccx.used_statics().borrow()); + let array = C_array(Type::i8(&cx).ptr_to(), &*cx.used_statics.borrow()); unsafe { - let g = llvm::LLVMAddGlobal(ccx.llmod(), + let g = llvm::LLVMAddGlobal(cx.llmod, val_ty(array).to_ref(), name.as_ptr()); llvm::LLVMSetInitializer(g, array); @@ -1250,14 +1198,14 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } // Finalize debuginfo - if ccx.sess().opts.debuginfo != NoDebugInfo { - debuginfo::finalize(&ccx); + if cx.sess().opts.debuginfo != NoDebugInfo { + debuginfo::finalize(&cx); } let llvm_module = ModuleLlvm { - llcx: ccx.llcx(), - llmod: ccx.llmod(), - tm: create_target_machine(ccx.sess()), + llcx: cx.llcx, + llmod: cx.llmod, + tm: create_target_machine(cx.sess()), }; ModuleTranslation { @@ -1268,7 +1216,7 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } }; - (lcx.into_stats(), module) + (cx.into_stats(), module) } } diff --git a/src/librustc_trans/builder.rs b/src/librustc_trans/builder.rs index 4a0b1381a40..5ab8d03b8c7 100644 --- a/src/librustc_trans/builder.rs +++ b/src/librustc_trans/builder.rs @@ -32,7 +32,7 @@ use syntax_pos::Span; #[must_use] pub struct Builder<'a, 'tcx: 'a> { pub llbuilder: BuilderRef, - pub ccx: &'a CrateContext<'a, 'tcx>, + pub cx: &'a CodegenCx<'a, 'tcx>, } impl<'a, 'tcx> Drop for Builder<'a, 'tcx> { @@ -51,41 +51,41 @@ fn noname() -> *const c_char { } impl<'a, 'tcx> Builder<'a, 'tcx> { - pub fn new_block<'b>(ccx: &'a CrateContext<'a, 'tcx>, llfn: ValueRef, name: &'b str) -> Self { - let builder = Builder::with_ccx(ccx); + pub fn new_block<'b>(cx: &'a CodegenCx<'a, 'tcx>, llfn: ValueRef, name: &'b str) -> Self { + let bx = Builder::with_cx(cx); let llbb = unsafe { let name = CString::new(name).unwrap(); llvm::LLVMAppendBasicBlockInContext( - ccx.llcx(), + cx.llcx, llfn, name.as_ptr() ) }; - builder.position_at_end(llbb); - builder + bx.position_at_end(llbb); + bx } - pub fn with_ccx(ccx: &'a CrateContext<'a, 'tcx>) -> Self { + pub fn with_cx(cx: &'a CodegenCx<'a, 'tcx>) -> Self { // Create a fresh builder from the crate context. let llbuilder = unsafe { - llvm::LLVMCreateBuilderInContext(ccx.llcx()) + llvm::LLVMCreateBuilderInContext(cx.llcx) }; Builder { llbuilder, - ccx, + cx, } } pub fn build_sibling_block<'b>(&self, name: &'b str) -> Builder<'a, 'tcx> { - Builder::new_block(self.ccx, self.llfn(), name) + Builder::new_block(self.cx, self.llfn(), name) } pub fn sess(&self) -> &Session { - self.ccx.sess() + self.cx.sess() } pub fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx> { - self.ccx.tcx() + self.cx.tcx } pub fn llfn(&self) -> ValueRef { @@ -101,11 +101,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } fn count_insn(&self, category: &str) { - if self.ccx.sess().trans_stats() { - self.ccx.stats().borrow_mut().n_llvm_insns += 1; + if self.cx.sess().trans_stats() { + self.cx.stats.borrow_mut().n_llvm_insns += 1; } - if self.ccx.sess().count_llvm_insns() { - *self.ccx.stats() + if self.cx.sess().count_llvm_insns() { + *self.cx.stats .borrow_mut() .llvm_insns .entry(category.to_string()) @@ -489,11 +489,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } pub fn alloca(&self, ty: Type, name: &str, align: Align) -> ValueRef { - let builder = Builder::with_ccx(self.ccx); - builder.position_at_start(unsafe { + let bx = Builder::with_cx(self.cx); + bx.position_at_start(unsafe { llvm::LLVMGetFirstBasicBlock(self.llfn()) }); - builder.dynamic_alloca(ty, name, align) + bx.dynamic_alloca(ty, name, align) } pub fn dynamic_alloca(&self, ty: Type, name: &str, align: Align) -> ValueRef { @@ -558,7 +558,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ]; llvm::LLVMSetMetadata(load, llvm::MD_range as c_uint, - llvm::LLVMMDNodeInContext(self.ccx.llcx(), + llvm::LLVMMDNodeInContext(self.cx.llcx, v.as_ptr(), v.len() as c_uint)); } @@ -567,7 +567,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pub fn nonnull_metadata(&self, load: ValueRef) { unsafe { llvm::LLVMSetMetadata(load, llvm::MD_nonnull as c_uint, - llvm::LLVMMDNodeInContext(self.ccx.llcx(), ptr::null(), 0)); + llvm::LLVMMDNodeInContext(self.cx.llcx, ptr::null(), 0)); } } @@ -620,8 +620,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // point to a metadata value of the integer 1. Who knew? // // [1]: http://llvm.org/docs/LangRef.html#store-instruction - let one = C_i32(self.ccx, 1); - let node = llvm::LLVMMDNodeInContext(self.ccx.llcx(), + let one = C_i32(self.cx, 1); + let node = llvm::LLVMMDNodeInContext(self.cx.llcx, &one, 1); llvm::LLVMSetMetadata(insn, @@ -840,24 +840,24 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } pub fn add_span_comment(&self, sp: Span, text: &str) { - if self.ccx.sess().asm_comments() { + if self.cx.sess().asm_comments() { let s = format!("{} ({})", text, - self.ccx.sess().codemap().span_to_string(sp)); + self.cx.sess().codemap().span_to_string(sp)); debug!("{}", s); self.add_comment(&s); } } pub fn add_comment(&self, text: &str) { - if self.ccx.sess().asm_comments() { + if self.cx.sess().asm_comments() { let sanitized = text.replace("$", ""); let comment_text = format!("{} {}", "#", sanitized.replace("\n", "\n\t# ")); self.count_insn("inlineasm"); let comment_text = CString::new(comment_text).unwrap(); let asm = unsafe { - llvm::LLVMConstInlineAsm(Type::func(&[], &Type::void(self.ccx)).to_ref(), + llvm::LLVMConstInlineAsm(Type::func(&[], &Type::void(self.cx)).to_ref(), comment_text.as_ptr(), noname(), False, False) }; @@ -949,8 +949,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { unsafe { let elt_ty = val_ty(elt); let undef = llvm::LLVMGetUndef(Type::vector(&elt_ty, num_elts as u64).to_ref()); - let vec = self.insert_element(undef, elt, C_i32(self.ccx, 0)); - let vec_i32_ty = Type::vector(&Type::i32(self.ccx), num_elts as u64); + let vec = self.insert_element(undef, elt, C_i32(self.cx, 0)); + let vec_i32_ty = Type::vector(&Type::i32(self.cx), num_elts as u64); self.shuffle_vector(vec, undef, C_null(vec_i32_ty)) } } @@ -1160,7 +1160,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pub fn set_invariant_load(&self, load: ValueRef) { unsafe { llvm::LLVMSetMetadata(load, llvm::MD_invariant_load as c_uint, - llvm::LLVMMDNodeInContext(self.ccx.llcx(), ptr::null(), 0)); + llvm::LLVMMDNodeInContext(self.cx.llcx, ptr::null(), 0)); } } @@ -1245,7 +1245,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// If LLVM lifetime intrinsic support is disabled (i.e. optimizations /// off) or `ptr` is zero-sized, then no-op (does not call `emit`). fn call_lifetime_intrinsic(&self, intrinsic: &str, ptr: ValueRef, size: Size) { - if self.ccx.sess().opts.optimize == config::OptLevel::No { + if self.cx.sess().opts.optimize == config::OptLevel::No { return; } @@ -1254,9 +1254,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { return; } - let lifetime_intrinsic = self.ccx.get_intrinsic(intrinsic); + let lifetime_intrinsic = self.cx.get_intrinsic(intrinsic); - let ptr = self.pointercast(ptr, Type::i8p(self.ccx)); - self.call(lifetime_intrinsic, &[C_u64(self.ccx, size), ptr], None); + let ptr = self.pointercast(ptr, Type::i8p(self.cx)); + self.call(lifetime_intrinsic, &[C_u64(self.cx, size), ptr], None); } } diff --git a/src/librustc_trans/cabi_aarch64.rs b/src/librustc_trans/cabi_aarch64.rs index d5f341f9685..72ae1449de0 100644 --- a/src/librustc_trans/cabi_aarch64.rs +++ b/src/librustc_trans/cabi_aarch64.rs @@ -9,15 +9,15 @@ // except according to those terms. use abi::{FnType, ArgType, LayoutExt, Reg, RegKind, Uniform}; -use context::CrateContext; +use context::CodegenCx; -fn is_homogeneous_aggregate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg: &mut ArgType<'tcx>) +fn is_homogeneous_aggregate<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>) -> Option<Uniform> { - arg.layout.homogeneous_aggregate(ccx).and_then(|unit| { + arg.layout.homogeneous_aggregate(cx).and_then(|unit| { let size = arg.layout.size; // Ensure we have at most four uniquely addressable members. - if size > unit.size.checked_mul(4, ccx).unwrap() { + if size > unit.size.checked_mul(4, cx).unwrap() { return None; } @@ -38,12 +38,12 @@ fn is_homogeneous_aggregate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg: &mut Ar }) } -fn classify_ret_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ret: &mut ArgType<'tcx>) { +fn classify_ret_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>) { if !ret.layout.is_aggregate() { ret.extend_integer_width_to(32); return; } - if let Some(uniform) = is_homogeneous_aggregate(ccx, ret) { + if let Some(uniform) = is_homogeneous_aggregate(cx, ret) { ret.cast_to(uniform); return; } @@ -69,12 +69,12 @@ fn classify_ret_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ret: &mut ArgType<'tc ret.make_indirect(); } -fn classify_arg_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg: &mut ArgType<'tcx>) { +fn classify_arg_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>) { if !arg.layout.is_aggregate() { arg.extend_integer_width_to(32); return; } - if let Some(uniform) = is_homogeneous_aggregate(ccx, arg) { + if let Some(uniform) = is_homogeneous_aggregate(cx, arg) { arg.cast_to(uniform); return; } @@ -100,13 +100,13 @@ fn classify_arg_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg: &mut ArgType<'tc arg.make_indirect(); } -pub fn compute_abi_info<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fty: &mut FnType<'tcx>) { +pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fty: &mut FnType<'tcx>) { if !fty.ret.is_ignore() { - classify_ret_ty(ccx, &mut fty.ret); + classify_ret_ty(cx, &mut fty.ret); } for arg in &mut fty.args { if arg.is_ignore() { continue; } - classify_arg_ty(ccx, arg); + classify_arg_ty(cx, arg); } } diff --git a/src/librustc_trans/cabi_arm.rs b/src/librustc_trans/cabi_arm.rs index 438053d63b5..b6cf16cb8d5 100644 --- a/src/librustc_trans/cabi_arm.rs +++ b/src/librustc_trans/cabi_arm.rs @@ -9,16 +9,16 @@ // except according to those terms. use abi::{FnType, ArgType, LayoutExt, Reg, RegKind, Uniform}; -use context::CrateContext; +use context::CodegenCx; use llvm::CallConv; -fn is_homogeneous_aggregate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg: &mut ArgType<'tcx>) +fn is_homogeneous_aggregate<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>) -> Option<Uniform> { - arg.layout.homogeneous_aggregate(ccx).and_then(|unit| { + arg.layout.homogeneous_aggregate(cx).and_then(|unit| { let size = arg.layout.size; // Ensure we have at most four uniquely addressable members. - if size > unit.size.checked_mul(4, ccx).unwrap() { + if size > unit.size.checked_mul(4, cx).unwrap() { return None; } @@ -39,14 +39,14 @@ fn is_homogeneous_aggregate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg: &mut Ar }) } -fn classify_ret_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ret: &mut ArgType<'tcx>, vfp: bool) { +fn classify_ret_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>, vfp: bool) { if !ret.layout.is_aggregate() { ret.extend_integer_width_to(32); return; } if vfp { - if let Some(uniform) = is_homogeneous_aggregate(ccx, ret) { + if let Some(uniform) = is_homogeneous_aggregate(cx, ret) { ret.cast_to(uniform); return; } @@ -71,14 +71,14 @@ fn classify_ret_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ret: &mut ArgType<'tc ret.make_indirect(); } -fn classify_arg_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg: &mut ArgType<'tcx>, vfp: bool) { +fn classify_arg_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>, vfp: bool) { if !arg.layout.is_aggregate() { arg.extend_integer_width_to(32); return; } if vfp { - if let Some(uniform) = is_homogeneous_aggregate(ccx, arg) { + if let Some(uniform) = is_homogeneous_aggregate(cx, arg) { arg.cast_to(uniform); return; } @@ -92,19 +92,19 @@ fn classify_arg_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg: &mut ArgType<'tc }); } -pub fn compute_abi_info<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fty: &mut FnType<'tcx>) { +pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fty: &mut FnType<'tcx>) { // If this is a target with a hard-float ABI, and the function is not explicitly // `extern "aapcs"`, then we must use the VFP registers for homogeneous aggregates. - let vfp = ccx.sess().target.target.llvm_target.ends_with("hf") + let vfp = cx.sess().target.target.llvm_target.ends_with("hf") && fty.cconv != CallConv::ArmAapcsCallConv && !fty.variadic; if !fty.ret.is_ignore() { - classify_ret_ty(ccx, &mut fty.ret, vfp); + classify_ret_ty(cx, &mut fty.ret, vfp); } for arg in &mut fty.args { if arg.is_ignore() { continue; } - classify_arg_ty(ccx, arg, vfp); + classify_arg_ty(cx, arg, vfp); } } diff --git a/src/librustc_trans/cabi_asmjs.rs b/src/librustc_trans/cabi_asmjs.rs index 1664251cf89..b182f833dd6 100644 --- a/src/librustc_trans/cabi_asmjs.rs +++ b/src/librustc_trans/cabi_asmjs.rs @@ -9,16 +9,16 @@ // except according to those terms. use abi::{FnType, ArgType, LayoutExt, Uniform}; -use context::CrateContext; +use context::CodegenCx; // Data layout: e-p:32:32-i64:64-v128:32:128-n32-S128 // See the https://github.com/kripken/emscripten-fastcomp-clang repository. // The class `EmscriptenABIInfo` in `/lib/CodeGen/TargetInfo.cpp` contains the ABI definitions. -fn classify_ret_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ret: &mut ArgType<'tcx>) { +fn classify_ret_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>) { if ret.layout.is_aggregate() { - if let Some(unit) = ret.layout.homogeneous_aggregate(ccx) { + if let Some(unit) = ret.layout.homogeneous_aggregate(cx) { let size = ret.layout.size; if unit.size == size { ret.cast_to(Uniform { @@ -39,9 +39,9 @@ fn classify_arg_ty(arg: &mut ArgType) { } } -pub fn compute_abi_info<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fty: &mut FnType<'tcx>) { +pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fty: &mut FnType<'tcx>) { if !fty.ret.is_ignore() { - classify_ret_ty(ccx, &mut fty.ret); + classify_ret_ty(cx, &mut fty.ret); } for arg in &mut fty.args { diff --git a/src/librustc_trans/cabi_mips.rs b/src/librustc_trans/cabi_mips.rs index fe61670a108..cd567f517fe 100644 --- a/src/librustc_trans/cabi_mips.rs +++ b/src/librustc_trans/cabi_mips.rs @@ -9,23 +9,23 @@ // except according to those terms. use abi::{ArgType, FnType, LayoutExt, Reg, Uniform}; -use context::CrateContext; +use context::CodegenCx; use rustc::ty::layout::Size; -fn classify_ret_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, +fn classify_ret_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>, offset: &mut Size) { if !ret.layout.is_aggregate() { ret.extend_integer_width_to(32); } else { ret.make_indirect(); - *offset += ccx.tcx().data_layout.pointer_size; + *offset += cx.tcx.data_layout.pointer_size; } } -fn classify_arg_ty(ccx: &CrateContext, arg: &mut ArgType, offset: &mut Size) { - let dl = &ccx.tcx().data_layout; +fn classify_arg_ty(cx: &CodegenCx, arg: &mut ArgType, offset: &mut Size) { + let dl = &cx.tcx.data_layout; let size = arg.layout.size; let align = arg.layout.align.max(dl.i32_align).min(dl.i64_align); @@ -44,14 +44,14 @@ fn classify_arg_ty(ccx: &CrateContext, arg: &mut ArgType, offset: &mut Size) { *offset = offset.abi_align(align) + size.abi_align(align); } -pub fn compute_abi_info<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fty: &mut FnType<'tcx>) { +pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fty: &mut FnType<'tcx>) { let mut offset = Size::from_bytes(0); if !fty.ret.is_ignore() { - classify_ret_ty(ccx, &mut fty.ret, &mut offset); + classify_ret_ty(cx, &mut fty.ret, &mut offset); } for arg in &mut fty.args { if arg.is_ignore() { continue; } - classify_arg_ty(ccx, arg, &mut offset); + classify_arg_ty(cx, arg, &mut offset); } } diff --git a/src/librustc_trans/cabi_mips64.rs b/src/librustc_trans/cabi_mips64.rs index 16d0cfe072d..e44063faab8 100644 --- a/src/librustc_trans/cabi_mips64.rs +++ b/src/librustc_trans/cabi_mips64.rs @@ -9,23 +9,23 @@ // except according to those terms. use abi::{ArgType, FnType, LayoutExt, Reg, Uniform}; -use context::CrateContext; +use context::CodegenCx; use rustc::ty::layout::Size; -fn classify_ret_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, +fn classify_ret_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>, offset: &mut Size) { if !ret.layout.is_aggregate() { ret.extend_integer_width_to(64); } else { ret.make_indirect(); - *offset += ccx.tcx().data_layout.pointer_size; + *offset += cx.tcx.data_layout.pointer_size; } } -fn classify_arg_ty(ccx: &CrateContext, arg: &mut ArgType, offset: &mut Size) { - let dl = &ccx.tcx().data_layout; +fn classify_arg_ty(cx: &CodegenCx, arg: &mut ArgType, offset: &mut Size) { + let dl = &cx.tcx.data_layout; let size = arg.layout.size; let align = arg.layout.align.max(dl.i32_align).min(dl.i64_align); @@ -44,14 +44,14 @@ fn classify_arg_ty(ccx: &CrateContext, arg: &mut ArgType, offset: &mut Size) { *offset = offset.abi_align(align) + size.abi_align(align); } -pub fn compute_abi_info<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fty: &mut FnType<'tcx>) { +pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fty: &mut FnType<'tcx>) { let mut offset = Size::from_bytes(0); if !fty.ret.is_ignore() { - classify_ret_ty(ccx, &mut fty.ret, &mut offset); + classify_ret_ty(cx, &mut fty.ret, &mut offset); } for arg in &mut fty.args { if arg.is_ignore() { continue; } - classify_arg_ty(ccx, arg, &mut offset); + classify_arg_ty(cx, arg, &mut offset); } } diff --git a/src/librustc_trans/cabi_powerpc.rs b/src/librustc_trans/cabi_powerpc.rs index c3c8c745e3a..1ea6e9b2695 100644 --- a/src/librustc_trans/cabi_powerpc.rs +++ b/src/librustc_trans/cabi_powerpc.rs @@ -9,23 +9,23 @@ // except according to those terms. use abi::{ArgType, FnType, LayoutExt, Reg, Uniform}; -use context::CrateContext; +use context::CodegenCx; use rustc::ty::layout::Size; -fn classify_ret_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, +fn classify_ret_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>, offset: &mut Size) { if !ret.layout.is_aggregate() { ret.extend_integer_width_to(32); } else { ret.make_indirect(); - *offset += ccx.tcx().data_layout.pointer_size; + *offset += cx.tcx.data_layout.pointer_size; } } -fn classify_arg_ty(ccx: &CrateContext, arg: &mut ArgType, offset: &mut Size) { - let dl = &ccx.tcx().data_layout; +fn classify_arg_ty(cx: &CodegenCx, arg: &mut ArgType, offset: &mut Size) { + let dl = &cx.tcx.data_layout; let size = arg.layout.size; let align = arg.layout.align.max(dl.i32_align).min(dl.i64_align); @@ -44,14 +44,14 @@ fn classify_arg_ty(ccx: &CrateContext, arg: &mut ArgType, offset: &mut Size) { *offset = offset.abi_align(align) + size.abi_align(align); } -pub fn compute_abi_info<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fty: &mut FnType<'tcx>) { +pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fty: &mut FnType<'tcx>) { let mut offset = Size::from_bytes(0); if !fty.ret.is_ignore() { - classify_ret_ty(ccx, &mut fty.ret, &mut offset); + classify_ret_ty(cx, &mut fty.ret, &mut offset); } for arg in &mut fty.args { if arg.is_ignore() { continue; } - classify_arg_ty(ccx, arg, &mut offset); + classify_arg_ty(cx, arg, &mut offset); } } diff --git a/src/librustc_trans/cabi_powerpc64.rs b/src/librustc_trans/cabi_powerpc64.rs index 2206a4fa00c..c614cf3a5a9 100644 --- a/src/librustc_trans/cabi_powerpc64.rs +++ b/src/librustc_trans/cabi_powerpc64.rs @@ -13,7 +13,7 @@ // need to be fixed when PowerPC vector support is added. use abi::{FnType, ArgType, LayoutExt, Reg, RegKind, Uniform}; -use context::CrateContext; +use context::CodegenCx; use rustc::ty::layout; #[derive(Debug, Clone, Copy, PartialEq)] @@ -23,15 +23,15 @@ enum ABI { } use self::ABI::*; -fn is_homogeneous_aggregate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, +fn is_homogeneous_aggregate<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>, abi: ABI) -> Option<Uniform> { - arg.layout.homogeneous_aggregate(ccx).and_then(|unit| { + arg.layout.homogeneous_aggregate(cx).and_then(|unit| { // ELFv1 only passes one-member aggregates transparently. // ELFv2 passes up to eight uniquely addressable members. if (abi == ELFv1 && arg.layout.size > unit.size) - || arg.layout.size > unit.size.checked_mul(8, ccx).unwrap() { + || arg.layout.size > unit.size.checked_mul(8, cx).unwrap() { return None; } @@ -52,7 +52,7 @@ fn is_homogeneous_aggregate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, }) } -fn classify_ret_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ret: &mut ArgType<'tcx>, abi: ABI) { +fn classify_ret_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>, abi: ABI) { if !ret.layout.is_aggregate() { ret.extend_integer_width_to(64); return; @@ -64,7 +64,7 @@ fn classify_ret_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ret: &mut ArgType<'tc return; } - if let Some(uniform) = is_homogeneous_aggregate(ccx, ret, abi) { + if let Some(uniform) = is_homogeneous_aggregate(cx, ret, abi) { ret.cast_to(uniform); return; } @@ -92,13 +92,13 @@ fn classify_ret_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ret: &mut ArgType<'tc ret.make_indirect(); } -fn classify_arg_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg: &mut ArgType<'tcx>, abi: ABI) { +fn classify_arg_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>, abi: ABI) { if !arg.layout.is_aggregate() { arg.extend_integer_width_to(64); return; } - if let Some(uniform) = is_homogeneous_aggregate(ccx, arg, abi) { + if let Some(uniform) = is_homogeneous_aggregate(cx, arg, abi) { arg.cast_to(uniform); return; } @@ -128,19 +128,19 @@ fn classify_arg_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg: &mut ArgType<'tc }); } -pub fn compute_abi_info<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fty: &mut FnType<'tcx>) { - let abi = match ccx.sess().target.target.target_endian.as_str() { +pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fty: &mut FnType<'tcx>) { + let abi = match cx.sess().target.target.target_endian.as_str() { "big" => ELFv1, "little" => ELFv2, _ => unimplemented!(), }; if !fty.ret.is_ignore() { - classify_ret_ty(ccx, &mut fty.ret, abi); + classify_ret_ty(cx, &mut fty.ret, abi); } for arg in &mut fty.args { if arg.is_ignore() { continue; } - classify_arg_ty(ccx, arg, abi); + classify_arg_ty(cx, arg, abi); } } diff --git a/src/librustc_trans/cabi_s390x.rs b/src/librustc_trans/cabi_s390x.rs index 9fb460043ae..5e817686def 100644 --- a/src/librustc_trans/cabi_s390x.rs +++ b/src/librustc_trans/cabi_s390x.rs @@ -12,7 +12,7 @@ // for a pre-z13 machine or using -mno-vx. use abi::{FnType, ArgType, LayoutExt, Reg}; -use context::CrateContext; +use context::CodegenCx; use rustc::ty::layout::{self, TyLayout}; @@ -24,7 +24,7 @@ fn classify_ret_ty(ret: &mut ArgType) { } } -fn is_single_fp_element<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, +fn is_single_fp_element<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, layout: TyLayout<'tcx>) -> bool { match layout.abi { layout::Abi::Scalar(ref scalar) => { @@ -35,7 +35,7 @@ fn is_single_fp_element<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, } layout::Abi::Aggregate { .. } => { if layout.fields.count() == 1 && layout.fields.offset(0).bytes() == 0 { - is_single_fp_element(ccx, layout.field(ccx, 0)) + is_single_fp_element(cx, layout.field(cx, 0)) } else { false } @@ -44,13 +44,13 @@ fn is_single_fp_element<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, } } -fn classify_arg_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg: &mut ArgType<'tcx>) { +fn classify_arg_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>) { if !arg.layout.is_aggregate() && arg.layout.size.bits() <= 64 { arg.extend_integer_width_to(64); return; } - if is_single_fp_element(ccx, arg.layout) { + if is_single_fp_element(cx, arg.layout) { match arg.layout.size.bytes() { 4 => arg.cast_to(Reg::f32()), 8 => arg.cast_to(Reg::f64()), @@ -67,13 +67,13 @@ fn classify_arg_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg: &mut ArgType<'tc } } -pub fn compute_abi_info<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fty: &mut FnType<'tcx>) { +pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fty: &mut FnType<'tcx>) { if !fty.ret.is_ignore() { classify_ret_ty(&mut fty.ret); } for arg in &mut fty.args { if arg.is_ignore() { continue; } - classify_arg_ty(ccx, arg); + classify_arg_ty(cx, arg); } } diff --git a/src/librustc_trans/cabi_sparc.rs b/src/librustc_trans/cabi_sparc.rs index fe61670a108..cd567f517fe 100644 --- a/src/librustc_trans/cabi_sparc.rs +++ b/src/librustc_trans/cabi_sparc.rs @@ -9,23 +9,23 @@ // except according to those terms. use abi::{ArgType, FnType, LayoutExt, Reg, Uniform}; -use context::CrateContext; +use context::CodegenCx; use rustc::ty::layout::Size; -fn classify_ret_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, +fn classify_ret_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>, offset: &mut Size) { if !ret.layout.is_aggregate() { ret.extend_integer_width_to(32); } else { ret.make_indirect(); - *offset += ccx.tcx().data_layout.pointer_size; + *offset += cx.tcx.data_layout.pointer_size; } } -fn classify_arg_ty(ccx: &CrateContext, arg: &mut ArgType, offset: &mut Size) { - let dl = &ccx.tcx().data_layout; +fn classify_arg_ty(cx: &CodegenCx, arg: &mut ArgType, offset: &mut Size) { + let dl = &cx.tcx.data_layout; let size = arg.layout.size; let align = arg.layout.align.max(dl.i32_align).min(dl.i64_align); @@ -44,14 +44,14 @@ fn classify_arg_ty(ccx: &CrateContext, arg: &mut ArgType, offset: &mut Size) { *offset = offset.abi_align(align) + size.abi_align(align); } -pub fn compute_abi_info<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fty: &mut FnType<'tcx>) { +pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fty: &mut FnType<'tcx>) { let mut offset = Size::from_bytes(0); if !fty.ret.is_ignore() { - classify_ret_ty(ccx, &mut fty.ret, &mut offset); + classify_ret_ty(cx, &mut fty.ret, &mut offset); } for arg in &mut fty.args { if arg.is_ignore() { continue; } - classify_arg_ty(ccx, arg, &mut offset); + classify_arg_ty(cx, arg, &mut offset); } } diff --git a/src/librustc_trans/cabi_sparc64.rs b/src/librustc_trans/cabi_sparc64.rs index 7c52e27fa67..fb94b09d626 100644 --- a/src/librustc_trans/cabi_sparc64.rs +++ b/src/librustc_trans/cabi_sparc64.rs @@ -11,13 +11,13 @@ // FIXME: This needs an audit for correctness and completeness. use abi::{FnType, ArgType, LayoutExt, Reg, RegKind, Uniform}; -use context::CrateContext; +use context::CodegenCx; -fn is_homogeneous_aggregate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg: &mut ArgType<'tcx>) +fn is_homogeneous_aggregate<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>) -> Option<Uniform> { - arg.layout.homogeneous_aggregate(ccx).and_then(|unit| { + arg.layout.homogeneous_aggregate(cx).and_then(|unit| { // Ensure we have at most eight uniquely addressable members. - if arg.layout.size > unit.size.checked_mul(8, ccx).unwrap() { + if arg.layout.size > unit.size.checked_mul(8, cx).unwrap() { return None; } @@ -38,13 +38,13 @@ fn is_homogeneous_aggregate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg: &mut Ar }) } -fn classify_ret_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ret: &mut ArgType<'tcx>) { +fn classify_ret_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>) { if !ret.layout.is_aggregate() { ret.extend_integer_width_to(64); return; } - if let Some(uniform) = is_homogeneous_aggregate(ccx, ret) { + if let Some(uniform) = is_homogeneous_aggregate(cx, ret) { ret.cast_to(uniform); return; } @@ -72,13 +72,13 @@ fn classify_ret_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ret: &mut ArgType<'tc ret.make_indirect(); } -fn classify_arg_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg: &mut ArgType<'tcx>) { +fn classify_arg_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>) { if !arg.layout.is_aggregate() { arg.extend_integer_width_to(64); return; } - if let Some(uniform) = is_homogeneous_aggregate(ccx, arg) { + if let Some(uniform) = is_homogeneous_aggregate(cx, arg) { arg.cast_to(uniform); return; } @@ -90,13 +90,13 @@ fn classify_arg_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg: &mut ArgType<'tc }); } -pub fn compute_abi_info<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fty: &mut FnType<'tcx>) { +pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fty: &mut FnType<'tcx>) { if !fty.ret.is_ignore() { - classify_ret_ty(ccx, &mut fty.ret); + classify_ret_ty(cx, &mut fty.ret); } for arg in &mut fty.args { if arg.is_ignore() { continue; } - classify_arg_ty(ccx, arg); + classify_arg_ty(cx, arg); } } diff --git a/src/librustc_trans/cabi_x86.rs b/src/librustc_trans/cabi_x86.rs index 6fd0140c399..60347ba0945 100644 --- a/src/librustc_trans/cabi_x86.rs +++ b/src/librustc_trans/cabi_x86.rs @@ -9,7 +9,7 @@ // except according to those terms. use abi::{ArgAttribute, FnType, LayoutExt, PassMode, Reg, RegKind}; -use common::CrateContext; +use common::CodegenCx; use rustc::ty::layout::{self, TyLayout}; @@ -19,7 +19,7 @@ pub enum Flavor { Fastcall } -fn is_single_fp_element<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, +fn is_single_fp_element<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, layout: TyLayout<'tcx>) -> bool { match layout.abi { layout::Abi::Scalar(ref scalar) => { @@ -30,7 +30,7 @@ fn is_single_fp_element<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, } layout::Abi::Aggregate { .. } => { if layout.fields.count() == 1 && layout.fields.offset(0).bytes() == 0 { - is_single_fp_element(ccx, layout.field(ccx, 0)) + is_single_fp_element(cx, layout.field(cx, 0)) } else { false } @@ -39,7 +39,7 @@ fn is_single_fp_element<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, } } -pub fn compute_abi_info<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, +pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fty: &mut FnType<'tcx>, flavor: Flavor) { if !fty.ret.is_ignore() { @@ -51,12 +51,12 @@ pub fn compute_abi_info<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, // Some links: // http://www.angelcode.com/dev/callconv/callconv.html // Clang's ABI handling is in lib/CodeGen/TargetInfo.cpp - let t = &ccx.sess().target.target; + let t = &cx.sess().target.target; if t.options.is_like_osx || t.options.is_like_windows || t.options.is_like_openbsd { // According to Clang, everyone but MSVC returns single-element // float aggregates directly in a floating-point register. - if !t.options.is_like_msvc && is_single_fp_element(ccx, fty.ret.layout) { + if !t.options.is_like_msvc && is_single_fp_element(cx, fty.ret.layout) { match fty.ret.layout.size.bytes() { 4 => fty.ret.cast_to(Reg::f32()), 8 => fty.ret.cast_to(Reg::f64()), @@ -112,7 +112,7 @@ pub fn compute_abi_info<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, }; // At this point we know this must be a primitive of sorts. - let unit = arg.layout.homogeneous_aggregate(ccx).unwrap(); + let unit = arg.layout.homogeneous_aggregate(cx).unwrap(); assert_eq!(unit.size, arg.layout.size); if unit.kind == RegKind::Float { continue; diff --git a/src/librustc_trans/cabi_x86_64.rs b/src/librustc_trans/cabi_x86_64.rs index 7c9f2574693..6db18bfecf2 100644 --- a/src/librustc_trans/cabi_x86_64.rs +++ b/src/librustc_trans/cabi_x86_64.rs @@ -12,7 +12,7 @@ // https://github.com/jckarter/clay/blob/master/compiler/src/externals.cpp use abi::{ArgType, CastTarget, FnType, LayoutExt, Reg, RegKind}; -use context::CrateContext; +use context::CodegenCx; use rustc::ty::layout::{self, TyLayout, Size}; @@ -31,7 +31,7 @@ struct Memory; const LARGEST_VECTOR_SIZE: usize = 512; const MAX_EIGHTBYTES: usize = LARGEST_VECTOR_SIZE / 64; -fn classify_arg<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg: &ArgType<'tcx>) +fn classify_arg<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, arg: &ArgType<'tcx>) -> Result<[Class; MAX_EIGHTBYTES], Memory> { fn unify(cls: &mut [Class], off: Size, @@ -52,7 +52,7 @@ fn classify_arg<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg: &ArgType<'tcx>) cls[i] = to_write; } - fn classify<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, + fn classify<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, layout: TyLayout<'tcx>, cls: &mut [Class], off: Size) @@ -82,7 +82,7 @@ fn classify_arg<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg: &ArgType<'tcx>) // everything after the first one is the upper // half of a register. - let stride = element.value.size(ccx); + let stride = element.value.size(cx); for i in 1..count { let field_off = off + stride * i; unify(cls, field_off, Class::SseUp); @@ -95,7 +95,7 @@ fn classify_arg<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg: &ArgType<'tcx>) layout::Variants::Single { .. } => { for i in 0..layout.fields.count() { let field_off = off + layout.fields.offset(i); - classify(ccx, layout.field(ccx, i), cls, field_off)?; + classify(cx, layout.field(cx, i), cls, field_off)?; } } layout::Variants::Tagged { .. } | @@ -114,7 +114,7 @@ fn classify_arg<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg: &ArgType<'tcx>) } let mut cls = [Class::None; MAX_EIGHTBYTES]; - classify(ccx, arg.layout, &mut cls, Size::from_bytes(0))?; + classify(cx, arg.layout, &mut cls, Size::from_bytes(0))?; if n > 2 { if cls[0] != Class::Sse { return Err(Memory); @@ -189,12 +189,12 @@ fn cast_target(cls: &[Class], size: Size) -> CastTarget { target } -pub fn compute_abi_info<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fty: &mut FnType<'tcx>) { +pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fty: &mut FnType<'tcx>) { let mut int_regs = 6; // RDI, RSI, RDX, RCX, R8, R9 let mut sse_regs = 8; // XMM0-7 let mut x86_64_ty = |arg: &mut ArgType<'tcx>, is_arg: bool| { - let cls = classify_arg(ccx, arg); + let cls = classify_arg(cx, arg); let mut needed_int = 0; let mut needed_sse = 0; diff --git a/src/librustc_trans/callee.rs b/src/librustc_trans/callee.rs index ccbc6620ffe..c3d5e08c73e 100644 --- a/src/librustc_trans/callee.rs +++ b/src/librustc_trans/callee.rs @@ -15,7 +15,7 @@ //! closure. use attributes; -use common::{self, CrateContext}; +use common::{self, CodegenCx}; use consts; use declare; use llvm::{self, ValueRef}; @@ -34,13 +34,13 @@ use rustc_back::PanicStrategy; /// /// # Parameters /// -/// - `ccx`: the crate context +/// - `cx`: the crate context /// - `instance`: the instance to be instantiated -pub fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, +pub fn get_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, instance: Instance<'tcx>) -> ValueRef { - let tcx = ccx.tcx(); + let tcx = cx.tcx; debug!("get_fn(instance={:?})", instance); @@ -48,8 +48,8 @@ pub fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, assert!(!instance.substs.has_escaping_regions()); assert!(!instance.substs.has_param_types()); - let fn_ty = instance.ty(ccx.tcx()); - if let Some(&llfn) = ccx.instances().borrow().get(&instance) { + let fn_ty = instance.ty(cx.tcx); + if let Some(&llfn) = cx.instances.borrow().get(&instance) { return llfn; } @@ -57,10 +57,10 @@ pub fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, debug!("get_fn({:?}: {:?}) => {}", instance, fn_ty, sym); // Create a fn pointer with the substituted signature. - let fn_ptr_ty = tcx.mk_fn_ptr(common::ty_fn_sig(ccx, fn_ty)); - let llptrty = ccx.layout_of(fn_ptr_ty).llvm_type(ccx); + let fn_ptr_ty = tcx.mk_fn_ptr(common::ty_fn_sig(cx, fn_ty)); + let llptrty = cx.layout_of(fn_ptr_ty).llvm_type(cx); - let llfn = if let Some(llfn) = declare::get_declared_value(ccx, &sym) { + let llfn = if let Some(llfn) = declare::get_declared_value(cx, &sym) { // This is subtle and surprising, but sometimes we have to bitcast // the resulting fn pointer. The reason has to do with external // functions. If you have two crates that both bind the same C @@ -92,14 +92,14 @@ pub fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, llfn } } else { - let llfn = declare::declare_fn(ccx, &sym, fn_ty); + let llfn = declare::declare_fn(cx, &sym, fn_ty); assert_eq!(common::val_ty(llfn), llptrty); debug!("get_fn: not casting pointer!"); if instance.def.is_inline(tcx) { attributes::inline(llfn, attributes::InlineAttr::Hint); } - attributes::from_fn_attrs(ccx, llfn, instance.def.def_id()); + attributes::from_fn_attrs(cx, llfn, instance.def.def_id()); let instance_def_id = instance.def_id(); @@ -149,9 +149,9 @@ pub fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, unsafe { llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::ExternalLinkage); - if ccx.tcx().is_translated_function(instance_def_id) { + if cx.tcx.is_translated_function(instance_def_id) { if instance_def_id.is_local() { - if !ccx.tcx().is_exported_symbol(instance_def_id) { + if !cx.tcx.is_exported_symbol(instance_def_id) { llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden); } } else { @@ -160,7 +160,7 @@ pub fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, } } - if ccx.use_dll_storage_attrs() && + if cx.use_dll_storage_attrs && tcx.is_dllimport_foreign_item(instance_def_id) { unsafe { @@ -171,20 +171,20 @@ pub fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, llfn }; - ccx.instances().borrow_mut().insert(instance, llfn); + cx.instances.borrow_mut().insert(instance, llfn); llfn } -pub fn resolve_and_get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, +pub fn resolve_and_get_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, def_id: DefId, substs: &'tcx Substs<'tcx>) -> ValueRef { get_fn( - ccx, + cx, ty::Instance::resolve( - ccx.tcx(), + cx.tcx, ty::ParamEnv::empty(traits::Reveal::All), def_id, substs diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs index b1bdee3fa5f..9e745c3a1f5 100644 --- a/src/librustc_trans/common.rs +++ b/src/librustc_trans/common.rs @@ -38,7 +38,7 @@ use syntax::abi::Abi; use syntax::symbol::InternedString; use syntax_pos::{Span, DUMMY_SP}; -pub use context::{CrateContext, SharedCrateContext}; +pub use context::CodegenCx; pub fn type_needs_drop<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> bool { ty.needs_drop(tcx, ty::ParamEnv::empty(traits::Reveal::All)) @@ -152,46 +152,46 @@ pub fn C_uint_big(t: Type, u: u128) -> ValueRef { } } -pub fn C_bool(ccx: &CrateContext, val: bool) -> ValueRef { - C_uint(Type::i1(ccx), val as u64) +pub fn C_bool(cx: &CodegenCx, val: bool) -> ValueRef { + C_uint(Type::i1(cx), val as u64) } -pub fn C_i32(ccx: &CrateContext, i: i32) -> ValueRef { - C_int(Type::i32(ccx), i as i64) +pub fn C_i32(cx: &CodegenCx, i: i32) -> ValueRef { + C_int(Type::i32(cx), i as i64) } -pub fn C_u32(ccx: &CrateContext, i: u32) -> ValueRef { - C_uint(Type::i32(ccx), i as u64) +pub fn C_u32(cx: &CodegenCx, i: u32) -> ValueRef { + C_uint(Type::i32(cx), i as u64) } -pub fn C_u64(ccx: &CrateContext, i: u64) -> ValueRef { - C_uint(Type::i64(ccx), i) +pub fn C_u64(cx: &CodegenCx, i: u64) -> ValueRef { + C_uint(Type::i64(cx), i) } -pub fn C_usize(ccx: &CrateContext, i: u64) -> ValueRef { - let bit_size = ccx.data_layout().pointer_size.bits(); +pub fn C_usize(cx: &CodegenCx, i: u64) -> ValueRef { + let bit_size = cx.data_layout().pointer_size.bits(); if bit_size < 64 { // make sure it doesn't overflow assert!(i < (1<<bit_size)); } - C_uint(ccx.isize_ty(), i) + C_uint(cx.isize_ty, i) } -pub fn C_u8(ccx: &CrateContext, i: u8) -> ValueRef { - C_uint(Type::i8(ccx), i as u64) +pub fn C_u8(cx: &CodegenCx, i: u8) -> ValueRef { + C_uint(Type::i8(cx), i as u64) } // This is a 'c-like' raw string, which differs from // our boxed-and-length-annotated strings. -pub fn C_cstr(cx: &CrateContext, s: InternedString, null_terminated: bool) -> ValueRef { +pub fn C_cstr(cx: &CodegenCx, s: InternedString, null_terminated: bool) -> ValueRef { unsafe { - if let Some(&llval) = cx.const_cstr_cache().borrow().get(&s) { + if let Some(&llval) = cx.const_cstr_cache.borrow().get(&s) { return llval; } - let sc = llvm::LLVMConstStringInContext(cx.llcx(), + let sc = llvm::LLVMConstStringInContext(cx.llcx, s.as_ptr() as *const c_char, s.len() as c_uint, !null_terminated as Bool); @@ -203,28 +203,28 @@ pub fn C_cstr(cx: &CrateContext, s: InternedString, null_terminated: bool) -> Va llvm::LLVMSetGlobalConstant(g, True); llvm::LLVMRustSetLinkage(g, llvm::Linkage::InternalLinkage); - cx.const_cstr_cache().borrow_mut().insert(s, g); + cx.const_cstr_cache.borrow_mut().insert(s, g); g } } // NB: Do not use `do_spill_noroot` to make this into a constant string, or // you will be kicked off fast isel. See issue #4352 for an example of this. -pub fn C_str_slice(cx: &CrateContext, s: InternedString) -> ValueRef { +pub fn C_str_slice(cx: &CodegenCx, s: InternedString) -> ValueRef { let len = s.len(); let cs = consts::ptrcast(C_cstr(cx, s, false), - cx.layout_of(cx.tcx().mk_str()).llvm_type(cx).ptr_to()); + cx.layout_of(cx.tcx.mk_str()).llvm_type(cx).ptr_to()); C_fat_ptr(cx, cs, C_usize(cx, len as u64)) } -pub fn C_fat_ptr(cx: &CrateContext, ptr: ValueRef, meta: ValueRef) -> ValueRef { +pub fn C_fat_ptr(cx: &CodegenCx, ptr: ValueRef, meta: ValueRef) -> ValueRef { assert_eq!(abi::FAT_PTR_ADDR, 0); assert_eq!(abi::FAT_PTR_EXTRA, 1); C_struct(cx, &[ptr, meta], false) } -pub fn C_struct(cx: &CrateContext, elts: &[ValueRef], packed: bool) -> ValueRef { - C_struct_in_context(cx.llcx(), elts, packed) +pub fn C_struct(cx: &CodegenCx, elts: &[ValueRef], packed: bool) -> ValueRef { + C_struct_in_context(cx.llcx, elts, packed) } pub fn C_struct_in_context(llcx: ContextRef, elts: &[ValueRef], packed: bool) -> ValueRef { @@ -247,8 +247,8 @@ pub fn C_vector(elts: &[ValueRef]) -> ValueRef { } } -pub fn C_bytes(cx: &CrateContext, bytes: &[u8]) -> ValueRef { - C_bytes_in_context(cx.llcx(), bytes) +pub fn C_bytes(cx: &CodegenCx, bytes: &[u8]) -> ValueRef { + C_bytes_in_context(cx.llcx, bytes) } pub fn C_bytes_in_context(llcx: ContextRef, bytes: &[u8]) -> ValueRef { @@ -328,37 +328,37 @@ pub fn langcall(tcx: TyCtxt, // of Java. (See related discussion on #1877 and #10183.) pub fn build_unchecked_lshift<'a, 'tcx>( - bcx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'tcx>, lhs: ValueRef, rhs: ValueRef ) -> ValueRef { - let rhs = base::cast_shift_expr_rhs(bcx, hir::BinOp_::BiShl, lhs, rhs); + let rhs = base::cast_shift_expr_rhs(bx, hir::BinOp_::BiShl, lhs, rhs); // #1877, #10183: Ensure that input is always valid - let rhs = shift_mask_rhs(bcx, rhs); - bcx.shl(lhs, rhs) + let rhs = shift_mask_rhs(bx, rhs); + bx.shl(lhs, rhs) } pub fn build_unchecked_rshift<'a, 'tcx>( - bcx: &Builder<'a, 'tcx>, lhs_t: Ty<'tcx>, lhs: ValueRef, rhs: ValueRef + bx: &Builder<'a, 'tcx>, lhs_t: Ty<'tcx>, lhs: ValueRef, rhs: ValueRef ) -> ValueRef { - let rhs = base::cast_shift_expr_rhs(bcx, hir::BinOp_::BiShr, lhs, rhs); + let rhs = base::cast_shift_expr_rhs(bx, hir::BinOp_::BiShr, lhs, rhs); // #1877, #10183: Ensure that input is always valid - let rhs = shift_mask_rhs(bcx, rhs); + let rhs = shift_mask_rhs(bx, rhs); let is_signed = lhs_t.is_signed(); if is_signed { - bcx.ashr(lhs, rhs) + bx.ashr(lhs, rhs) } else { - bcx.lshr(lhs, rhs) + bx.lshr(lhs, rhs) } } -fn shift_mask_rhs<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, rhs: ValueRef) -> ValueRef { +fn shift_mask_rhs<'a, 'tcx>(bx: &Builder<'a, 'tcx>, rhs: ValueRef) -> ValueRef { let rhs_llty = val_ty(rhs); - bcx.and(rhs, shift_mask_val(bcx, rhs_llty, rhs_llty, false)) + bx.and(rhs, shift_mask_val(bx, rhs_llty, rhs_llty, false)) } pub fn shift_mask_val<'a, 'tcx>( - bcx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'tcx>, llty: Type, mask_llty: Type, invert: bool @@ -375,23 +375,23 @@ pub fn shift_mask_val<'a, 'tcx>( } }, TypeKind::Vector => { - let mask = shift_mask_val(bcx, llty.element_type(), mask_llty.element_type(), invert); - bcx.vector_splat(mask_llty.vector_length(), mask) + let mask = shift_mask_val(bx, llty.element_type(), mask_llty.element_type(), invert); + bx.vector_splat(mask_llty.vector_length(), mask) }, _ => bug!("shift_mask_val: expected Integer or Vector, found {:?}", kind), } } -pub fn ty_fn_sig<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, +pub fn ty_fn_sig<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ty: Ty<'tcx>) -> ty::PolyFnSig<'tcx> { match ty.sty { ty::TyFnDef(..) | // Shims currently have type TyFnPtr. Not sure this should remain. - ty::TyFnPtr(_) => ty.fn_sig(ccx.tcx()), + ty::TyFnPtr(_) => ty.fn_sig(cx.tcx), ty::TyClosure(def_id, substs) => { - let tcx = ccx.tcx(); + let tcx = cx.tcx; let sig = substs.closure_sig(def_id, tcx); let env_ty = tcx.closure_env_ty(def_id, substs).unwrap(); @@ -404,8 +404,8 @@ pub fn ty_fn_sig<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, )) } ty::TyGenerator(def_id, substs, _) => { - let tcx = ccx.tcx(); - let sig = substs.generator_poly_sig(def_id, ccx.tcx()); + let tcx = cx.tcx; + let sig = substs.generator_poly_sig(def_id, cx.tcx); let env_region = ty::ReLateBound(ty::DebruijnIndex::new(1), ty::BrEnv); let env_ty = tcx.mk_mut_ref(tcx.mk_region(env_region), ty); diff --git a/src/librustc_trans/consts.rs b/src/librustc_trans/consts.rs index f9fbcebd32e..d5b33d837c5 100644 --- a/src/librustc_trans/consts.rs +++ b/src/librustc_trans/consts.rs @@ -17,7 +17,7 @@ use rustc::middle::const_val::ConstEvalErr; use debuginfo; use base; use monomorphize::{MonoItem, MonoItemExt}; -use common::{CrateContext, val_ty}; +use common::{CodegenCx, val_ty}; use declare; use monomorphize::Instance; use type_::Type; @@ -43,17 +43,17 @@ pub fn bitcast(val: ValueRef, ty: Type) -> ValueRef { } } -fn set_global_alignment(ccx: &CrateContext, +fn set_global_alignment(cx: &CodegenCx, gv: ValueRef, mut align: Align) { // The target may require greater alignment for globals than the type does. // 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) = ccx.sess().target.target.options.min_global_align { + if let Some(min) = cx.sess().target.target.options.min_global_align { match ty::layout::Align::from_bits(min, min) { Ok(min) => align = align.max(min), Err(err) => { - ccx.sess().err(&format!("invalid minimum global alignment: {}", err)); + cx.sess().err(&format!("invalid minimum global alignment: {}", err)); } } } @@ -62,30 +62,30 @@ fn set_global_alignment(ccx: &CrateContext, } } -pub fn addr_of_mut(ccx: &CrateContext, +pub fn addr_of_mut(cx: &CodegenCx, cv: ValueRef, align: Align, kind: &str) -> ValueRef { unsafe { - let name = ccx.generate_local_symbol_name(kind); - let gv = declare::define_global(ccx, &name[..], val_ty(cv)).unwrap_or_else(||{ + let name = cx.generate_local_symbol_name(kind); + let gv = declare::define_global(cx, &name[..], val_ty(cv)).unwrap_or_else(||{ bug!("symbol `{}` is already defined", name); }); llvm::LLVMSetInitializer(gv, cv); - set_global_alignment(ccx, gv, align); + set_global_alignment(cx, gv, align); llvm::LLVMRustSetLinkage(gv, llvm::Linkage::PrivateLinkage); SetUnnamedAddr(gv, true); gv } } -pub fn addr_of(ccx: &CrateContext, +pub fn addr_of(cx: &CodegenCx, cv: ValueRef, align: Align, kind: &str) -> ValueRef { - if let Some(&gv) = ccx.const_globals().borrow().get(&cv) { + if let Some(&gv) = cx.const_globals.borrow().get(&cv) { unsafe { // Upgrade the alignment in cases where the same constant is used with different // alignment requirements @@ -96,42 +96,42 @@ pub fn addr_of(ccx: &CrateContext, } return gv; } - let gv = addr_of_mut(ccx, cv, align, kind); + let gv = addr_of_mut(cx, cv, align, kind); unsafe { llvm::LLVMSetGlobalConstant(gv, True); } - ccx.const_globals().borrow_mut().insert(cv, gv); + cx.const_globals.borrow_mut().insert(cv, gv); gv } -pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef { - let instance = Instance::mono(ccx.tcx(), def_id); - if let Some(&g) = ccx.instances().borrow().get(&instance) { +pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef { + let instance = Instance::mono(cx.tcx, def_id); + if let Some(&g) = cx.instances.borrow().get(&instance) { return g; } - let ty = instance.ty(ccx.tcx()); - let g = if let Some(id) = ccx.tcx().hir.as_local_node_id(def_id) { + let ty = instance.ty(cx.tcx); + let g = if let Some(id) = cx.tcx.hir.as_local_node_id(def_id) { - let llty = ccx.layout_of(ty).llvm_type(ccx); - let (g, attrs) = match ccx.tcx().hir.get(id) { + let llty = cx.layout_of(ty).llvm_type(cx); + let (g, attrs) = match cx.tcx.hir.get(id) { hir_map::NodeItem(&hir::Item { ref attrs, span, node: hir::ItemStatic(..), .. }) => { - let sym = MonoItem::Static(id).symbol_name(ccx.tcx()); + let sym = MonoItem::Static(id).symbol_name(cx.tcx); - let defined_in_current_codegen_unit = ccx.codegen_unit() + let defined_in_current_codegen_unit = cx.codegen_unit .items() .contains_key(&MonoItem::Static(id)); assert!(!defined_in_current_codegen_unit); - if declare::get_declared_value(ccx, &sym[..]).is_some() { + if declare::get_declared_value(cx, &sym[..]).is_some() { span_bug!(span, "trans: Conflicting symbol names for static?"); } - let g = declare::define_global(ccx, &sym[..], llty).unwrap(); + let g = declare::define_global(cx, &sym[..], llty).unwrap(); - if !ccx.tcx().is_exported_symbol(def_id) { + if !cx.tcx.is_exported_symbol(def_id) { unsafe { llvm::LLVMRustSetVisibility(g, llvm::Visibility::Hidden); } @@ -143,7 +143,7 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef { hir_map::NodeForeignItem(&hir::ForeignItem { ref attrs, span, node: hir::ForeignItemStatic(..), .. }) => { - let sym = ccx.tcx().symbol_name(instance); + let sym = cx.tcx.symbol_name(instance); let g = if let Some(name) = attr::first_attr_value_str_by_name(&attrs, "linkage") { // If this is a static with a linkage specified, then we need to handle @@ -154,18 +154,18 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef { let linkage = match base::linkage_by_name(&name.as_str()) { Some(linkage) => linkage, None => { - ccx.sess().span_fatal(span, "invalid linkage specified"); + cx.sess().span_fatal(span, "invalid linkage specified"); } }; let llty2 = match ty.sty { - ty::TyRawPtr(ref mt) => ccx.layout_of(mt.ty).llvm_type(ccx), + ty::TyRawPtr(ref mt) => cx.layout_of(mt.ty).llvm_type(cx), _ => { - ccx.sess().span_fatal(span, "must have type `*const T` or `*mut T`"); + cx.sess().span_fatal(span, "must have type `*const T` or `*mut T`"); } }; unsafe { // Declare a symbol `foo` with the desired linkage. - let g1 = declare::declare_global(ccx, &sym, llty2); + let g1 = declare::declare_global(cx, &sym, llty2); llvm::LLVMRustSetLinkage(g1, base::linkage_to_llvm(linkage)); // Declare an internal global `extern_with_linkage_foo` which @@ -176,8 +176,8 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef { // zero. let mut real_name = "_rust_extern_with_linkage_".to_string(); real_name.push_str(&sym); - let g2 = declare::define_global(ccx, &real_name, llty).unwrap_or_else(||{ - ccx.sess().span_fatal(span, + let g2 = declare::define_global(cx, &real_name, llty).unwrap_or_else(||{ + cx.sess().span_fatal(span, &format!("symbol `{}` is already defined", &sym)) }); llvm::LLVMRustSetLinkage(g2, llvm::Linkage::InternalLinkage); @@ -186,7 +186,7 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef { } } else { // Generate an external declaration. - declare::declare_global(ccx, &sym, llty) + declare::declare_global(cx, &sym, llty) }; (g, attrs) @@ -197,29 +197,29 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef { for attr in attrs { if attr.check_name("thread_local") { - llvm::set_thread_local_mode(g, ccx.tls_model()); + llvm::set_thread_local_mode(g, cx.tls_model); } } g } else { - let sym = ccx.tcx().symbol_name(instance); + let sym = cx.tcx.symbol_name(instance); // FIXME(nagisa): perhaps the map of externs could be offloaded to llvm somehow? // FIXME(nagisa): investigate whether it can be changed into define_global - let g = declare::declare_global(ccx, &sym, ccx.layout_of(ty).llvm_type(ccx)); + let g = declare::declare_global(cx, &sym, cx.layout_of(ty).llvm_type(cx)); // Thread-local statics in some other crate need to *always* be linked // against in a thread-local fashion, so we need to be sure to apply the // thread-local attribute locally if it was present remotely. If we // don't do this then linker errors can be generated where the linker // complains that one object files has a thread local version of the // symbol and another one doesn't. - for attr in ccx.tcx().get_attrs(def_id).iter() { + for attr in cx.tcx.get_attrs(def_id).iter() { if attr.check_name("thread_local") { - llvm::set_thread_local_mode(g, ccx.tls_model()); + llvm::set_thread_local_mode(g, cx.tls_model); } } - if ccx.use_dll_storage_attrs() && !ccx.tcx().is_foreign_item(def_id) { + if cx.use_dll_storage_attrs && !cx.tcx.is_foreign_item(def_id) { // This item is external but not foreign, i.e. it originates from an external Rust // crate. Since we don't know whether this crate will be linked dynamically or // statically in the final application, we always mark such symbols as 'dllimport'. @@ -232,42 +232,42 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef { g }; - if ccx.use_dll_storage_attrs() && ccx.tcx().is_dllimport_foreign_item(def_id) { + if cx.use_dll_storage_attrs && cx.tcx.is_dllimport_foreign_item(def_id) { // For foreign (native) libs we know the exact storage type to use. unsafe { llvm::LLVMSetDLLStorageClass(g, llvm::DLLStorageClass::DllImport); } } - ccx.instances().borrow_mut().insert(instance, g); - ccx.statics().borrow_mut().insert(g, def_id); + cx.instances.borrow_mut().insert(instance, g); + cx.statics.borrow_mut().insert(g, def_id); g } -pub fn trans_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, +pub fn trans_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, m: hir::Mutability, id: ast::NodeId, attrs: &[ast::Attribute]) -> Result<ValueRef, ConstEvalErr<'tcx>> { unsafe { - let def_id = ccx.tcx().hir.local_def_id(id); - let g = get_static(ccx, def_id); + let def_id = cx.tcx.hir.local_def_id(id); + let g = get_static(cx, def_id); - let v = ::mir::trans_static_initializer(ccx, def_id)?; + let v = ::mir::trans_static_initializer(cx, def_id)?; // boolean SSA values are i1, but they have to be stored in i8 slots, // otherwise some LLVM optimization passes don't work as expected let mut val_llty = val_ty(v); - let v = if val_llty == Type::i1(ccx) { - val_llty = Type::i8(ccx); + let v = if val_llty == Type::i1(cx) { + val_llty = Type::i8(cx); llvm::LLVMConstZExt(v, val_llty.to_ref()) } else { v }; - let instance = Instance::mono(ccx.tcx(), def_id); - let ty = instance.ty(ccx.tcx()); - let llty = ccx.layout_of(ty).llvm_type(ccx); + let instance = Instance::mono(cx.tcx, def_id); + let ty = instance.ty(cx.tcx); + let llty = cx.layout_of(ty).llvm_type(cx); let g = if val_llty == llty { g } else { @@ -282,7 +282,7 @@ pub fn trans_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let visibility = llvm::LLVMRustGetVisibility(g); let new_g = llvm::LLVMRustGetOrInsertGlobal( - ccx.llmod(), name_string.as_ptr(), val_llty.to_ref()); + cx.llmod, name_string.as_ptr(), val_llty.to_ref()); llvm::LLVMRustSetLinkage(new_g, linkage); llvm::LLVMRustSetVisibility(new_g, visibility); @@ -290,32 +290,32 @@ pub fn trans_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, // To avoid breaking any invariants, we leave around the old // global for the moment; we'll replace all references to it // with the new global later. (See base::trans_crate.) - ccx.statics_to_rauw().borrow_mut().push((g, new_g)); + cx.statics_to_rauw.borrow_mut().push((g, new_g)); new_g }; - set_global_alignment(ccx, g, ccx.align_of(ty)); + set_global_alignment(cx, g, cx.align_of(ty)); llvm::LLVMSetInitializer(g, v); // As an optimization, all shared statics which do not have interior // mutability are placed into read-only memory. if m != hir::MutMutable { - if ccx.shared().type_is_freeze(ty) { + if cx.type_is_freeze(ty) { llvm::LLVMSetGlobalConstant(g, llvm::True); } } - debuginfo::create_global_var_metadata(ccx, id, g); + debuginfo::create_global_var_metadata(cx, id, g); if attr::contains_name(attrs, "thread_local") { - llvm::set_thread_local_mode(g, ccx.tls_model()); + llvm::set_thread_local_mode(g, cx.tls_model); } - base::set_link_section(ccx, g, attrs); + base::set_link_section(cx, g, attrs); if attr::contains_name(attrs, "used") { // This static will be stored in the llvm.used variable which is an array of i8* - let cast = llvm::LLVMConstPointerCast(g, Type::i8p(ccx).to_ref()); - ccx.used_statics().borrow_mut().push(cast); + let cast = llvm::LLVMConstPointerCast(g, Type::i8p(cx).to_ref()); + cx.used_statics.borrow_mut().push(cast); } Ok(g) diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index 3014963a97f..06b8d9ff7b3 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -11,10 +11,9 @@ use common; use llvm; use llvm::{ContextRef, ModuleRef, ValueRef}; -use rustc::dep_graph::{DepGraph, DepGraphSafe}; +use rustc::dep_graph::DepGraphSafe; use rustc::hir; use rustc::hir::def_id::DefId; -use rustc::ich::StableHashingContext; use rustc::traits; use debuginfo; use callee; @@ -28,7 +27,6 @@ use type_of::PointeeInfo; use rustc_data_structures::base_n; use rustc::mir::mono::Stats; -use rustc_data_structures::stable_hasher::StableHashingContextProvider; use rustc::session::config::{self, NoDebugInfo}; use rustc::session::Session; use rustc::ty::layout::{LayoutError, LayoutOf, Size, TyLayout}; @@ -41,38 +39,30 @@ use std::ptr; use std::iter; use std::str; use std::sync::Arc; -use std::marker::PhantomData; use syntax::symbol::InternedString; use abi::Abi; -/// The shared portion of a `CrateContext`. There is one `SharedCrateContext` -/// per crate. The data here is shared between all compilation units of the -/// crate, so it must not contain references to any LLVM data structures -/// (aside from metadata-related ones). -pub struct SharedCrateContext<'a, 'tcx: 'a> { - tcx: TyCtxt<'a, 'tcx, 'tcx>, - check_overflow: bool, - use_dll_storage_attrs: bool, - tls_model: llvm::ThreadLocalMode, -} +/// There is one `CodegenCx` per compilation unit. Each one has its own LLVM +/// `ContextRef` so that several compilation units may be optimized in parallel. +/// All other LLVM data structures in the `CodegenCx` are tied to that `ContextRef`. +pub struct CodegenCx<'a, 'tcx: 'a> { + pub tcx: TyCtxt<'a, 'tcx, 'tcx>, + pub check_overflow: bool, + pub use_dll_storage_attrs: bool, + pub tls_model: llvm::ThreadLocalMode, -/// The local portion of a `CrateContext`. There is one `LocalCrateContext` -/// per compilation unit. Each one has its own LLVM `ContextRef` so that -/// several compilation units may be optimized in parallel. All other LLVM -/// data structures in the `LocalCrateContext` are tied to that `ContextRef`. -pub struct LocalCrateContext<'a, 'tcx: 'a> { - llmod: ModuleRef, - llcx: ContextRef, - stats: RefCell<Stats>, - codegen_unit: Arc<CodegenUnit<'tcx>>, + pub llmod: ModuleRef, + pub llcx: ContextRef, + pub stats: RefCell<Stats>, + pub codegen_unit: Arc<CodegenUnit<'tcx>>, /// Cache instances of monomorphic and polymorphic items - instances: RefCell<FxHashMap<Instance<'tcx>, ValueRef>>, + pub instances: RefCell<FxHashMap<Instance<'tcx>, ValueRef>>, /// Cache generated vtables - vtables: RefCell<FxHashMap<(Ty<'tcx>, + pub vtables: RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), ValueRef>>, /// Cache of constant strings, - const_cstr_cache: RefCell<FxHashMap<InternedString, ValueRef>>, + pub const_cstr_cache: RefCell<FxHashMap<InternedString, ValueRef>>, /// Reverse-direction for const ptrs cast from globals. /// Key is a ValueRef holding a *T, @@ -82,72 +72,42 @@ pub struct LocalCrateContext<'a, 'tcx: 'a> { /// when we ptrcast, and we have to ptrcast during translation /// of a [T] const because we form a slice, a (*T,usize) pair, not /// a pointer to an LLVM array type. Similar for trait objects. - const_unsized: RefCell<FxHashMap<ValueRef, ValueRef>>, + pub const_unsized: RefCell<FxHashMap<ValueRef, ValueRef>>, /// Cache of emitted const globals (value -> global) - const_globals: RefCell<FxHashMap<ValueRef, ValueRef>>, + pub const_globals: RefCell<FxHashMap<ValueRef, ValueRef>>, /// Mapping from static definitions to their DefId's. - statics: RefCell<FxHashMap<ValueRef, DefId>>, + pub statics: RefCell<FxHashMap<ValueRef, DefId>>, /// List of globals for static variables which need to be passed to the /// LLVM function ReplaceAllUsesWith (RAUW) when translation is complete. /// (We have to make sure we don't invalidate any ValueRefs referring /// to constants.) - statics_to_rauw: RefCell<Vec<(ValueRef, ValueRef)>>, + pub statics_to_rauw: RefCell<Vec<(ValueRef, ValueRef)>>, /// Statics that will be placed in the llvm.used variable /// See http://llvm.org/docs/LangRef.html#the-llvm-used-global-variable for details - used_statics: RefCell<Vec<ValueRef>>, + pub used_statics: RefCell<Vec<ValueRef>>, - lltypes: RefCell<FxHashMap<(Ty<'tcx>, Option<usize>), Type>>, - scalar_lltypes: RefCell<FxHashMap<Ty<'tcx>, Type>>, - pointee_infos: RefCell<FxHashMap<(Ty<'tcx>, Size), Option<PointeeInfo>>>, - isize_ty: Type, + pub lltypes: RefCell<FxHashMap<(Ty<'tcx>, Option<usize>), Type>>, + pub scalar_lltypes: RefCell<FxHashMap<Ty<'tcx>, Type>>, + pub pointee_infos: RefCell<FxHashMap<(Ty<'tcx>, Size), Option<PointeeInfo>>>, + pub isize_ty: Type, - dbg_cx: Option<debuginfo::CrateDebugContext<'tcx>>, + pub dbg_cx: Option<debuginfo::CrateDebugContext<'tcx>>, eh_personality: Cell<Option<ValueRef>>, eh_unwind_resume: Cell<Option<ValueRef>>, - rust_try_fn: Cell<Option<ValueRef>>, + pub rust_try_fn: Cell<Option<ValueRef>>, intrinsics: RefCell<FxHashMap<&'static str, ValueRef>>, /// A counter that is used for generating local symbol names local_gen_sym_counter: Cell<usize>, - - /// A placeholder so we can add lifetimes - placeholder: PhantomData<&'a ()>, -} - -/// A CrateContext value binds together one LocalCrateContext with the -/// SharedCrateContext. It exists as a convenience wrapper, so we don't have to -/// pass around (SharedCrateContext, LocalCrateContext) tuples all over trans. -pub struct CrateContext<'a, 'tcx: 'a> { - shared: &'a SharedCrateContext<'a, 'tcx>, - local_ccx: &'a LocalCrateContext<'a, 'tcx>, -} - -impl<'a, 'tcx> CrateContext<'a, 'tcx> { - pub fn new(shared: &'a SharedCrateContext<'a, 'tcx>, - local_ccx: &'a LocalCrateContext<'a, 'tcx>) - -> Self { - CrateContext { shared, local_ccx } - } -} - -impl<'a, 'tcx> DepGraphSafe for CrateContext<'a, 'tcx> { -} - -impl<'a, 'tcx> DepGraphSafe for SharedCrateContext<'a, 'tcx> { } -impl<'a, 'tcx> StableHashingContextProvider for SharedCrateContext<'a, 'tcx> { - type ContextType = StableHashingContext<'tcx>; - - fn create_stable_hashing_context(&self) -> Self::ContextType { - self.tcx.create_stable_hashing_context() - } +impl<'a, 'tcx> DepGraphSafe for CodegenCx<'a, 'tcx> { } pub fn get_reloc_model(sess: &Session) -> llvm::RelocMode { @@ -252,8 +212,11 @@ pub unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (Cont (llcx, llmod) } -impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> { - pub fn new(tcx: TyCtxt<'b, 'tcx, 'tcx>) -> SharedCrateContext<'b, 'tcx> { +impl<'a, 'tcx> CodegenCx<'a, 'tcx> { + pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, + codegen_unit: Arc<CodegenUnit<'tcx>>, + llmod_id: &str) + -> CodegenCx<'a, 'tcx> { // An interesting part of Windows which MSVC forces our hand on (and // apparently MinGW didn't) is the usage of `dllimport` and `dllexport` // attributes in LLVM IR as well as native dependencies (in C these @@ -303,78 +266,25 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> { let tls_model = get_tls_model(&tcx.sess); - SharedCrateContext { - tcx, - check_overflow, - use_dll_storage_attrs, - tls_model, - } - } - - pub fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool { - common::type_needs_drop(self.tcx, ty) - } - - pub fn type_is_sized(&self, ty: Ty<'tcx>) -> bool { - common::type_is_sized(self.tcx, ty) - } - - pub fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool { - common::type_is_freeze(self.tcx, ty) - } - - pub fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool { - use syntax_pos::DUMMY_SP; - if ty.is_sized(self.tcx, ty::ParamEnv::empty(traits::Reveal::All), DUMMY_SP) { - return false; - } - - let tail = self.tcx.struct_tail(ty); - match tail.sty { - ty::TyForeign(..) => false, - ty::TyStr | ty::TySlice(..) | ty::TyDynamic(..) => true, - _ => bug!("unexpected unsized tail: {:?}", tail.sty), - } - } - - pub fn tcx(&self) -> TyCtxt<'b, 'tcx, 'tcx> { - self.tcx - } - - pub fn sess<'a>(&'a self) -> &'a Session { - &self.tcx.sess - } - - pub fn dep_graph<'a>(&'a self) -> &'a DepGraph { - &self.tcx.dep_graph - } - - pub fn use_dll_storage_attrs(&self) -> bool { - self.use_dll_storage_attrs - } -} - -impl<'a, 'tcx> LocalCrateContext<'a, 'tcx> { - pub fn new(shared: &SharedCrateContext<'a, 'tcx>, - codegen_unit: Arc<CodegenUnit<'tcx>>, - llmod_id: &str) - -> LocalCrateContext<'a, 'tcx> { unsafe { - let (llcx, llmod) = create_context_and_module(&shared.tcx.sess, + let (llcx, llmod) = create_context_and_module(&tcx.sess, &llmod_id[..]); - let dbg_cx = if shared.tcx.sess.opts.debuginfo != NoDebugInfo { + let dbg_cx = if tcx.sess.opts.debuginfo != NoDebugInfo { let dctx = debuginfo::CrateDebugContext::new(llmod); - debuginfo::metadata::compile_unit_metadata(shared, + debuginfo::metadata::compile_unit_metadata(tcx, codegen_unit.name(), - &dctx, - shared.tcx.sess); + &dctx); Some(dctx) } else { None }; - let local_ccx = LocalCrateContext { + let mut cx = CodegenCx { + tcx, + check_overflow, + use_dll_storage_attrs, + tls_model, llmod, llcx, stats: RefCell::new(Stats::default()), @@ -397,41 +307,9 @@ impl<'a, 'tcx> LocalCrateContext<'a, 'tcx> { rust_try_fn: Cell::new(None), intrinsics: RefCell::new(FxHashMap()), local_gen_sym_counter: Cell::new(0), - placeholder: PhantomData, }; - - let (isize_ty, mut local_ccx) = { - // Do a little dance to create a dummy CrateContext, so we can - // create some things in the LLVM module of this codegen unit - let mut local_ccxs = vec![local_ccx]; - let isize_ty = { - let dummy_ccx = LocalCrateContext::dummy_ccx(shared, - local_ccxs.as_mut_slice()); - Type::isize(&dummy_ccx) - }; - (isize_ty, local_ccxs.pop().unwrap()) - }; - - local_ccx.isize_ty = isize_ty; - - local_ccx - } - } - - /// Create a dummy `CrateContext` from `self` and the provided - /// `SharedCrateContext`. This is somewhat dangerous because `self` may - /// not be fully initialized. - /// - /// This is used in the `LocalCrateContext` constructor to allow calling - /// functions that expect a complete `CrateContext`, even before the local - /// portion is fully initialized and attached to the `SharedCrateContext`. - fn dummy_ccx(shared: &'a SharedCrateContext<'a, 'tcx>, - local_ccxs: &'a [LocalCrateContext<'a, 'tcx>]) - -> CrateContext<'a, 'tcx> { - assert!(local_ccxs.len() == 1); - CrateContext { - shared, - local_ccx: &local_ccxs[0] + cx.isize_ty = Type::isize(&cx); + cx } } @@ -440,25 +318,13 @@ impl<'a, 'tcx> LocalCrateContext<'a, 'tcx> { } } -impl<'b, 'tcx> CrateContext<'b, 'tcx> { - pub fn shared(&self) -> &'b SharedCrateContext<'b, 'tcx> { - self.shared - } - - fn local(&self) -> &'b LocalCrateContext<'b, 'tcx> { - self.local_ccx - } - - pub fn tcx(&self) -> TyCtxt<'b, 'tcx, 'tcx> { - self.shared.tcx - } - +impl<'b, 'tcx> CodegenCx<'b, 'tcx> { pub fn sess<'a>(&'a self) -> &'a Session { - &self.shared.tcx.sess + &self.tcx.sess } pub fn get_intrinsic(&self, key: &str) -> ValueRef { - if let Some(v) = self.intrinsics().borrow().get(key).cloned() { + if let Some(v) = self.intrinsics.borrow().get(key).cloned() { return v; } match declare_intrinsic(self, key) { @@ -467,106 +333,11 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { } } - pub fn llmod(&self) -> ModuleRef { - self.local().llmod - } - - pub fn llcx(&self) -> ContextRef { - self.local().llcx - } - - pub fn codegen_unit(&self) -> &CodegenUnit<'tcx> { - &self.local().codegen_unit - } - - pub fn td(&self) -> llvm::TargetDataRef { - unsafe { llvm::LLVMRustGetModuleDataLayout(self.llmod()) } - } - - pub fn instances<'a>(&'a self) -> &'a RefCell<FxHashMap<Instance<'tcx>, ValueRef>> { - &self.local().instances - } - - pub fn vtables<'a>(&'a self) - -> &'a RefCell<FxHashMap<(Ty<'tcx>, - Option<ty::PolyExistentialTraitRef<'tcx>>), ValueRef>> { - &self.local().vtables - } - - pub fn const_cstr_cache<'a>(&'a self) -> &'a RefCell<FxHashMap<InternedString, ValueRef>> { - &self.local().const_cstr_cache - } - - pub fn const_unsized<'a>(&'a self) -> &'a RefCell<FxHashMap<ValueRef, ValueRef>> { - &self.local().const_unsized - } - - pub fn const_globals<'a>(&'a self) -> &'a RefCell<FxHashMap<ValueRef, ValueRef>> { - &self.local().const_globals - } - - pub fn statics<'a>(&'a self) -> &'a RefCell<FxHashMap<ValueRef, DefId>> { - &self.local().statics - } - - pub fn statics_to_rauw<'a>(&'a self) -> &'a RefCell<Vec<(ValueRef, ValueRef)>> { - &self.local().statics_to_rauw - } - - pub fn used_statics<'a>(&'a self) -> &'a RefCell<Vec<ValueRef>> { - &self.local().used_statics - } - - pub fn lltypes<'a>(&'a self) -> &'a RefCell<FxHashMap<(Ty<'tcx>, Option<usize>), Type>> { - &self.local().lltypes - } - - pub fn scalar_lltypes<'a>(&'a self) -> &'a RefCell<FxHashMap<Ty<'tcx>, Type>> { - &self.local().scalar_lltypes - } - - pub fn pointee_infos<'a>(&'a self) - -> &'a RefCell<FxHashMap<(Ty<'tcx>, Size), Option<PointeeInfo>>> { - &self.local().pointee_infos - } - - pub fn stats<'a>(&'a self) -> &'a RefCell<Stats> { - &self.local().stats - } - - pub fn isize_ty(&self) -> Type { - self.local().isize_ty - } - - pub fn dbg_cx<'a>(&'a self) -> &'a Option<debuginfo::CrateDebugContext<'tcx>> { - &self.local().dbg_cx - } - - pub fn rust_try_fn<'a>(&'a self) -> &'a Cell<Option<ValueRef>> { - &self.local().rust_try_fn - } - - fn intrinsics<'a>(&'a self) -> &'a RefCell<FxHashMap<&'static str, ValueRef>> { - &self.local().intrinsics - } - - pub fn check_overflow(&self) -> bool { - self.shared.check_overflow - } - - pub fn use_dll_storage_attrs(&self) -> bool { - self.shared.use_dll_storage_attrs() - } - - pub fn tls_model(&self) -> llvm::ThreadLocalMode { - self.shared.tls_model - } - /// Generate a new symbol name with the given prefix. This symbol name must /// only be used for definitions with `internal` or `private` linkage. pub fn generate_local_symbol_name(&self, prefix: &str) -> String { - let idx = self.local().local_gen_sym_counter.get(); - self.local().local_gen_sym_counter.set(idx + 1); + let idx = self.local_gen_sym_counter.get(); + self.local_gen_sym_counter.set(idx + 1); // Include a '.' character, so there can be no accidental conflicts with // user defined names let mut name = String::with_capacity(prefix.len() + 6); @@ -597,10 +368,10 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { // `rust_eh_personality` function, but rather we wired it up to the // CRT's custom personality function, which forces LLVM to consider // landing pads as "landing pads for SEH". - if let Some(llpersonality) = self.local().eh_personality.get() { + if let Some(llpersonality) = self.eh_personality.get() { return llpersonality } - let tcx = self.tcx(); + let tcx = self.tcx; let llfn = match tcx.lang_items().eh_personality() { Some(def_id) if !base::wants_msvc_seh(self.sess()) => { callee::resolve_and_get_fn(self, def_id, tcx.intern_substs(&[])) @@ -615,7 +386,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { declare::declare_cfn(self, name, fty) } }; - self.local().eh_personality.set(Some(llfn)); + self.eh_personality.set(Some(llfn)); llfn } @@ -623,12 +394,12 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { // otherwise declares it as an external function. pub fn eh_unwind_resume(&self) -> ValueRef { use attributes; - let unwresume = &self.local().eh_unwind_resume; + let unwresume = &self.eh_unwind_resume; if let Some(llfn) = unwresume.get() { return llfn; } - let tcx = self.tcx(); + let tcx = self.tcx; assert!(self.sess().target.target.options.custom_unwind_resume); if let Some(def_id) = tcx.lang_items().eh_unwind_resume() { let llfn = callee::resolve_and_get_fn(self, def_id, tcx.intern_substs(&[])); @@ -649,33 +420,47 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { unwresume.set(Some(llfn)); llfn } -} -impl<'a, 'tcx> ty::layout::HasDataLayout for &'a SharedCrateContext<'a, 'tcx> { - fn data_layout(&self) -> &ty::layout::TargetDataLayout { - &self.tcx.data_layout + pub fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool { + common::type_needs_drop(self.tcx, ty) } -} -impl<'a, 'tcx> ty::layout::HasTyCtxt<'tcx> for &'a SharedCrateContext<'a, 'tcx> { - fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> { - self.tcx + pub fn type_is_sized(&self, ty: Ty<'tcx>) -> bool { + common::type_is_sized(self.tcx, ty) + } + + pub fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool { + common::type_is_freeze(self.tcx, ty) + } + + pub fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool { + use syntax_pos::DUMMY_SP; + if ty.is_sized(self.tcx, ty::ParamEnv::empty(traits::Reveal::All), DUMMY_SP) { + return false; + } + + let tail = self.tcx.struct_tail(ty); + match tail.sty { + ty::TyForeign(..) => false, + ty::TyStr | ty::TySlice(..) | ty::TyDynamic(..) => true, + _ => bug!("unexpected unsized tail: {:?}", tail.sty), + } } } -impl<'a, 'tcx> ty::layout::HasDataLayout for &'a CrateContext<'a, 'tcx> { +impl<'a, 'tcx> ty::layout::HasDataLayout for &'a CodegenCx<'a, 'tcx> { fn data_layout(&self) -> &ty::layout::TargetDataLayout { - &self.shared.tcx.data_layout + &self.tcx.data_layout } } -impl<'a, 'tcx> ty::layout::HasTyCtxt<'tcx> for &'a CrateContext<'a, 'tcx> { +impl<'a, 'tcx> ty::layout::HasTyCtxt<'tcx> for &'a CodegenCx<'a, 'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> { - self.shared.tcx + self.tcx } } -impl<'a, 'tcx> LayoutOf<Ty<'tcx>> for &'a SharedCrateContext<'a, 'tcx> { +impl<'a, 'tcx> LayoutOf<Ty<'tcx>> for &'a CodegenCx<'a, 'tcx> { type TyLayout = TyLayout<'tcx>; fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout { @@ -688,57 +473,48 @@ impl<'a, 'tcx> LayoutOf<Ty<'tcx>> for &'a SharedCrateContext<'a, 'tcx> { } } -impl<'a, 'tcx> LayoutOf<Ty<'tcx>> for &'a CrateContext<'a, 'tcx> { - type TyLayout = TyLayout<'tcx>; - - - fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout { - self.shared.layout_of(ty) - } -} - /// Declare any llvm intrinsics that you might need -fn declare_intrinsic(ccx: &CrateContext, key: &str) -> Option<ValueRef> { +fn declare_intrinsic(cx: &CodegenCx, key: &str) -> Option<ValueRef> { macro_rules! ifn { ($name:expr, fn() -> $ret:expr) => ( if key == $name { - let f = declare::declare_cfn(ccx, $name, Type::func(&[], &$ret)); + let f = declare::declare_cfn(cx, $name, Type::func(&[], &$ret)); llvm::SetUnnamedAddr(f, false); - ccx.intrinsics().borrow_mut().insert($name, f.clone()); + cx.intrinsics.borrow_mut().insert($name, f.clone()); return Some(f); } ); ($name:expr, fn(...) -> $ret:expr) => ( if key == $name { - let f = declare::declare_cfn(ccx, $name, Type::variadic_func(&[], &$ret)); + let f = declare::declare_cfn(cx, $name, Type::variadic_func(&[], &$ret)); llvm::SetUnnamedAddr(f, false); - ccx.intrinsics().borrow_mut().insert($name, f.clone()); + cx.intrinsics.borrow_mut().insert($name, f.clone()); return Some(f); } ); ($name:expr, fn($($arg:expr),*) -> $ret:expr) => ( if key == $name { - let f = declare::declare_cfn(ccx, $name, Type::func(&[$($arg),*], &$ret)); + let f = declare::declare_cfn(cx, $name, Type::func(&[$($arg),*], &$ret)); llvm::SetUnnamedAddr(f, false); - ccx.intrinsics().borrow_mut().insert($name, f.clone()); + cx.intrinsics.borrow_mut().insert($name, f.clone()); return Some(f); } ); } macro_rules! mk_struct { - ($($field_ty:expr),*) => (Type::struct_(ccx, &[$($field_ty),*], false)) + ($($field_ty:expr),*) => (Type::struct_(cx, &[$($field_ty),*], false)) } - let i8p = Type::i8p(ccx); - let void = Type::void(ccx); - let i1 = Type::i1(ccx); - let t_i8 = Type::i8(ccx); - let t_i16 = Type::i16(ccx); - let t_i32 = Type::i32(ccx); - let t_i64 = Type::i64(ccx); - let t_i128 = Type::i128(ccx); - let t_f32 = Type::f32(ccx); - let t_f64 = Type::f64(ccx); + let i8p = Type::i8p(cx); + let void = Type::void(cx); + let i1 = Type::i1(cx); + let t_i8 = Type::i8(cx); + let t_i16 = Type::i16(cx); + let t_i32 = Type::i32(cx); + let t_i64 = Type::i64(cx); + let t_i128 = Type::i128(cx); + let t_f32 = Type::f32(cx); + let t_f64 = Type::f64(cx); ifn!("llvm.memcpy.p0i8.p0i8.i16", fn(i8p, i8p, t_i16, t_i32, i1) -> void); ifn!("llvm.memcpy.p0i8.p0i8.i32", fn(i8p, i8p, t_i32, t_i32, i1) -> void); @@ -870,9 +646,9 @@ fn declare_intrinsic(ccx: &CrateContext, key: &str) -> Option<ValueRef> { ifn!("llvm.assume", fn(i1) -> void); ifn!("llvm.prefetch", fn(i8p, t_i32, t_i32, t_i32) -> void); - if ccx.sess().opts.debuginfo != NoDebugInfo { - ifn!("llvm.dbg.declare", fn(Type::metadata(ccx), Type::metadata(ccx)) -> void); - ifn!("llvm.dbg.value", fn(Type::metadata(ccx), t_i64, Type::metadata(ccx)) -> void); + if cx.sess().opts.debuginfo != NoDebugInfo { + ifn!("llvm.dbg.declare", fn(Type::metadata(cx), Type::metadata(cx)) -> void); + ifn!("llvm.dbg.value", fn(Type::metadata(cx), t_i64, Type::metadata(cx)) -> void); } return None; } diff --git a/src/librustc_trans/debuginfo/create_scope_map.rs b/src/librustc_trans/debuginfo/create_scope_map.rs index 95f13ea8716..bddb3d90940 100644 --- a/src/librustc_trans/debuginfo/create_scope_map.rs +++ b/src/librustc_trans/debuginfo/create_scope_map.rs @@ -14,7 +14,7 @@ use super::utils::{DIB, span_start}; use llvm; use llvm::debuginfo::DIScope; -use common::CrateContext; +use common::CodegenCx; use rustc::mir::{Mir, VisibilityScope}; use libc::c_uint; @@ -44,7 +44,7 @@ impl MirDebugScope { /// Produce DIScope DIEs for each MIR Scope which has variables defined in it. /// If debuginfo is disabled, the returned vector is empty. -pub fn create_mir_scopes(ccx: &CrateContext, mir: &Mir, debug_context: &FunctionDebugContext) +pub fn create_mir_scopes(cx: &CodegenCx, mir: &Mir, debug_context: &FunctionDebugContext) -> IndexVec<VisibilityScope, MirDebugScope> { let null_scope = MirDebugScope { scope_metadata: ptr::null_mut(), @@ -71,13 +71,13 @@ pub fn create_mir_scopes(ccx: &CrateContext, mir: &Mir, debug_context: &Function // Instantiate all scopes. for idx in 0..mir.visibility_scopes.len() { let scope = VisibilityScope::new(idx); - make_mir_scope(ccx, &mir, &has_variables, debug_context, scope, &mut scopes); + make_mir_scope(cx, &mir, &has_variables, debug_context, scope, &mut scopes); } scopes } -fn make_mir_scope(ccx: &CrateContext, +fn make_mir_scope(cx: &CodegenCx, mir: &Mir, has_variables: &BitVector, debug_context: &FunctionDebugContextData, @@ -89,11 +89,11 @@ fn make_mir_scope(ccx: &CrateContext, let scope_data = &mir.visibility_scopes[scope]; let parent_scope = if let Some(parent) = scope_data.parent_scope { - make_mir_scope(ccx, mir, has_variables, debug_context, parent, scopes); + make_mir_scope(cx, mir, has_variables, debug_context, parent, scopes); scopes[parent] } else { // The root is the function itself. - let loc = span_start(ccx, mir.span); + let loc = span_start(cx, mir.span); scopes[scope] = MirDebugScope { scope_metadata: debug_context.fn_metadata, file_start_pos: loc.file.start_pos, @@ -115,14 +115,14 @@ fn make_mir_scope(ccx: &CrateContext, } } - let loc = span_start(ccx, scope_data.span); - let file_metadata = file_metadata(ccx, + let loc = span_start(cx, scope_data.span); + let file_metadata = file_metadata(cx, &loc.file.name, debug_context.defining_crate); let scope_metadata = unsafe { llvm::LLVMRustDIBuilderCreateLexicalBlock( - DIB(ccx), + DIB(cx), parent_scope.scope_metadata, file_metadata, loc.line as c_uint, diff --git a/src/librustc_trans/debuginfo/doc.rs b/src/librustc_trans/debuginfo/doc.rs index 93dca03e1ff..cbecc0eb7d1 100644 --- a/src/librustc_trans/debuginfo/doc.rs +++ b/src/librustc_trans/debuginfo/doc.rs @@ -32,7 +32,7 @@ //! The public API of the module is a set of functions that will insert the //! correct metadata into the LLVM IR when called with the right parameters. //! The module is thus driven from an outside client with functions like -//! `debuginfo::create_local_var_metadata(bcx: block, local: &ast::local)`. +//! `debuginfo::create_local_var_metadata(bx: block, local: &ast::local)`. //! //! Internally the module will try to reuse already created metadata by //! utilizing a cache. The way to get a shared metadata node when needed is @@ -44,8 +44,8 @@ //! that exact file path. //! //! All private state used by the module is stored within either the -//! CrateDebugContext struct (owned by the CrateContext) or the -//! FunctionDebugContext (owned by the MirContext). +//! CrateDebugContext struct (owned by the CodegenCx) or the +//! FunctionDebugContext (owned by the FunctionCx). //! //! This file consists of three conceptual sections: //! 1. The public interface of the module diff --git a/src/librustc_trans/debuginfo/gdb.rs b/src/librustc_trans/debuginfo/gdb.rs index 14d3fa49553..03e7c63dbca 100644 --- a/src/librustc_trans/debuginfo/gdb.rs +++ b/src/librustc_trans/debuginfo/gdb.rs @@ -12,7 +12,7 @@ use llvm; -use common::{C_bytes, CrateContext, C_i32}; +use common::{C_bytes, CodegenCx, C_i32}; use builder::Builder; use declare; use type_::Type; @@ -24,14 +24,14 @@ use syntax::attr; /// Inserts a side-effect free instruction sequence that makes sure that the /// .debug_gdb_scripts global is referenced, so it isn't removed by the linker. -pub fn insert_reference_to_gdb_debug_scripts_section_global(ccx: &CrateContext, builder: &Builder) { - if needs_gdb_debug_scripts_section(ccx) { - let gdb_debug_scripts_section_global = get_or_insert_gdb_debug_scripts_section_global(ccx); +pub fn insert_reference_to_gdb_debug_scripts_section_global(bx: &Builder) { + if needs_gdb_debug_scripts_section(bx.cx) { + let gdb_debug_scripts_section = get_or_insert_gdb_debug_scripts_section_global(bx.cx); // Load just the first byte as that's all that's necessary to force // LLVM to keep around the reference to the global. - let indices = [C_i32(ccx, 0), C_i32(ccx, 0)]; - let element = builder.inbounds_gep(gdb_debug_scripts_section_global, &indices); - let volative_load_instruction = builder.volatile_load(element); + let indices = [C_i32(bx.cx, 0), C_i32(bx.cx, 0)]; + let element = bx.inbounds_gep(gdb_debug_scripts_section, &indices); + let volative_load_instruction = bx.volatile_load(element); unsafe { llvm::LLVMSetAlignment(volative_load_instruction, 1); } @@ -40,13 +40,13 @@ pub fn insert_reference_to_gdb_debug_scripts_section_global(ccx: &CrateContext, /// Allocates the global variable responsible for the .debug_gdb_scripts binary /// section. -pub fn get_or_insert_gdb_debug_scripts_section_global(ccx: &CrateContext) +pub fn get_or_insert_gdb_debug_scripts_section_global(cx: &CodegenCx) -> llvm::ValueRef { let c_section_var_name = "__rustc_debug_gdb_scripts_section__\0"; let section_var_name = &c_section_var_name[..c_section_var_name.len()-1]; let section_var = unsafe { - llvm::LLVMGetNamedGlobal(ccx.llmod(), + llvm::LLVMGetNamedGlobal(cx.llmod, c_section_var_name.as_ptr() as *const _) }; @@ -55,15 +55,15 @@ pub fn get_or_insert_gdb_debug_scripts_section_global(ccx: &CrateContext) let section_contents = b"\x01gdb_load_rust_pretty_printers.py\0"; unsafe { - let llvm_type = Type::array(&Type::i8(ccx), + let llvm_type = Type::array(&Type::i8(cx), section_contents.len() as u64); - let section_var = declare::define_global(ccx, section_var_name, + let section_var = declare::define_global(cx, section_var_name, llvm_type).unwrap_or_else(||{ bug!("symbol `{}` is already defined", section_var_name) }); llvm::LLVMSetSection(section_var, section_name.as_ptr() as *const _); - llvm::LLVMSetInitializer(section_var, C_bytes(ccx, section_contents)); + llvm::LLVMSetInitializer(section_var, C_bytes(cx, section_contents)); llvm::LLVMSetGlobalConstant(section_var, llvm::True); llvm::LLVMSetUnnamedAddr(section_var, llvm::True); llvm::LLVMRustSetLinkage(section_var, llvm::Linkage::LinkOnceODRLinkage); @@ -77,13 +77,13 @@ pub fn get_or_insert_gdb_debug_scripts_section_global(ccx: &CrateContext) } } -pub fn needs_gdb_debug_scripts_section(ccx: &CrateContext) -> bool { +pub fn needs_gdb_debug_scripts_section(cx: &CodegenCx) -> bool { let omit_gdb_pretty_printer_section = - attr::contains_name(&ccx.tcx().hir.krate_attrs(), + attr::contains_name(&cx.tcx.hir.krate_attrs(), "omit_gdb_pretty_printer_section"); !omit_gdb_pretty_printer_section && - !ccx.sess().target.target.options.is_like_osx && - !ccx.sess().target.target.options.is_like_windows && - ccx.sess().opts.debuginfo != NoDebugInfo + !cx.sess().target.target.options.is_like_osx && + !cx.sess().target.target.options.is_like_windows && + cx.sess().opts.debuginfo != NoDebugInfo } diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index 6f3556516c4..62ba91840d9 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -18,7 +18,6 @@ use super::namespace::mangled_name_of_item; use super::type_names::compute_debuginfo_type_name; use super::{CrateDebugContext}; use abi; -use context::SharedCrateContext; use llvm::{self, ValueRef}; use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor, @@ -30,10 +29,10 @@ use rustc::ty::fold::TypeVisitor; use rustc::ty::util::TypeIdHasher; use rustc::ich::Fingerprint; use rustc::ty::Instance; -use common::CrateContext; -use rustc::ty::{self, AdtKind, Ty}; +use common::CodegenCx; +use rustc::ty::{self, AdtKind, Ty, TyCtxt}; use rustc::ty::layout::{self, Align, LayoutOf, Size, TyLayout}; -use rustc::session::{Session, config}; +use rustc::session::config; use rustc::util::nodemap::FxHashMap; use rustc::util::common::path2cstr; @@ -134,7 +133,7 @@ impl<'tcx> TypeMap<'tcx> { // Get the UniqueTypeId for the given type. If the UniqueTypeId for the given // type has been requested before, this is just a table lookup. Otherwise an // ID will be generated and stored for later lookup. - fn get_unique_type_id_of_type<'a>(&mut self, cx: &CrateContext<'a, 'tcx>, + fn get_unique_type_id_of_type<'a>(&mut self, cx: &CodegenCx<'a, 'tcx>, type_: Ty<'tcx>) -> UniqueTypeId { // Let's see if we already have something in the cache match self.type_to_unique_id.get(&type_).cloned() { @@ -144,7 +143,7 @@ impl<'tcx> TypeMap<'tcx> { // The hasher we are using to generate the UniqueTypeId. We want // something that provides more than the 64 bits of the DefaultHasher. - let mut type_id_hasher = TypeIdHasher::<Fingerprint>::new(cx.tcx()); + let mut type_id_hasher = TypeIdHasher::<Fingerprint>::new(cx.tcx); type_id_hasher.visit_ty(type_); let unique_type_id = type_id_hasher.finish().to_hex(); @@ -158,7 +157,7 @@ impl<'tcx> TypeMap<'tcx> { // types of their own, so they need special handling. We still need a // UniqueTypeId for them, since to debuginfo they *are* real types. fn get_unique_type_id_of_enum_variant<'a>(&mut self, - cx: &CrateContext<'a, 'tcx>, + cx: &CodegenCx<'a, 'tcx>, enum_type: Ty<'tcx>, variant_name: &str) -> UniqueTypeId { @@ -187,7 +186,7 @@ enum RecursiveTypeDescription<'tcx> { } fn create_and_register_recursive_type_forward_declaration<'a, 'tcx>( - cx: &CrateContext<'a, 'tcx>, + cx: &CodegenCx<'a, 'tcx>, unfinished_type: Ty<'tcx>, unique_type_id: UniqueTypeId, metadata_stub: DICompositeType, @@ -211,7 +210,7 @@ impl<'tcx> RecursiveTypeDescription<'tcx> { // Finishes up the description of the type in question (mostly by providing // descriptions of the fields of the given type) and returns the final type // metadata. - fn finalize<'a>(&self, cx: &CrateContext<'a, 'tcx>) -> MetadataCreationResult { + fn finalize<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> MetadataCreationResult { match *self { FinalMetadata(metadata) => MetadataCreationResult::new(metadata, false), UnfinishedMetadata { @@ -263,7 +262,7 @@ macro_rules! return_if_metadata_created_in_meantime { ) } -fn fixed_vec_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, +fn fixed_vec_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, unique_type_id: UniqueTypeId, array_or_slice_type: Ty<'tcx>, element_type: Ty<'tcx>, @@ -299,13 +298,13 @@ fn fixed_vec_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, return MetadataCreationResult::new(metadata, false); } -fn vec_slice_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, +fn vec_slice_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, slice_ptr_type: Ty<'tcx>, element_type: Ty<'tcx>, unique_type_id: UniqueTypeId, span: Span) -> MetadataCreationResult { - let data_ptr_type = cx.tcx().mk_imm_ptr(element_type); + let data_ptr_type = cx.tcx.mk_imm_ptr(element_type); let data_ptr_metadata = type_metadata(cx, data_ptr_type, span); @@ -314,7 +313,7 @@ fn vec_slice_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let slice_type_name = compute_debuginfo_type_name(cx, slice_ptr_type, true); let (pointer_size, pointer_align) = cx.size_and_align_of(data_ptr_type); - let (usize_size, usize_align) = cx.size_and_align_of(cx.tcx().types.usize); + let (usize_size, usize_align) = cx.size_and_align_of(cx.tcx.types.usize); let member_descriptions = [ MemberDescription { @@ -327,7 +326,7 @@ fn vec_slice_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, }, MemberDescription { name: "length".to_string(), - type_metadata: type_metadata(cx, cx.tcx().types.usize, span), + type_metadata: type_metadata(cx, cx.tcx.types.usize, span), offset: pointer_size, size: usize_size, align: usize_align, @@ -348,13 +347,13 @@ fn vec_slice_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, MetadataCreationResult::new(metadata, false) } -fn subroutine_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, +fn subroutine_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, unique_type_id: UniqueTypeId, signature: ty::PolyFnSig<'tcx>, span: Span) -> MetadataCreationResult { - let signature = cx.tcx().erase_late_bound_regions_and_normalize(&signature); + let signature = cx.tcx.erase_late_bound_regions_and_normalize(&signature); let mut signature_metadata: Vec<DIType> = Vec::with_capacity(signature.inputs().len() + 1); @@ -387,7 +386,7 @@ fn subroutine_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, // trait_type should be the actual trait (e.g., Trait). Where the trait is part // of a DST struct, there is no trait_object_type and the results of this // function will be a little bit weird. -fn trait_pointer_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, +fn trait_pointer_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, trait_type: Ty<'tcx>, trait_object_type: Option<Ty<'tcx>>, unique_type_id: UniqueTypeId) @@ -416,7 +415,7 @@ fn trait_pointer_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let file_metadata = unknown_file_metadata(cx); - let layout = cx.layout_of(cx.tcx().mk_mut_ptr(trait_type)); + let layout = cx.layout_of(cx.tcx.mk_mut_ptr(trait_type)); assert_eq!(abi::FAT_PTR_ADDR, 0); assert_eq!(abi::FAT_PTR_EXTRA, 1); @@ -427,7 +426,7 @@ fn trait_pointer_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, MemberDescription { name: "pointer".to_string(), type_metadata: type_metadata(cx, - cx.tcx().mk_mut_ptr(cx.tcx().types.u8), + cx.tcx.mk_mut_ptr(cx.tcx.types.u8), syntax_pos::DUMMY_SP), offset: layout.fields.offset(0), size: data_ptr_field.size, @@ -454,7 +453,7 @@ fn trait_pointer_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, syntax_pos::DUMMY_SP) } -pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, +pub fn type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, t: Ty<'tcx>, usage_site_span: Span) -> DIType { @@ -499,7 +498,7 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, Ok(vec_slice_metadata(cx, t, typ, unique_type_id, usage_site_span)) } ty::TyStr => { - Ok(vec_slice_metadata(cx, t, cx.tcx().types.u8, unique_type_id, usage_site_span)) + Ok(vec_slice_metadata(cx, t, cx.tcx.types.u8, unique_type_id, usage_site_span)) } ty::TyDynamic(..) => { Ok(MetadataCreationResult::new( @@ -539,7 +538,7 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, fixed_vec_metadata(cx, unique_type_id, t, typ, usage_site_span) } ty::TyStr => { - fixed_vec_metadata(cx, unique_type_id, t, cx.tcx().types.i8, usage_site_span) + fixed_vec_metadata(cx, unique_type_id, t, cx.tcx.types.i8, usage_site_span) } ty::TyDynamic(..) => { MetadataCreationResult::new( @@ -567,7 +566,7 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, ty::TyFnDef(..) | ty::TyFnPtr(_) => { let fn_metadata = subroutine_type_metadata(cx, unique_type_id, - t.fn_sig(cx.tcx()), + t.fn_sig(cx.tcx), usage_site_span).metadata; match debug_context(cx).type_map .borrow() @@ -581,7 +580,7 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } ty::TyClosure(def_id, substs) => { - let upvar_tys : Vec<_> = substs.upvar_tys(def_id, cx.tcx()).collect(); + let upvar_tys : Vec<_> = substs.upvar_tys(def_id, cx.tcx).collect(); prepare_tuple_metadata(cx, t, &upvar_tys, @@ -589,8 +588,8 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, usage_site_span).finalize(cx) } ty::TyGenerator(def_id, substs, _) => { - let upvar_tys : Vec<_> = substs.field_tys(def_id, cx.tcx()).map(|t| { - cx.tcx().fully_normalize_associated_types_in(&t) + let upvar_tys : Vec<_> = substs.field_tys(def_id, cx.tcx).map(|t| { + cx.tcx.fully_normalize_associated_types_in(&t) }).collect(); prepare_tuple_metadata(cx, t, @@ -674,7 +673,7 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, metadata } -pub fn file_metadata(cx: &CrateContext, +pub fn file_metadata(cx: &CodegenCx, file_name: &FileName, defining_crate: CrateNum) -> DIFile { debug!("file_metadata: file_name: {}, defining_crate: {}", @@ -692,11 +691,11 @@ pub fn file_metadata(cx: &CrateContext, file_metadata_raw(cx, &file_name.to_string(), &directory.to_string_lossy()) } -pub fn unknown_file_metadata(cx: &CrateContext) -> DIFile { +pub fn unknown_file_metadata(cx: &CodegenCx) -> DIFile { file_metadata_raw(cx, "<unknown>", "") } -fn file_metadata_raw(cx: &CrateContext, +fn file_metadata_raw(cx: &CodegenCx, file_name: &str, directory: &str) -> DIFile { @@ -722,7 +721,7 @@ fn file_metadata_raw(cx: &CrateContext, file_metadata } -fn basic_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, +fn basic_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, t: Ty<'tcx>) -> DIType { debug!("basic_type_metadata: {:?}", t); @@ -759,7 +758,7 @@ fn basic_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, return ty_metadata; } -fn foreign_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, +fn foreign_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, t: Ty<'tcx>, unique_type_id: UniqueTypeId) -> DIType { debug!("foreign_type_metadata: {:?}", t); @@ -768,7 +767,7 @@ fn foreign_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, create_struct_stub(cx, t, &name, unique_type_id, NO_SCOPE_METADATA) } -fn pointer_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, +fn pointer_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, pointer_type: Ty<'tcx>, pointee_type_metadata: DIType) -> DIType { @@ -785,21 +784,20 @@ fn pointer_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } } -pub fn compile_unit_metadata(scc: &SharedCrateContext, +pub fn compile_unit_metadata(tcx: TyCtxt, codegen_unit_name: &str, - debug_context: &CrateDebugContext, - sess: &Session) + debug_context: &CrateDebugContext) -> DIDescriptor { - let mut name_in_debuginfo = match sess.local_crate_source_file { + let mut name_in_debuginfo = match tcx.sess.local_crate_source_file { Some(ref path) => path.clone(), - None => PathBuf::from(&*scc.tcx().crate_name(LOCAL_CRATE).as_str()), + None => PathBuf::from(&*tcx.crate_name(LOCAL_CRATE).as_str()), }; // The OSX linker has an idiosyncrasy where it will ignore some debuginfo // if multiple object files with the same DW_AT_name are linked together. // As a workaround we generate unique names for each object file. Those do // not correspond to an actual source file but that should be harmless. - if scc.sess().target.target.options.is_like_osx { + if tcx.sess.target.target.options.is_like_osx { name_in_debuginfo.push("@"); name_in_debuginfo.push(codegen_unit_name); } @@ -811,7 +809,7 @@ pub fn compile_unit_metadata(scc: &SharedCrateContext, let name_in_debuginfo = name_in_debuginfo.to_string_lossy().into_owned(); let name_in_debuginfo = CString::new(name_in_debuginfo).unwrap(); - let work_dir = CString::new(&sess.working_dir.0.to_string_lossy()[..]).unwrap(); + let work_dir = CString::new(&tcx.sess.working_dir.0.to_string_lossy()[..]).unwrap(); let producer = CString::new(producer).unwrap(); let flags = "\0"; let split_name = "\0"; @@ -825,20 +823,20 @@ pub fn compile_unit_metadata(scc: &SharedCrateContext, DW_LANG_RUST, file_metadata, producer.as_ptr(), - sess.opts.optimize != config::OptLevel::No, + tcx.sess.opts.optimize != config::OptLevel::No, flags.as_ptr() as *const _, 0, split_name.as_ptr() as *const _); - if sess.opts.debugging_opts.profile { + if tcx.sess.opts.debugging_opts.profile { let cu_desc_metadata = llvm::LLVMRustMetadataAsValue(debug_context.llcontext, unit_metadata); let gcov_cu_info = [ path_to_mdstring(debug_context.llcontext, - &scc.tcx().output_filenames(LOCAL_CRATE).with_extension("gcno")), + &tcx.output_filenames(LOCAL_CRATE).with_extension("gcno")), path_to_mdstring(debug_context.llcontext, - &scc.tcx().output_filenames(LOCAL_CRATE).with_extension("gcda")), + &tcx.output_filenames(LOCAL_CRATE).with_extension("gcda")), cu_desc_metadata, ]; let gcov_metadata = llvm::LLVMMDNodeInContext(debug_context.llcontext, @@ -903,7 +901,7 @@ enum MemberDescriptionFactory<'tcx> { } impl<'tcx> MemberDescriptionFactory<'tcx> { - fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>) + fn create_member_descriptions<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> Vec<MemberDescription> { match *self { StructMDF(ref this) => { @@ -937,7 +935,7 @@ struct StructMemberDescriptionFactory<'tcx> { } impl<'tcx> StructMemberDescriptionFactory<'tcx> { - fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>) + fn create_member_descriptions<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> Vec<MemberDescription> { let layout = cx.layout_of(self.ty); self.variant.fields.iter().enumerate().map(|(i, f)| { @@ -961,7 +959,7 @@ impl<'tcx> StructMemberDescriptionFactory<'tcx> { } -fn prepare_struct_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, +fn prepare_struct_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, struct_type: Ty<'tcx>, unique_type_id: UniqueTypeId, span: Span) @@ -1006,7 +1004,7 @@ struct TupleMemberDescriptionFactory<'tcx> { } impl<'tcx> TupleMemberDescriptionFactory<'tcx> { - fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>) + fn create_member_descriptions<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> Vec<MemberDescription> { let layout = cx.layout_of(self.ty); self.component_types.iter().enumerate().map(|(i, &component_type)| { @@ -1023,7 +1021,7 @@ impl<'tcx> TupleMemberDescriptionFactory<'tcx> { } } -fn prepare_tuple_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, +fn prepare_tuple_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, tuple_type: Ty<'tcx>, component_types: &[Ty<'tcx>], unique_type_id: UniqueTypeId, @@ -1059,7 +1057,7 @@ struct UnionMemberDescriptionFactory<'tcx> { } impl<'tcx> UnionMemberDescriptionFactory<'tcx> { - fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>) + fn create_member_descriptions<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> Vec<MemberDescription> { self.variant.fields.iter().enumerate().map(|(i, f)| { let field = self.layout.field(cx, i); @@ -1076,7 +1074,7 @@ impl<'tcx> UnionMemberDescriptionFactory<'tcx> { } } -fn prepare_union_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, +fn prepare_union_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, union_type: Ty<'tcx>, unique_type_id: UniqueTypeId, span: Span) @@ -1127,7 +1125,7 @@ struct EnumMemberDescriptionFactory<'tcx> { } impl<'tcx> EnumMemberDescriptionFactory<'tcx> { - fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>) + fn create_member_descriptions<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> Vec<MemberDescription> { let adt = &self.enum_type.ty_adt_def().unwrap(); match self.layout.variants { @@ -1212,7 +1210,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> { // of discriminant instead of us having to recover its path. // Right now it's not even going to work for `niche_start > 0`, // and for multiple niche variants it only supports the first. - fn compute_field_path<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, + fn compute_field_path<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, name: &mut String, layout: TyLayout<'tcx>, offset: Size, @@ -1223,10 +1221,10 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> { continue; } let inner_offset = offset - field_offset; - let field = layout.field(ccx, i); + let field = layout.field(cx, i); if inner_offset + size <= field.size { write!(name, "{}$", i).unwrap(); - compute_field_path(ccx, name, field, inner_offset, size); + compute_field_path(cx, name, field, inner_offset, size); } } } @@ -1262,7 +1260,7 @@ struct VariantMemberDescriptionFactory<'tcx> { } impl<'tcx> VariantMemberDescriptionFactory<'tcx> { - fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>) + fn create_member_descriptions<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> Vec<MemberDescription> { self.args.iter().enumerate().map(|(i, &(ref name, ty))| { let (size, align) = cx.size_and_align_of(ty); @@ -1292,7 +1290,7 @@ enum EnumDiscriminantInfo { // of the variant, and (3) a MemberDescriptionFactory for producing the // descriptions of the fields of the variant. This is a rudimentary version of a // full RecursiveTypeDescription. -fn describe_enum_variant<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, +fn describe_enum_variant<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, layout: layout::TyLayout<'tcx>, variant: &'tcx ty::VariantDef, discriminant_info: EnumDiscriminantInfo, @@ -1352,7 +1350,7 @@ fn describe_enum_variant<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, (metadata_stub, member_description_factory) } -fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, +fn prepare_enum_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, enum_type: Ty<'tcx>, enum_def_id: DefId, unique_type_id: UniqueTypeId, @@ -1370,7 +1368,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let file_metadata = unknown_file_metadata(cx); let def = enum_type.ty_adt_def().unwrap(); - let enumerators_metadata: Vec<DIDescriptor> = def.discriminants(cx.tcx()) + let enumerators_metadata: Vec<DIDescriptor> = def.discriminants(cx.tcx) .zip(&def.variants) .map(|(discr, v)| { let token = v.name.as_str(); @@ -1396,7 +1394,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let (discriminant_size, discriminant_align) = (discr.size(cx), discr.align(cx)); let discriminant_base_type_metadata = - type_metadata(cx, discr.to_ty(cx.tcx()), syntax_pos::DUMMY_SP); + type_metadata(cx, discr.to_ty(cx.tcx), syntax_pos::DUMMY_SP); let discriminant_name = get_enum_discriminant_name(cx, enum_def_id); let name = CString::new(discriminant_name.as_bytes()).unwrap(); @@ -1472,10 +1470,10 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, }), ); - fn get_enum_discriminant_name(cx: &CrateContext, + fn get_enum_discriminant_name(cx: &CodegenCx, def_id: DefId) -> InternedString { - cx.tcx().item_name(def_id) + cx.tcx.item_name(def_id) } } @@ -1483,7 +1481,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, /// results in a LLVM struct. /// /// Examples of Rust types to use this are: structs, tuples, boxes, vecs, and enums. -fn composite_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, +fn composite_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, composite_type: Ty<'tcx>, composite_type_name: &str, composite_type_unique_id: UniqueTypeId, @@ -1509,7 +1507,7 @@ fn composite_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, return composite_type_metadata; } -fn set_members_of_composite_type(cx: &CrateContext, +fn set_members_of_composite_type(cx: &CodegenCx, composite_type_metadata: DICompositeType, member_descriptions: &[MemberDescription]) { // In some rare cases LLVM metadata uniquing would lead to an existing type @@ -1560,7 +1558,7 @@ fn set_members_of_composite_type(cx: &CrateContext, // A convenience wrapper around LLVMRustDIBuilderCreateStructType(). Does not do // any caching, does not add any fields to the struct. This can be done later // with set_members_of_composite_type(). -fn create_struct_stub<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, +fn create_struct_stub<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, struct_type: Ty<'tcx>, struct_type_name: &str, unique_type_id: UniqueTypeId, @@ -1597,7 +1595,7 @@ fn create_struct_stub<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, return metadata_stub; } -fn create_union_stub<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, +fn create_union_stub<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, union_type: Ty<'tcx>, union_type_name: &str, unique_type_id: UniqueTypeId, @@ -1635,20 +1633,20 @@ fn create_union_stub<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, /// Creates debug information for the given global variable. /// /// Adds the created metadata nodes directly to the crate's IR. -pub fn create_global_var_metadata(cx: &CrateContext, +pub fn create_global_var_metadata(cx: &CodegenCx, node_id: ast::NodeId, global: ValueRef) { - if cx.dbg_cx().is_none() { + if cx.dbg_cx.is_none() { return; } - let tcx = cx.tcx(); + let tcx = cx.tcx; let node_def_id = tcx.hir.local_def_id(node_id); let no_mangle = attr::contains_name(&tcx.get_attrs(node_def_id), "no_mangle"); // We may want to remove the namespace scope if we're in an extern block, see: // https://github.com/rust-lang/rust/pull/46457#issuecomment-351750952 let var_scope = get_namespace_for_item(cx, node_def_id); - let span = cx.tcx().def_span(node_def_id); + let span = cx.tcx.def_span(node_def_id); let (file_metadata, line_number) = if span != syntax_pos::DUMMY_SP { let loc = span_start(cx, span); @@ -1658,7 +1656,7 @@ pub fn create_global_var_metadata(cx: &CrateContext, }; let is_local_to_unit = is_node_local_to_unit(cx, node_id); - let variable_type = Instance::mono(cx.tcx(), node_def_id).ty(cx.tcx()); + let variable_type = Instance::mono(cx.tcx, node_def_id).ty(cx.tcx); let type_metadata = type_metadata(cx, variable_type, span); let var_name = tcx.item_name(node_def_id).to_string(); let var_name = CString::new(var_name).unwrap(); @@ -1691,15 +1689,15 @@ pub fn create_global_var_metadata(cx: &CrateContext, } // Creates an "extension" of an existing DIScope into another file. -pub fn extend_scope_to_file(ccx: &CrateContext, +pub fn extend_scope_to_file(cx: &CodegenCx, scope_metadata: DIScope, file: &syntax_pos::FileMap, defining_crate: CrateNum) -> DILexicalBlock { - let file_metadata = file_metadata(ccx, &file.name, defining_crate); + let file_metadata = file_metadata(cx, &file.name, defining_crate); unsafe { llvm::LLVMRustDIBuilderCreateLexicalBlockFile( - DIB(ccx), + DIB(cx), scope_metadata, file_metadata) } @@ -1709,10 +1707,10 @@ pub fn extend_scope_to_file(ccx: &CrateContext, /// given type. /// /// Adds the created metadata nodes directly to the crate's IR. -pub fn create_vtable_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, +pub fn create_vtable_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ty: ty::Ty<'tcx>, vtable: ValueRef) { - if cx.dbg_cx().is_none() { + if cx.dbg_cx.is_none() { return; } @@ -1736,7 +1734,7 @@ pub fn create_vtable_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER, Size::from_bytes(0).bits(), - cx.tcx().data_layout.pointer_align.abi_bits() as u32, + cx.tcx.data_layout.pointer_align.abi_bits() as u32, DIFlags::FlagArtificial, ptr::null_mut(), empty_array, diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index 3f9ace151a3..b46e12d9d5b 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -27,7 +27,7 @@ use rustc::hir::def_id::{DefId, CrateNum}; use rustc::ty::subst::Substs; use abi::Abi; -use common::CrateContext; +use common::CodegenCx; use builder::Builder; use monomorphize::Instance; use rustc::ty::{self, Ty}; @@ -150,8 +150,8 @@ pub enum VariableKind { } /// Create any deferred debug metadata nodes -pub fn finalize(cx: &CrateContext) { - if cx.dbg_cx().is_none() { +pub fn finalize(cx: &CodegenCx) { + if cx.dbg_cx.is_none() { return; } @@ -176,21 +176,21 @@ pub fn finalize(cx: &CrateContext) { // Android has the same issue (#22398) if cx.sess().target.target.options.is_like_osx || cx.sess().target.target.options.is_like_android { - llvm::LLVMRustAddModuleFlag(cx.llmod(), + llvm::LLVMRustAddModuleFlag(cx.llmod, "Dwarf Version\0".as_ptr() as *const _, 2) } // Indicate that we want CodeView debug information on MSVC if cx.sess().target.target.options.is_like_msvc { - llvm::LLVMRustAddModuleFlag(cx.llmod(), + llvm::LLVMRustAddModuleFlag(cx.llmod, "CodeView\0".as_ptr() as *const _, 1) } // Prevent bitcode readers from deleting the debug info. let ptr = "Debug Info Version\0".as_ptr(); - llvm::LLVMRustAddModuleFlag(cx.llmod(), ptr as *const _, + llvm::LLVMRustAddModuleFlag(cx.llmod, ptr as *const _, llvm::LLVMRustDebugMetadataVersion()); }; } @@ -201,7 +201,7 @@ pub fn finalize(cx: &CrateContext) { /// for debug info creation. The function may also return another variant of the /// FunctionDebugContext enum which indicates why no debuginfo should be created /// for the function. -pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, +pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, instance: Instance<'tcx>, sig: ty::FnSig<'tcx>, llfn: ValueRef, @@ -210,7 +210,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, return FunctionDebugContext::DebugInfoDisabled; } - for attr in instance.def.attrs(cx.tcx()).iter() { + for attr in instance.def.attrs(cx.tcx).iter() { if attr.check_name("no_debug") { return FunctionDebugContext::FunctionWithoutDebugInfo; } @@ -235,15 +235,15 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, }; // Find the enclosing function, in case this is a closure. - let def_key = cx.tcx().def_key(def_id); + let def_key = cx.tcx.def_key(def_id); let mut name = def_key.disambiguated_data.data.to_string(); - let enclosing_fn_def_id = cx.tcx().closure_base_def_id(def_id); + let enclosing_fn_def_id = cx.tcx.closure_base_def_id(def_id); // Get_template_parameters() will append a `<...>` clause to the function // name if necessary. - let generics = cx.tcx().generics_of(enclosing_fn_def_id); - let substs = instance.substs.truncate_to(cx.tcx(), generics); + let generics = cx.tcx.generics_of(enclosing_fn_def_id); + let substs = instance.substs.truncate_to(cx.tcx, generics); let template_parameters = get_template_parameters(cx, &generics, substs, @@ -255,7 +255,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let scope_line = span_start(cx, span).line; - let local_id = cx.tcx().hir.as_local_node_id(instance.def_id()); + let local_id = cx.tcx.hir.as_local_node_id(instance.def_id()); let is_local_to_unit = local_id.map_or(false, |id| is_node_local_to_unit(cx, id)); let function_name = CString::new(name).unwrap(); @@ -299,7 +299,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, return FunctionDebugContext::RegularContext(fn_debug_context); - fn get_function_signature<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, + fn get_function_signature<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, sig: ty::FnSig<'tcx>) -> DIArray { if cx.sess().opts.debuginfo == LimitedDebugInfo { return create_DIArray(DIB(cx), &[]); @@ -334,8 +334,8 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, signature.extend(inputs.iter().map(|&t| { let t = match t.sty { ty::TyArray(ct, _) - if (ct == cx.tcx().types.u8) || cx.layout_of(ct).is_zst() => { - cx.tcx().mk_imm_ptr(ct) + if (ct == cx.tcx.types.u8) || cx.layout_of(ct).is_zst() => { + cx.tcx.mk_imm_ptr(ct) } _ => t }; @@ -358,7 +358,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, return create_DIArray(DIB(cx), &signature[..]); } - fn get_template_parameters<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, + fn get_template_parameters<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, generics: &ty::Generics, substs: &Substs<'tcx>, file_metadata: DIFile, @@ -375,7 +375,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, name_to_append_suffix_to.push_str(","); } - let actual_type = cx.tcx().fully_normalize_associated_types_in(&actual_type); + let actual_type = cx.tcx.fully_normalize_associated_types_in(&actual_type); // Add actual type name to <...> clause of function name let actual_type_name = compute_debuginfo_type_name(cx, actual_type, @@ -388,7 +388,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let template_params: Vec<_> = if cx.sess().opts.debuginfo == FullDebugInfo { let names = get_type_parameter_names(cx, generics); substs.types().zip(names).map(|(ty, name)| { - let actual_type = cx.tcx().fully_normalize_associated_types_in(&ty); + let actual_type = cx.tcx.fully_normalize_associated_types_in(&ty); let actual_type_metadata = type_metadata(cx, actual_type, syntax_pos::DUMMY_SP); let name = CString::new(name.as_str().as_bytes()).unwrap(); unsafe { @@ -409,24 +409,24 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, return create_DIArray(DIB(cx), &template_params[..]); } - fn get_type_parameter_names(cx: &CrateContext, generics: &ty::Generics) -> Vec<ast::Name> { + fn get_type_parameter_names(cx: &CodegenCx, generics: &ty::Generics) -> Vec<ast::Name> { let mut names = generics.parent.map_or(vec![], |def_id| { - get_type_parameter_names(cx, cx.tcx().generics_of(def_id)) + get_type_parameter_names(cx, cx.tcx.generics_of(def_id)) }); names.extend(generics.types.iter().map(|param| param.name)); names } - fn get_containing_scope<'ccx, 'tcx>(cx: &CrateContext<'ccx, 'tcx>, + fn get_containing_scope<'cx, 'tcx>(cx: &CodegenCx<'cx, 'tcx>, instance: Instance<'tcx>) -> DIScope { // First, let's see if this is a method within an inherent impl. Because // if yes, we want to make the result subroutine DIE a child of the // subroutine's self-type. - let self_type = cx.tcx().impl_of_method(instance.def_id()).and_then(|impl_def_id| { + let self_type = cx.tcx.impl_of_method(instance.def_id()).and_then(|impl_def_id| { // If the method does *not* belong to a trait, proceed - if cx.tcx().trait_id_of_impl(impl_def_id).is_none() { - let impl_self_ty = cx.tcx().trans_impl_self_ty(impl_def_id, instance.substs); + if cx.tcx.trait_id_of_impl(impl_def_id).is_none() { + let impl_self_ty = cx.tcx.trans_impl_self_ty(impl_def_id, instance.substs); // Only "class" methods are generally understood by LLVM, // so avoid methods on other types (e.g. `<*mut T>::null`). @@ -446,7 +446,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, self_type.unwrap_or_else(|| { namespace::item_namespace(cx, DefId { krate: instance.def_id().krate, - index: cx.tcx() + index: cx.tcx .def_key(instance.def_id()) .parent .expect("get_containing_scope: missing parent?") @@ -455,7 +455,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } } -pub fn declare_local<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, +pub fn declare_local<'a, 'tcx>(bx: &Builder<'a, 'tcx>, dbg_context: &FunctionDebugContext, variable_name: ast::Name, variable_type: Ty<'tcx>, @@ -463,7 +463,7 @@ pub fn declare_local<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, variable_access: VariableAccess, variable_kind: VariableKind, span: Span) { - let cx = bcx.ccx; + let cx = bx.cx; let file = span_start(cx, span).file; let file_metadata = file_metadata(cx, @@ -499,10 +499,10 @@ pub fn declare_local<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, align.abi() as u32, ) }; - source_loc::set_debug_location(bcx, + source_loc::set_debug_location(bx, InternalDebugLocation::new(scope_metadata, loc.line, loc.col.to_usize())); unsafe { - let debug_loc = llvm::LLVMGetCurrentDebugLocation(bcx.llbuilder); + let debug_loc = llvm::LLVMGetCurrentDebugLocation(bx.llbuilder); let instr = llvm::LLVMRustDIBuilderInsertDeclareAtEnd( DIB(cx), alloca, @@ -510,9 +510,9 @@ pub fn declare_local<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, address_operations.as_ptr(), address_operations.len() as c_uint, debug_loc, - bcx.llbb()); + bx.llbb()); - llvm::LLVMSetInstDebugLocation(bcx.llbuilder, instr); + llvm::LLVMSetInstDebugLocation(bx.llbuilder, instr); } } } @@ -520,7 +520,7 @@ pub fn declare_local<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, match variable_kind { ArgumentVariable(_) | CapturedVariable => { assert!(!dbg_context.get_ref(span).source_locations_enabled.get()); - source_loc::set_debug_location(bcx, UnknownLocation); + source_loc::set_debug_location(bx, UnknownLocation); } _ => { /* nothing to do */ } } diff --git a/src/librustc_trans/debuginfo/namespace.rs b/src/librustc_trans/debuginfo/namespace.rs index 47e2b8c461c..46067a43303 100644 --- a/src/librustc_trans/debuginfo/namespace.rs +++ b/src/librustc_trans/debuginfo/namespace.rs @@ -20,44 +20,44 @@ use llvm; use llvm::debuginfo::DIScope; use rustc::hir::def_id::DefId; use rustc::hir::map::DefPathData; -use common::CrateContext; +use common::CodegenCx; use std::ffi::CString; use std::ptr; pub fn mangled_name_of_instance<'a, 'tcx>( - ccx: &CrateContext<'a, 'tcx>, + cx: &CodegenCx<'a, 'tcx>, instance: Instance<'tcx>, ) -> ty::SymbolName { - let tcx = ccx.tcx(); + let tcx = cx.tcx; tcx.symbol_name(instance) } pub fn mangled_name_of_item<'a, 'tcx>( - ccx: &CrateContext<'a, 'tcx>, + cx: &CodegenCx<'a, 'tcx>, node_id: ast::NodeId, ) -> ty::SymbolName { - let tcx = ccx.tcx(); + let tcx = cx.tcx; let node_def_id = tcx.hir.local_def_id(node_id); let instance = Instance::mono(tcx, node_def_id); tcx.symbol_name(instance) } -pub fn item_namespace(ccx: &CrateContext, def_id: DefId) -> DIScope { - if let Some(&scope) = debug_context(ccx).namespace_map.borrow().get(&def_id) { +pub fn item_namespace(cx: &CodegenCx, def_id: DefId) -> DIScope { + if let Some(&scope) = debug_context(cx).namespace_map.borrow().get(&def_id) { return scope; } - let def_key = ccx.tcx().def_key(def_id); + let def_key = cx.tcx.def_key(def_id); let parent_scope = def_key.parent.map_or(ptr::null_mut(), |parent| { - item_namespace(ccx, DefId { + item_namespace(cx, DefId { krate: def_id.krate, index: parent }) }); let namespace_name = match def_key.disambiguated_data.data { - DefPathData::CrateRoot => ccx.tcx().crate_name(def_id.krate).as_str(), + DefPathData::CrateRoot => cx.tcx.crate_name(def_id.krate).as_str(), data => data.as_interned_str() }; @@ -65,13 +65,13 @@ pub fn item_namespace(ccx: &CrateContext, def_id: DefId) -> DIScope { let scope = unsafe { llvm::LLVMRustDIBuilderCreateNameSpace( - DIB(ccx), + DIB(cx), parent_scope, namespace_name.as_ptr(), - unknown_file_metadata(ccx), + unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER) }; - debug_context(ccx).namespace_map.borrow_mut().insert(def_id, scope); + debug_context(cx).namespace_map.borrow_mut().insert(def_id, scope); scope } diff --git a/src/librustc_trans/debuginfo/source_loc.rs b/src/librustc_trans/debuginfo/source_loc.rs index 7393802294a..7440296ce5d 100644 --- a/src/librustc_trans/debuginfo/source_loc.rs +++ b/src/librustc_trans/debuginfo/source_loc.rs @@ -26,25 +26,25 @@ use syntax_pos::{Span, Pos}; /// /// Maps to a call to llvm::LLVMSetCurrentDebugLocation(...). pub fn set_source_location( - debug_context: &FunctionDebugContext, builder: &Builder, scope: DIScope, span: Span + debug_context: &FunctionDebugContext, bx: &Builder, scope: DIScope, span: Span ) { let function_debug_context = match *debug_context { FunctionDebugContext::DebugInfoDisabled => return, FunctionDebugContext::FunctionWithoutDebugInfo => { - set_debug_location(builder, UnknownLocation); + set_debug_location(bx, UnknownLocation); return; } FunctionDebugContext::RegularContext(ref data) => data }; let dbg_loc = if function_debug_context.source_locations_enabled.get() { - debug!("set_source_location: {}", builder.sess().codemap().span_to_string(span)); - let loc = span_start(builder.ccx, span); + debug!("set_source_location: {}", bx.sess().codemap().span_to_string(span)); + let loc = span_start(bx.cx, span); InternalDebugLocation::new(scope, loc.line, loc.col.to_usize()) } else { UnknownLocation }; - set_debug_location(builder, dbg_loc); + set_debug_location(bx, dbg_loc); } /// Enables emitting source locations for the given functions. @@ -79,7 +79,7 @@ impl InternalDebugLocation { } } -pub fn set_debug_location(builder: &Builder, debug_location: InternalDebugLocation) { +pub fn set_debug_location(bx: &Builder, debug_location: InternalDebugLocation) { let metadata_node = match debug_location { KnownLocation { scope, line, .. } => { // Always set the column to zero like Clang and GCC @@ -88,7 +88,7 @@ pub fn set_debug_location(builder: &Builder, debug_location: InternalDebugLocati unsafe { llvm::LLVMRustDIBuilderCreateDebugLocation( - debug_context(builder.ccx).llcontext, + debug_context(bx.cx).llcontext, line as c_uint, col as c_uint, scope, @@ -102,6 +102,6 @@ pub fn set_debug_location(builder: &Builder, debug_location: InternalDebugLocati }; unsafe { - llvm::LLVMSetCurrentDebugLocation(builder.llbuilder, metadata_node); + llvm::LLVMSetCurrentDebugLocation(bx.llbuilder, metadata_node); } } diff --git a/src/librustc_trans/debuginfo/type_names.rs b/src/librustc_trans/debuginfo/type_names.rs index 85467f5bfbd..0aec92b0d66 100644 --- a/src/librustc_trans/debuginfo/type_names.rs +++ b/src/librustc_trans/debuginfo/type_names.rs @@ -10,7 +10,7 @@ // Type Names for Debug Info. -use common::CrateContext; +use common::CodegenCx; use rustc::hir::def_id::DefId; use rustc::ty::subst::Substs; use rustc::ty::{self, Ty}; @@ -21,7 +21,7 @@ use rustc::hir; // any caching, i.e. calling the function twice with the same type will also do // the work twice. The `qualified` parameter only affects the first level of the // type name, further levels (i.e. type parameters) are always fully qualified. -pub fn compute_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, +pub fn compute_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, t: Ty<'tcx>, qualified: bool) -> String { @@ -32,7 +32,7 @@ pub fn compute_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, // Pushes the name of the type as it should be stored in debuginfo on the // `output` String. See also compute_debuginfo_type_name(). -pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, +pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, t: Ty<'tcx>, qualified: bool, output: &mut String) { @@ -117,14 +117,14 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, }, ty::TyDynamic(ref trait_data, ..) => { if let Some(principal) = trait_data.principal() { - let principal = cx.tcx().erase_late_bound_regions_and_normalize( + let principal = cx.tcx.erase_late_bound_regions_and_normalize( &principal); push_item_name(cx, principal.def_id, false, output); push_type_params(cx, principal.substs, output); } }, ty::TyFnDef(..) | ty::TyFnPtr(_) => { - let sig = t.fn_sig(cx.tcx()); + let sig = t.fn_sig(cx.tcx); if sig.unsafety() == hir::Unsafety::Unsafe { output.push_str("unsafe "); } @@ -138,7 +138,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, output.push_str("fn("); - let sig = cx.tcx().erase_late_bound_regions_and_normalize(&sig); + let sig = cx.tcx.erase_late_bound_regions_and_normalize(&sig); if !sig.inputs().is_empty() { for ¶meter_type in sig.inputs() { push_debuginfo_type_name(cx, parameter_type, true, output); @@ -179,18 +179,18 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } } - fn push_item_name(cx: &CrateContext, + fn push_item_name(cx: &CodegenCx, def_id: DefId, qualified: bool, output: &mut String) { if qualified { - output.push_str(&cx.tcx().crate_name(def_id.krate).as_str()); - for path_element in cx.tcx().def_path(def_id).data { + output.push_str(&cx.tcx.crate_name(def_id.krate).as_str()); + for path_element in cx.tcx.def_path(def_id).data { output.push_str("::"); output.push_str(&path_element.data.as_interned_str()); } } else { - output.push_str(&cx.tcx().item_name(def_id)); + output.push_str(&cx.tcx.item_name(def_id)); } } @@ -199,7 +199,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, // reconstructed for items from non-local crates. For local crates, this // would be possible but with inlining and LTO we have to use the least // common denominator - otherwise we would run into conflicts. - fn push_type_params<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, + fn push_type_params<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, substs: &Substs<'tcx>, output: &mut String) { if substs.types().next().is_none() { diff --git a/src/librustc_trans/debuginfo/utils.rs b/src/librustc_trans/debuginfo/utils.rs index 95427d9b3cd..c571b84b8e9 100644 --- a/src/librustc_trans/debuginfo/utils.rs +++ b/src/librustc_trans/debuginfo/utils.rs @@ -18,12 +18,12 @@ use rustc::ty::DefIdTree; use llvm; use llvm::debuginfo::{DIScope, DIBuilderRef, DIDescriptor, DIArray}; -use common::{CrateContext}; +use common::{CodegenCx}; use syntax_pos::{self, Span}; use syntax::ast; -pub fn is_node_local_to_unit(cx: &CrateContext, node_id: ast::NodeId) -> bool +pub fn is_node_local_to_unit(cx: &CodegenCx, node_id: ast::NodeId) -> bool { // The is_local_to_unit flag indicates whether a function is local to the // current compilation unit (i.e. if it is *static* in the C-sense). The @@ -33,8 +33,8 @@ pub fn is_node_local_to_unit(cx: &CrateContext, node_id: ast::NodeId) -> bool // visible). It might better to use the `exported_items` set from // `driver::CrateAnalysis` in the future, but (atm) this set is not // available in the translation pass. - let def_id = cx.tcx().hir.local_def_id(node_id); - !cx.tcx().is_exported_symbol(def_id) + let def_id = cx.tcx.hir.local_def_id(node_id); + !cx.tcx.is_exported_symbol(def_id) } #[allow(non_snake_case)] @@ -45,23 +45,23 @@ pub fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray { } /// Return syntax_pos::Loc corresponding to the beginning of the span -pub fn span_start(cx: &CrateContext, span: Span) -> syntax_pos::Loc { +pub fn span_start(cx: &CodegenCx, span: Span) -> syntax_pos::Loc { cx.sess().codemap().lookup_char_pos(span.lo()) } #[inline] -pub fn debug_context<'a, 'tcx>(cx: &'a CrateContext<'a, 'tcx>) +pub fn debug_context<'a, 'tcx>(cx: &'a CodegenCx<'a, 'tcx>) -> &'a CrateDebugContext<'tcx> { - cx.dbg_cx().as_ref().unwrap() + cx.dbg_cx.as_ref().unwrap() } #[inline] #[allow(non_snake_case)] -pub fn DIB(cx: &CrateContext) -> DIBuilderRef { - cx.dbg_cx().as_ref().unwrap().builder +pub fn DIB(cx: &CodegenCx) -> DIBuilderRef { + cx.dbg_cx.as_ref().unwrap().builder } -pub fn get_namespace_for_item(cx: &CrateContext, def_id: DefId) -> DIScope { - item_namespace(cx, cx.tcx().parent(def_id) +pub fn get_namespace_for_item(cx: &CodegenCx, def_id: DefId) -> DIScope { + item_namespace(cx, cx.tcx.parent(def_id) .expect("get_namespace_for_item: missing parent?")) } diff --git a/src/librustc_trans/declare.rs b/src/librustc_trans/declare.rs index f894bdf16e4..aa1cd0c27e7 100644 --- a/src/librustc_trans/declare.rs +++ b/src/librustc_trans/declare.rs @@ -27,7 +27,7 @@ use rustc::session::config::Sanitizer; use rustc_back::PanicStrategy; use abi::{Abi, FnType}; use attributes; -use context::CrateContext; +use context::CodegenCx; use common; use type_::Type; use value::Value; @@ -39,13 +39,13 @@ use std::ffi::CString; /// /// If there’s a value with the same name already declared, the function will /// return its ValueRef instead. -pub fn declare_global(ccx: &CrateContext, name: &str, ty: Type) -> llvm::ValueRef { +pub fn declare_global(cx: &CodegenCx, name: &str, ty: Type) -> llvm::ValueRef { debug!("declare_global(name={:?})", name); let namebuf = CString::new(name).unwrap_or_else(|_|{ bug!("name {:?} contains an interior null byte", name) }); unsafe { - llvm::LLVMRustGetOrInsertGlobal(ccx.llmod(), namebuf.as_ptr(), ty.to_ref()) + llvm::LLVMRustGetOrInsertGlobal(cx.llmod, namebuf.as_ptr(), ty.to_ref()) } } @@ -54,13 +54,13 @@ pub fn declare_global(ccx: &CrateContext, name: &str, ty: Type) -> llvm::ValueRe /// /// If there’s a value with the same name already declared, the function will /// update the declaration and return existing ValueRef instead. -fn declare_raw_fn(ccx: &CrateContext, name: &str, callconv: llvm::CallConv, ty: Type) -> ValueRef { +fn declare_raw_fn(cx: &CodegenCx, name: &str, callconv: llvm::CallConv, ty: Type) -> ValueRef { debug!("declare_raw_fn(name={:?}, ty={:?})", name, ty); let namebuf = CString::new(name).unwrap_or_else(|_|{ bug!("name {:?} contains an interior null byte", name) }); let llfn = unsafe { - llvm::LLVMRustGetOrInsertFunction(ccx.llmod(), namebuf.as_ptr(), ty.to_ref()) + llvm::LLVMRustGetOrInsertFunction(cx.llmod, namebuf.as_ptr(), ty.to_ref()) }; llvm::SetFunctionCallConv(llfn, callconv); @@ -68,12 +68,12 @@ fn declare_raw_fn(ccx: &CrateContext, name: &str, callconv: llvm::CallConv, ty: // be merged. llvm::SetUnnamedAddr(llfn, true); - if ccx.tcx().sess.opts.cg.no_redzone - .unwrap_or(ccx.tcx().sess.target.target.options.disable_redzone) { + if cx.tcx.sess.opts.cg.no_redzone + .unwrap_or(cx.tcx.sess.target.target.options.disable_redzone) { llvm::Attribute::NoRedZone.apply_llfn(Function, llfn); } - if let Some(ref sanitizer) = ccx.tcx().sess.opts.debugging_opts.sanitizer { + if let Some(ref sanitizer) = cx.tcx.sess.opts.debugging_opts.sanitizer { match *sanitizer { Sanitizer::Address => { llvm::Attribute::SanitizeAddress.apply_llfn(Function, llfn); @@ -88,7 +88,7 @@ fn declare_raw_fn(ccx: &CrateContext, name: &str, callconv: llvm::CallConv, ty: } } - match ccx.tcx().sess.opts.cg.opt_level.as_ref().map(String::as_ref) { + match cx.tcx.sess.opts.cg.opt_level.as_ref().map(String::as_ref) { Some("s") => { llvm::Attribute::OptimizeForSize.apply_llfn(Function, llfn); }, @@ -99,7 +99,7 @@ fn declare_raw_fn(ccx: &CrateContext, name: &str, callconv: llvm::CallConv, ty: _ => {}, } - if ccx.tcx().sess.panic_strategy() != PanicStrategy::Unwind { + if cx.tcx.sess.panic_strategy() != PanicStrategy::Unwind { attributes::unwind(llfn, false); } @@ -114,8 +114,8 @@ fn declare_raw_fn(ccx: &CrateContext, name: &str, callconv: llvm::CallConv, ty: /// /// If there’s a value with the same name already declared, the function will /// update the declaration and return existing ValueRef instead. -pub fn declare_cfn(ccx: &CrateContext, name: &str, fn_type: Type) -> ValueRef { - declare_raw_fn(ccx, name, llvm::CCallConv, fn_type) +pub fn declare_cfn(cx: &CodegenCx, name: &str, fn_type: Type) -> ValueRef { + declare_raw_fn(cx, name, llvm::CCallConv, fn_type) } @@ -123,15 +123,15 @@ pub fn declare_cfn(ccx: &CrateContext, name: &str, fn_type: Type) -> ValueRef { /// /// If there’s a value with the same name already declared, the function will /// update the declaration and return existing ValueRef instead. -pub fn declare_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, name: &str, +pub fn declare_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, name: &str, fn_type: Ty<'tcx>) -> ValueRef { debug!("declare_rust_fn(name={:?}, fn_type={:?})", name, fn_type); - let sig = common::ty_fn_sig(ccx, fn_type); - let sig = ccx.tcx().erase_late_bound_regions_and_normalize(&sig); + let sig = common::ty_fn_sig(cx, fn_type); + let sig = cx.tcx.erase_late_bound_regions_and_normalize(&sig); debug!("declare_rust_fn (after region erasure) sig={:?}", sig); - let fty = FnType::new(ccx, sig, &[]); - let llfn = declare_raw_fn(ccx, name, fty.cconv, fty.llvm_type(ccx)); + let fty = FnType::new(cx, sig, &[]); + let llfn = declare_raw_fn(cx, name, fty.cconv, fty.llvm_type(cx)); // FIXME(canndrew): This is_never should really be an is_uninhabited if sig.output().is_never() { @@ -154,11 +154,11 @@ pub fn declare_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, name: &str, /// return None if the name already has a definition associated with it. In that /// case an error should be reported to the user, because it usually happens due /// to user’s fault (e.g. misuse of #[no_mangle] or #[export_name] attributes). -pub fn define_global(ccx: &CrateContext, name: &str, ty: Type) -> Option<ValueRef> { - if get_defined_value(ccx, name).is_some() { +pub fn define_global(cx: &CodegenCx, name: &str, ty: Type) -> Option<ValueRef> { + if get_defined_value(cx, name).is_some() { None } else { - Some(declare_global(ccx, name, ty)) + Some(declare_global(cx, name, ty)) } } @@ -167,13 +167,13 @@ pub fn define_global(ccx: &CrateContext, name: &str, ty: Type) -> Option<ValueRe /// Use this function when you intend to define a function. This function will /// return panic if the name already has a definition associated with it. This /// can happen with #[no_mangle] or #[export_name], for example. -pub fn define_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, +pub fn define_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, name: &str, fn_type: Ty<'tcx>) -> ValueRef { - if get_defined_value(ccx, name).is_some() { - ccx.sess().fatal(&format!("symbol `{}` already defined", name)) + if get_defined_value(cx, name).is_some() { + cx.sess().fatal(&format!("symbol `{}` already defined", name)) } else { - declare_fn(ccx, name, fn_type) + declare_fn(cx, name, fn_type) } } @@ -182,22 +182,22 @@ pub fn define_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, /// Use this function when you intend to define a function. This function will /// return panic if the name already has a definition associated with it. This /// can happen with #[no_mangle] or #[export_name], for example. -pub fn define_internal_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, +pub fn define_internal_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, name: &str, fn_type: Ty<'tcx>) -> ValueRef { - let llfn = define_fn(ccx, name, fn_type); + let llfn = define_fn(cx, name, fn_type); unsafe { llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::InternalLinkage) }; llfn } /// Get declared value by name. -pub fn get_declared_value(ccx: &CrateContext, name: &str) -> Option<ValueRef> { +pub fn get_declared_value(cx: &CodegenCx, name: &str) -> Option<ValueRef> { debug!("get_declared_value(name={:?})", name); let namebuf = CString::new(name).unwrap_or_else(|_|{ bug!("name {:?} contains an interior null byte", name) }); - let val = unsafe { llvm::LLVMRustGetNamedValue(ccx.llmod(), namebuf.as_ptr()) }; + let val = unsafe { llvm::LLVMRustGetNamedValue(cx.llmod, namebuf.as_ptr()) }; if val.is_null() { debug!("get_declared_value: {:?} value is null", name); None @@ -209,8 +209,8 @@ pub fn get_declared_value(ccx: &CrateContext, name: &str) -> Option<ValueRef> { /// Get defined or externally defined (AvailableExternally linkage) value by /// name. -pub fn get_defined_value(ccx: &CrateContext, name: &str) -> Option<ValueRef> { - get_declared_value(ccx, name).and_then(|val|{ +pub fn get_defined_value(cx: &CodegenCx, name: &str) -> Option<ValueRef> { + get_declared_value(cx, name).and_then(|val|{ let declaration = unsafe { llvm::LLVMIsDeclaration(val) != 0 }; diff --git a/src/librustc_trans/diagnostics.rs b/src/librustc_trans/diagnostics.rs index 8f5d836f56f..57cc33d09bb 100644 --- a/src/librustc_trans/diagnostics.rs +++ b/src/librustc_trans/diagnostics.rs @@ -47,27 +47,9 @@ unsafe { simd_add(i32x2(0, 0), i32x2(1, 2)); } // ok! ``` "##, -E0558: r##" -The `export_name` attribute was malformed. - -Erroneous code example: - -```ignore (error-emitted-at-codegen-which-cannot-be-handled-by-compile_fail) -#[export_name] // error: export_name attribute has invalid format -pub fn something() {} - -fn main() {} -``` - -The `export_name` attribute expects a string in order to determine the name of -the exported symbol. Example: - -``` -#[export_name = "some_function"] // ok! -pub fn something() {} +} -fn main() {} -``` -"##, +register_diagnostics! { + E0558 } diff --git a/src/librustc_trans/glue.rs b/src/librustc_trans/glue.rs index 9477adc17c0..c7275d09401 100644 --- a/src/librustc_trans/glue.rs +++ b/src/librustc_trans/glue.rs @@ -23,39 +23,39 @@ use rustc::ty::layout::LayoutOf; use rustc::ty::{self, Ty}; use value::Value; -pub fn size_and_align_of_dst<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, t: Ty<'tcx>, info: ValueRef) +pub fn size_and_align_of_dst<'a, 'tcx>(bx: &Builder<'a, 'tcx>, t: Ty<'tcx>, info: ValueRef) -> (ValueRef, ValueRef) { debug!("calculate size of DST: {}; with lost info: {:?}", t, Value(info)); - if bcx.ccx.shared().type_is_sized(t) { - let (size, align) = bcx.ccx.size_and_align_of(t); + if bx.cx.type_is_sized(t) { + let (size, align) = bx.cx.size_and_align_of(t); debug!("size_and_align_of_dst t={} info={:?} size: {:?} align: {:?}", t, Value(info), size, align); - let size = C_usize(bcx.ccx, size.bytes()); - let align = C_usize(bcx.ccx, align.abi()); + let size = C_usize(bx.cx, size.bytes()); + let align = C_usize(bx.cx, align.abi()); return (size, align); } assert!(!info.is_null()); match t.sty { ty::TyDynamic(..) => { // load size/align from vtable - (meth::SIZE.get_usize(bcx, info), meth::ALIGN.get_usize(bcx, info)) + (meth::SIZE.get_usize(bx, info), meth::ALIGN.get_usize(bx, info)) } ty::TySlice(_) | ty::TyStr => { - let unit = t.sequence_element_type(bcx.tcx()); + let unit = t.sequence_element_type(bx.tcx()); // The info in this case is the length of the str, so the size is that // times the unit size. - let (size, align) = bcx.ccx.size_and_align_of(unit); - (bcx.mul(info, C_usize(bcx.ccx, size.bytes())), - C_usize(bcx.ccx, align.abi())) + let (size, align) = bx.cx.size_and_align_of(unit); + (bx.mul(info, C_usize(bx.cx, size.bytes())), + C_usize(bx.cx, align.abi())) } _ => { - let ccx = bcx.ccx; + let cx = bx.cx; // 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 = ccx.layout_of(t); + let layout = cx.layout_of(t); debug!("DST {} layout: {:?}", t, layout); let i = layout.fields.count() - 1; @@ -63,13 +63,13 @@ pub fn size_and_align_of_dst<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, t: Ty<'tcx>, inf let sized_align = layout.align.abi(); debug!("DST {} statically sized prefix size: {} align: {}", t, sized_size, sized_align); - let sized_size = C_usize(ccx, sized_size); - let sized_align = C_usize(ccx, sized_align); + let sized_size = C_usize(cx, sized_size); + let sized_align = C_usize(cx, sized_align); // Recurse to get the size of the dynamically sized field (must be // the last field). - let field_ty = layout.field(ccx, i).ty; - let (unsized_size, mut unsized_align) = size_and_align_of_dst(bcx, field_ty, info); + let field_ty = layout.field(cx, i).ty; + let (unsized_size, mut unsized_align) = size_and_align_of_dst(bx, field_ty, info); // FIXME (#26403, #27023): We should be adding padding // to `sized_size` (to accommodate the `unsized_align` @@ -79,7 +79,7 @@ pub fn size_and_align_of_dst<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, t: Ty<'tcx>, inf // here. But this is where the add would go.) // Return the sum of sizes and max of aligns. - let size = bcx.add(sized_size, unsized_size); + let size = bx.add(sized_size, unsized_size); // Packed types ignore the alignment of their fields. if let ty::TyAdt(def, _) = t.sty { @@ -95,9 +95,9 @@ pub fn size_and_align_of_dst<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, t: Ty<'tcx>, inf (Some(sized_align), Some(unsized_align)) => { // If both alignments are constant, (the sized_align should always be), then // pick the correct alignment statically. - C_usize(ccx, std::cmp::max(sized_align, unsized_align) as u64) + C_usize(cx, std::cmp::max(sized_align, unsized_align) as u64) } - _ => bcx.select(bcx.icmp(llvm::IntUGT, sized_align, unsized_align), + _ => bx.select(bx.icmp(llvm::IntUGT, sized_align, unsized_align), sized_align, unsized_align) }; @@ -113,8 +113,8 @@ pub fn size_and_align_of_dst<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, t: Ty<'tcx>, inf // // `(size + (align-1)) & -align` - let addend = bcx.sub(align, C_usize(bcx.ccx, 1)); - let size = bcx.and(bcx.add(size, addend), bcx.neg(align)); + let addend = bx.sub(align, C_usize(bx.cx, 1)); + let size = bx.and(bx.add(size, addend), bx.neg(align)); (size, align) } diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs index 23f7d47e722..b1f1fb52c90 100644 --- a/src/librustc_trans/intrinsic.rs +++ b/src/librustc_trans/intrinsic.rs @@ -35,7 +35,7 @@ use syntax_pos::Span; use std::cmp::Ordering; use std::iter; -fn get_simple_intrinsic(ccx: &CrateContext, name: &str) -> Option<ValueRef> { +fn get_simple_intrinsic(cx: &CodegenCx, name: &str) -> Option<ValueRef> { let llvm_name = match name { "sqrtf32" => "llvm.sqrt.f32", "sqrtf64" => "llvm.sqrt.f64", @@ -79,20 +79,20 @@ fn get_simple_intrinsic(ccx: &CrateContext, name: &str) -> Option<ValueRef> { "abort" => "llvm.trap", _ => return None }; - Some(ccx.get_intrinsic(&llvm_name)) + Some(cx.get_intrinsic(&llvm_name)) } /// Remember to add all intrinsics here, in librustc_typeck/check/mod.rs, /// and in libcore/intrinsics.rs; if you need access to any llvm intrinsics, /// add them to librustc_trans/trans/context.rs -pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, +pub fn trans_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>, callee_ty: Ty<'tcx>, fn_ty: &FnType<'tcx>, args: &[OperandRef<'tcx>], llresult: ValueRef, span: Span) { - let ccx = bcx.ccx; - let tcx = ccx.tcx(); + let cx = bx.cx; + let tcx = cx.tcx; let (def_id, substs) = match callee_ty.sty { ty::TyFnDef(def_id, substs) => (def_id, substs), @@ -105,13 +105,13 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, let ret_ty = sig.output(); let name = &*tcx.item_name(def_id); - let llret_ty = ccx.layout_of(ret_ty).llvm_type(ccx); + let llret_ty = cx.layout_of(ret_ty).llvm_type(cx); let result = PlaceRef::new_sized(llresult, fn_ty.ret.layout, fn_ty.ret.layout.align); - let simple = get_simple_intrinsic(ccx, name); + let simple = get_simple_intrinsic(cx, name); let llval = match name { _ if simple.is_some() => { - bcx.call(simple.unwrap(), + bx.call(simple.unwrap(), &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), None) } @@ -119,15 +119,15 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, return; }, "likely" => { - let expect = ccx.get_intrinsic(&("llvm.expect.i1")); - bcx.call(expect, &[args[0].immediate(), C_bool(ccx, true)], None) + let expect = cx.get_intrinsic(&("llvm.expect.i1")); + bx.call(expect, &[args[0].immediate(), C_bool(cx, true)], None) } "unlikely" => { - let expect = ccx.get_intrinsic(&("llvm.expect.i1")); - bcx.call(expect, &[args[0].immediate(), C_bool(ccx, false)], None) + let expect = cx.get_intrinsic(&("llvm.expect.i1")); + bx.call(expect, &[args[0].immediate(), C_bool(cx, false)], None) } "try" => { - try_intrinsic(bcx, ccx, + try_intrinsic(bx, cx, args[0].immediate(), args[1].immediate(), args[2].immediate(), @@ -135,57 +135,57 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, return; } "breakpoint" => { - let llfn = ccx.get_intrinsic(&("llvm.debugtrap")); - bcx.call(llfn, &[], None) + let llfn = cx.get_intrinsic(&("llvm.debugtrap")); + bx.call(llfn, &[], None) } "size_of" => { let tp_ty = substs.type_at(0); - C_usize(ccx, ccx.size_of(tp_ty).bytes()) + C_usize(cx, cx.size_of(tp_ty).bytes()) } "size_of_val" => { let tp_ty = substs.type_at(0); if let OperandValue::Pair(_, meta) = args[0].val { let (llsize, _) = - glue::size_and_align_of_dst(bcx, tp_ty, meta); + glue::size_and_align_of_dst(bx, tp_ty, meta); llsize } else { - C_usize(ccx, ccx.size_of(tp_ty).bytes()) + C_usize(cx, cx.size_of(tp_ty).bytes()) } } "min_align_of" => { let tp_ty = substs.type_at(0); - C_usize(ccx, ccx.align_of(tp_ty).abi()) + C_usize(cx, cx.align_of(tp_ty).abi()) } "min_align_of_val" => { let tp_ty = substs.type_at(0); if let OperandValue::Pair(_, meta) = args[0].val { let (_, llalign) = - glue::size_and_align_of_dst(bcx, tp_ty, meta); + glue::size_and_align_of_dst(bx, tp_ty, meta); llalign } else { - C_usize(ccx, ccx.align_of(tp_ty).abi()) + C_usize(cx, cx.align_of(tp_ty).abi()) } } "pref_align_of" => { let tp_ty = substs.type_at(0); - C_usize(ccx, ccx.align_of(tp_ty).pref()) + C_usize(cx, cx.align_of(tp_ty).pref()) } "type_name" => { let tp_ty = substs.type_at(0); let ty_name = Symbol::intern(&tp_ty.to_string()).as_str(); - C_str_slice(ccx, ty_name) + C_str_slice(cx, ty_name) } "type_id" => { - C_u64(ccx, ccx.tcx().type_id_hash(substs.type_at(0))) + C_u64(cx, cx.tcx.type_id_hash(substs.type_at(0))) } "init" => { let ty = substs.type_at(0); - if !ccx.layout_of(ty).is_zst() { + if !cx.layout_of(ty).is_zst() { // Just zero out the stack slot. // If we store a zero constant, LLVM will drown in vreg allocation for large data // structures, and the generated code will be awful. (A telltale sign of this is // large quantities of `mov [byte ptr foo],0` in the generated code.) - memset_intrinsic(bcx, false, ty, llresult, C_u8(ccx, 0), C_usize(ccx, 1)); + memset_intrinsic(bx, false, ty, llresult, C_u8(cx, 0), C_usize(cx, 1)); } return; } @@ -196,82 +196,82 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, "needs_drop" => { let tp_ty = substs.type_at(0); - C_bool(ccx, bcx.ccx.shared().type_needs_drop(tp_ty)) + C_bool(cx, bx.cx.type_needs_drop(tp_ty)) } "offset" => { let ptr = args[0].immediate(); let offset = args[1].immediate(); - bcx.inbounds_gep(ptr, &[offset]) + bx.inbounds_gep(ptr, &[offset]) } "arith_offset" => { let ptr = args[0].immediate(); let offset = args[1].immediate(); - bcx.gep(ptr, &[offset]) + bx.gep(ptr, &[offset]) } "copy_nonoverlapping" => { - copy_intrinsic(bcx, false, false, substs.type_at(0), + copy_intrinsic(bx, false, false, substs.type_at(0), args[1].immediate(), args[0].immediate(), args[2].immediate()) } "copy" => { - copy_intrinsic(bcx, true, false, substs.type_at(0), + copy_intrinsic(bx, true, false, substs.type_at(0), args[1].immediate(), args[0].immediate(), args[2].immediate()) } "write_bytes" => { - memset_intrinsic(bcx, false, substs.type_at(0), + memset_intrinsic(bx, false, substs.type_at(0), args[0].immediate(), args[1].immediate(), args[2].immediate()) } "volatile_copy_nonoverlapping_memory" => { - copy_intrinsic(bcx, false, true, substs.type_at(0), + copy_intrinsic(bx, false, true, substs.type_at(0), args[0].immediate(), args[1].immediate(), args[2].immediate()) } "volatile_copy_memory" => { - copy_intrinsic(bcx, true, true, substs.type_at(0), + copy_intrinsic(bx, true, true, substs.type_at(0), args[0].immediate(), args[1].immediate(), args[2].immediate()) } "volatile_set_memory" => { - memset_intrinsic(bcx, true, substs.type_at(0), + memset_intrinsic(bx, true, substs.type_at(0), args[0].immediate(), args[1].immediate(), args[2].immediate()) } "volatile_load" => { let tp_ty = substs.type_at(0); let mut ptr = args[0].immediate(); if let PassMode::Cast(ty) = fn_ty.ret.mode { - ptr = bcx.pointercast(ptr, ty.llvm_type(ccx).ptr_to()); + ptr = bx.pointercast(ptr, ty.llvm_type(cx).ptr_to()); } - let load = bcx.volatile_load(ptr); + let load = bx.volatile_load(ptr); unsafe { - llvm::LLVMSetAlignment(load, ccx.align_of(tp_ty).abi() as u32); + llvm::LLVMSetAlignment(load, cx.align_of(tp_ty).abi() as u32); } - to_immediate(bcx, load, ccx.layout_of(tp_ty)) + to_immediate(bx, load, cx.layout_of(tp_ty)) }, "volatile_store" => { let tp_ty = substs.type_at(0); - let dst = args[0].deref(bcx.ccx); + let dst = args[0].deref(bx.cx); if let OperandValue::Pair(a, b) = args[1].val { - bcx.volatile_store(a, dst.project_field(bcx, 0).llval); - bcx.volatile_store(b, dst.project_field(bcx, 1).llval); + bx.volatile_store(a, dst.project_field(bx, 0).llval); + bx.volatile_store(b, dst.project_field(bx, 1).llval); } else { let val = if let OperandValue::Ref(ptr, align) = args[1].val { - bcx.load(ptr, align) + bx.load(ptr, align) } else { if dst.layout.is_zst() { return; } - from_immediate(bcx, args[1].immediate()) + from_immediate(bx, args[1].immediate()) }; - let ptr = bcx.pointercast(dst.llval, val_ty(val).ptr_to()); - let store = bcx.volatile_store(val, ptr); + let ptr = bx.pointercast(dst.llval, val_ty(val).ptr_to()); + let store = bx.volatile_store(val, ptr); unsafe { - llvm::LLVMSetAlignment(store, ccx.align_of(tp_ty).abi() as u32); + llvm::LLVMSetAlignment(store, cx.align_of(tp_ty).abi() as u32); } } return; }, "prefetch_read_data" | "prefetch_write_data" | "prefetch_read_instruction" | "prefetch_write_instruction" => { - let expect = ccx.get_intrinsic(&("llvm.prefetch")); + let expect = cx.get_intrinsic(&("llvm.prefetch")); let (rw, cache_type) = match name { "prefetch_read_data" => (0, 1), "prefetch_write_data" => (1, 1), @@ -279,11 +279,11 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, "prefetch_write_instruction" => (1, 0), _ => bug!() }; - bcx.call(expect, &[ + bx.call(expect, &[ args[0].immediate(), - C_i32(ccx, rw), + C_i32(cx, rw), args[1].immediate(), - C_i32(ccx, cache_type) + C_i32(cx, cache_type) ], None) }, "ctlz" | "ctlz_nonzero" | "cttz" | "cttz_nonzero" | "ctpop" | "bswap" | @@ -291,27 +291,27 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, "overflowing_add" | "overflowing_sub" | "overflowing_mul" | "unchecked_div" | "unchecked_rem" | "unchecked_shl" | "unchecked_shr" => { let ty = arg_tys[0]; - match int_type_width_signed(ty, ccx) { + match int_type_width_signed(ty, cx) { Some((width, signed)) => match name { "ctlz" | "cttz" => { - let y = C_bool(bcx.ccx, false); - let llfn = ccx.get_intrinsic(&format!("llvm.{}.i{}", name, width)); - bcx.call(llfn, &[args[0].immediate(), y], None) + let y = C_bool(bx.cx, false); + let llfn = cx.get_intrinsic(&format!("llvm.{}.i{}", name, width)); + bx.call(llfn, &[args[0].immediate(), y], None) } "ctlz_nonzero" | "cttz_nonzero" => { - let y = C_bool(bcx.ccx, true); + let y = C_bool(bx.cx, true); let llvm_name = &format!("llvm.{}.i{}", &name[..4], width); - let llfn = ccx.get_intrinsic(llvm_name); - bcx.call(llfn, &[args[0].immediate(), y], None) + let llfn = cx.get_intrinsic(llvm_name); + bx.call(llfn, &[args[0].immediate(), y], None) } - "ctpop" => bcx.call(ccx.get_intrinsic(&format!("llvm.ctpop.i{}", width)), + "ctpop" => bx.call(cx.get_intrinsic(&format!("llvm.ctpop.i{}", width)), &[args[0].immediate()], None), "bswap" => { if width == 8 { args[0].immediate() // byte swap a u8/i8 is just a no-op } else { - bcx.call(ccx.get_intrinsic(&format!("llvm.bswap.i{}", width)), + bx.call(cx.get_intrinsic(&format!("llvm.bswap.i{}", width)), &[args[0].immediate()], None) } } @@ -319,44 +319,44 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, let intrinsic = format!("llvm.{}{}.with.overflow.i{}", if signed { 's' } else { 'u' }, &name[..3], width); - let llfn = bcx.ccx.get_intrinsic(&intrinsic); + let llfn = bx.cx.get_intrinsic(&intrinsic); // Convert `i1` to a `bool`, and write it to the out parameter - let pair = bcx.call(llfn, &[ + let pair = bx.call(llfn, &[ args[0].immediate(), args[1].immediate() ], None); - let val = bcx.extract_value(pair, 0); - let overflow = bcx.zext(bcx.extract_value(pair, 1), Type::bool(ccx)); + let val = bx.extract_value(pair, 0); + let overflow = bx.zext(bx.extract_value(pair, 1), Type::bool(cx)); - let dest = result.project_field(bcx, 0); - bcx.store(val, dest.llval, dest.align); - let dest = result.project_field(bcx, 1); - bcx.store(overflow, dest.llval, dest.align); + let dest = result.project_field(bx, 0); + bx.store(val, dest.llval, dest.align); + let dest = result.project_field(bx, 1); + bx.store(overflow, dest.llval, dest.align); return; }, - "overflowing_add" => bcx.add(args[0].immediate(), args[1].immediate()), - "overflowing_sub" => bcx.sub(args[0].immediate(), args[1].immediate()), - "overflowing_mul" => bcx.mul(args[0].immediate(), args[1].immediate()), + "overflowing_add" => bx.add(args[0].immediate(), args[1].immediate()), + "overflowing_sub" => bx.sub(args[0].immediate(), args[1].immediate()), + "overflowing_mul" => bx.mul(args[0].immediate(), args[1].immediate()), "unchecked_div" => if signed { - bcx.sdiv(args[0].immediate(), args[1].immediate()) + bx.sdiv(args[0].immediate(), args[1].immediate()) } else { - bcx.udiv(args[0].immediate(), args[1].immediate()) + bx.udiv(args[0].immediate(), args[1].immediate()) }, "unchecked_rem" => if signed { - bcx.srem(args[0].immediate(), args[1].immediate()) + bx.srem(args[0].immediate(), args[1].immediate()) } else { - bcx.urem(args[0].immediate(), args[1].immediate()) + bx.urem(args[0].immediate(), args[1].immediate()) }, - "unchecked_shl" => bcx.shl(args[0].immediate(), args[1].immediate()), + "unchecked_shl" => bx.shl(args[0].immediate(), args[1].immediate()), "unchecked_shr" => if signed { - bcx.ashr(args[0].immediate(), args[1].immediate()) + bx.ashr(args[0].immediate(), args[1].immediate()) } else { - bcx.lshr(args[0].immediate(), args[1].immediate()) + bx.lshr(args[0].immediate(), args[1].immediate()) }, _ => bug!(), }, @@ -375,11 +375,11 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, match float_type_width(sty) { Some(_width) => match name { - "fadd_fast" => bcx.fadd_fast(args[0].immediate(), args[1].immediate()), - "fsub_fast" => bcx.fsub_fast(args[0].immediate(), args[1].immediate()), - "fmul_fast" => bcx.fmul_fast(args[0].immediate(), args[1].immediate()), - "fdiv_fast" => bcx.fdiv_fast(args[0].immediate(), args[1].immediate()), - "frem_fast" => bcx.frem_fast(args[0].immediate(), args[1].immediate()), + "fadd_fast" => bx.fadd_fast(args[0].immediate(), args[1].immediate()), + "fsub_fast" => bx.fsub_fast(args[0].immediate(), args[1].immediate()), + "fmul_fast" => bx.fmul_fast(args[0].immediate(), args[1].immediate()), + "fdiv_fast" => bx.fdiv_fast(args[0].immediate(), args[1].immediate()), + "frem_fast" => bx.frem_fast(args[0].immediate(), args[1].immediate()), _ => bug!(), }, None => { @@ -394,23 +394,23 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, }, "discriminant_value" => { - args[0].deref(bcx.ccx).trans_get_discr(bcx, ret_ty) + args[0].deref(bx.cx).trans_get_discr(bx, ret_ty) } "align_offset" => { // `ptr as usize` - let ptr_val = bcx.ptrtoint(args[0].immediate(), bcx.ccx.isize_ty()); + let ptr_val = bx.ptrtoint(args[0].immediate(), bx.cx.isize_ty); // `ptr_val % align` let align = args[1].immediate(); - let offset = bcx.urem(ptr_val, align); - let zero = C_null(bcx.ccx.isize_ty()); + let offset = bx.urem(ptr_val, align); + let zero = C_null(bx.cx.isize_ty); // `offset == 0` - let is_zero = bcx.icmp(llvm::IntPredicate::IntEQ, offset, zero); + let is_zero = bx.icmp(llvm::IntPredicate::IntEQ, offset, zero); // `if offset == 0 { 0 } else { align - offset }` - bcx.select(is_zero, zero, bcx.sub(align, offset)) + bx.select(is_zero, zero, bx.sub(align, offset)) } name if name.starts_with("simd_") => { - match generic_simd_intrinsic(bcx, name, + match generic_simd_intrinsic(bx, name, callee_ty, args, ret_ty, llret_ty, @@ -439,16 +439,16 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, (SequentiallyConsistent, Monotonic), "failacq" if is_cxchg => (SequentiallyConsistent, Acquire), - _ => ccx.sess().fatal("unknown ordering in atomic intrinsic") + _ => cx.sess().fatal("unknown ordering in atomic intrinsic") }, 4 => match (split[2], split[3]) { ("acq", "failrelaxed") if is_cxchg => (Acquire, Monotonic), ("acqrel", "failrelaxed") if is_cxchg => (AcquireRelease, Monotonic), - _ => ccx.sess().fatal("unknown ordering in atomic intrinsic") + _ => cx.sess().fatal("unknown ordering in atomic intrinsic") }, - _ => ccx.sess().fatal("Atomic intrinsic not in correct format"), + _ => cx.sess().fatal("Atomic intrinsic not in correct format"), }; let invalid_monomorphization = |ty| { @@ -460,22 +460,22 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, match split[1] { "cxchg" | "cxchgweak" => { let ty = substs.type_at(0); - if int_type_width_signed(ty, ccx).is_some() { + if int_type_width_signed(ty, cx).is_some() { let weak = if split[1] == "cxchgweak" { llvm::True } else { llvm::False }; - let pair = bcx.atomic_cmpxchg( + let pair = bx.atomic_cmpxchg( args[0].immediate(), args[1].immediate(), args[2].immediate(), order, failorder, weak); - let val = bcx.extract_value(pair, 0); - let success = bcx.zext(bcx.extract_value(pair, 1), Type::bool(bcx.ccx)); + let val = bx.extract_value(pair, 0); + let success = bx.zext(bx.extract_value(pair, 1), Type::bool(bx.cx)); - let dest = result.project_field(bcx, 0); - bcx.store(val, dest.llval, dest.align); - let dest = result.project_field(bcx, 1); - bcx.store(success, dest.llval, dest.align); + let dest = result.project_field(bx, 0); + bx.store(val, dest.llval, dest.align); + let dest = result.project_field(bx, 1); + bx.store(success, dest.llval, dest.align); return; } else { return invalid_monomorphization(ty); @@ -484,9 +484,9 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, "load" => { let ty = substs.type_at(0); - if int_type_width_signed(ty, ccx).is_some() { - let align = ccx.align_of(ty); - bcx.atomic_load(args[0].immediate(), order, align) + if int_type_width_signed(ty, cx).is_some() { + let align = cx.align_of(ty); + bx.atomic_load(args[0].immediate(), order, align) } else { return invalid_monomorphization(ty); } @@ -494,9 +494,9 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, "store" => { let ty = substs.type_at(0); - if int_type_width_signed(ty, ccx).is_some() { - let align = ccx.align_of(ty); - bcx.atomic_store(args[1].immediate(), args[0].immediate(), order, align); + if int_type_width_signed(ty, cx).is_some() { + let align = cx.align_of(ty); + bx.atomic_store(args[1].immediate(), args[0].immediate(), order, align); return; } else { return invalid_monomorphization(ty); @@ -504,12 +504,12 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, } "fence" => { - bcx.atomic_fence(order, llvm::SynchronizationScope::CrossThread); + bx.atomic_fence(order, llvm::SynchronizationScope::CrossThread); return; } "singlethreadfence" => { - bcx.atomic_fence(order, llvm::SynchronizationScope::SingleThread); + bx.atomic_fence(order, llvm::SynchronizationScope::SingleThread); return; } @@ -527,12 +527,12 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, "min" => llvm::AtomicMin, "umax" => llvm::AtomicUMax, "umin" => llvm::AtomicUMin, - _ => ccx.sess().fatal("unknown atomic operation") + _ => cx.sess().fatal("unknown atomic operation") }; let ty = substs.type_at(0); - if int_type_width_signed(ty, ccx).is_some() { - bcx.atomic_rmw(atom_op, args[0].immediate(), args[1].immediate(), order) + if int_type_width_signed(ty, cx).is_some() { + bx.atomic_rmw(atom_op, args[0].immediate(), args[1].immediate(), order) } else { return invalid_monomorphization(ty); } @@ -542,16 +542,16 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, "nontemporal_store" => { let tp_ty = substs.type_at(0); - let dst = args[0].deref(bcx.ccx); + let dst = args[0].deref(bx.cx); let val = if let OperandValue::Ref(ptr, align) = args[1].val { - bcx.load(ptr, align) + bx.load(ptr, align) } else { - from_immediate(bcx, args[1].immediate()) + from_immediate(bx, args[1].immediate()) }; - let ptr = bcx.pointercast(dst.llval, val_ty(val).ptr_to()); - let store = bcx.nontemporal_store(val, ptr); + let ptr = bx.pointercast(dst.llval, val_ty(val).ptr_to()); + let store = bx.nontemporal_store(val, ptr); unsafe { - llvm::LLVMSetAlignment(store, ccx.align_of(tp_ty).abi() as u32); + llvm::LLVMSetAlignment(store, cx.align_of(tp_ty).abi() as u32); } return } @@ -565,39 +565,39 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, assert_eq!(x.len(), 1); x.into_iter().next().unwrap() } - fn ty_to_type(ccx: &CrateContext, t: &intrinsics::Type) -> Vec<Type> { + fn ty_to_type(cx: &CodegenCx, t: &intrinsics::Type) -> Vec<Type> { use intrinsics::Type::*; match *t { - Void => vec![Type::void(ccx)], + Void => vec![Type::void(cx)], Integer(_signed, _width, llvm_width) => { - vec![Type::ix(ccx, llvm_width as u64)] + vec![Type::ix(cx, llvm_width as u64)] } Float(x) => { match x { - 32 => vec![Type::f32(ccx)], - 64 => vec![Type::f64(ccx)], + 32 => vec![Type::f32(cx)], + 64 => vec![Type::f64(cx)], _ => bug!() } } Pointer(ref t, ref llvm_elem, _const) => { let t = llvm_elem.as_ref().unwrap_or(t); - let elem = one(ty_to_type(ccx, t)); + let elem = one(ty_to_type(cx, t)); vec![elem.ptr_to()] } Vector(ref t, ref llvm_elem, length) => { let t = llvm_elem.as_ref().unwrap_or(t); - let elem = one(ty_to_type(ccx, t)); + let elem = one(ty_to_type(cx, t)); vec![Type::vector(&elem, length as u64)] } Aggregate(false, ref contents) => { let elems = contents.iter() - .map(|t| one(ty_to_type(ccx, t))) + .map(|t| one(ty_to_type(cx, t))) .collect::<Vec<_>>(); - vec![Type::struct_(ccx, &elems, false)] + vec![Type::struct_(cx, &elems, false)] } Aggregate(true, ref contents) => { contents.iter() - .flat_map(|t| ty_to_type(ccx, t)) + .flat_map(|t| ty_to_type(cx, t)) .collect() } } @@ -607,7 +607,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, // qux` to be converted into `foo, bar, baz, qux`, integer // arguments to be truncated as needed and pointers to be // cast. - fn modify_as_needed<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, + fn modify_as_needed<'a, 'tcx>(bx: &Builder<'a, 'tcx>, t: &intrinsics::Type, arg: &OperandRef<'tcx>) -> Vec<ValueRef> @@ -620,29 +620,29 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, // This assumes the type is "simple", i.e. no // destructors, and the contents are SIMD // etc. - assert!(!bcx.ccx.shared().type_needs_drop(arg.layout.ty)); + assert!(!bx.cx.type_needs_drop(arg.layout.ty)); let (ptr, align) = match arg.val { OperandValue::Ref(ptr, align) => (ptr, align), _ => bug!() }; let arg = PlaceRef::new_sized(ptr, arg.layout, align); (0..contents.len()).map(|i| { - arg.project_field(bcx, i).load(bcx).immediate() + arg.project_field(bx, i).load(bx).immediate() }).collect() } intrinsics::Type::Pointer(_, Some(ref llvm_elem), _) => { - let llvm_elem = one(ty_to_type(bcx.ccx, llvm_elem)); - vec![bcx.pointercast(arg.immediate(), llvm_elem.ptr_to())] + let llvm_elem = one(ty_to_type(bx.cx, llvm_elem)); + vec![bx.pointercast(arg.immediate(), llvm_elem.ptr_to())] } intrinsics::Type::Vector(_, Some(ref llvm_elem), length) => { - let llvm_elem = one(ty_to_type(bcx.ccx, llvm_elem)); - vec![bcx.bitcast(arg.immediate(), Type::vector(&llvm_elem, length as u64))] + let llvm_elem = one(ty_to_type(bx.cx, llvm_elem)); + vec![bx.bitcast(arg.immediate(), Type::vector(&llvm_elem, length as u64))] } intrinsics::Type::Integer(_, width, llvm_width) if width != llvm_width => { // the LLVM intrinsic uses a smaller integer // size than the C intrinsic's signature, so // we have to trim it down here. - vec![bcx.trunc(arg.immediate(), Type::ix(bcx.ccx, llvm_width as u64))] + vec![bx.trunc(arg.immediate(), Type::ix(bx.cx, llvm_width as u64))] } _ => vec![arg.immediate()], } @@ -650,22 +650,22 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, let inputs = intr.inputs.iter() - .flat_map(|t| ty_to_type(ccx, t)) + .flat_map(|t| ty_to_type(cx, t)) .collect::<Vec<_>>(); - let outputs = one(ty_to_type(ccx, &intr.output)); + let outputs = one(ty_to_type(cx, &intr.output)); let llargs: Vec<_> = intr.inputs.iter().zip(args).flat_map(|(t, arg)| { - modify_as_needed(bcx, t, arg) + modify_as_needed(bx, t, arg) }).collect(); assert_eq!(inputs.len(), llargs.len()); let val = match intr.definition { intrinsics::IntrinsicDef::Named(name) => { - let f = declare::declare_cfn(ccx, + let f = declare::declare_cfn(cx, name, Type::func(&inputs, &outputs)); - bcx.call(f, &llargs, None) + bx.call(f, &llargs, None) } }; @@ -675,9 +675,9 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, assert!(!flatten); for i in 0..elems.len() { - let dest = result.project_field(bcx, i); - let val = bcx.extract_value(val, i as u64); - bcx.store(val, dest.llval, dest.align); + let dest = result.project_field(bx, i); + let val = bx.extract_value(val, i as u64); + bx.store(val, dest.llval, dest.align); } return; } @@ -688,16 +688,16 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, if !fn_ty.ret.is_ignore() { if let PassMode::Cast(ty) = fn_ty.ret.mode { - let ptr = bcx.pointercast(result.llval, ty.llvm_type(ccx).ptr_to()); - bcx.store(llval, ptr, result.align); + let ptr = bx.pointercast(result.llval, ty.llvm_type(cx).ptr_to()); + bx.store(llval, ptr, result.align); } else { - OperandRef::from_immediate_or_packed_pair(bcx, llval, result.layout) - .val.store(bcx, result); + OperandRef::from_immediate_or_packed_pair(bx, llval, result.layout) + .val.store(bx, result); } } } -fn copy_intrinsic<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, +fn copy_intrinsic<'a, 'tcx>(bx: &Builder<'a, 'tcx>, allow_overlap: bool, volatile: bool, ty: Ty<'tcx>, @@ -705,10 +705,10 @@ fn copy_intrinsic<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, src: ValueRef, count: ValueRef) -> ValueRef { - let ccx = bcx.ccx; - let (size, align) = ccx.size_and_align_of(ty); - let size = C_usize(ccx, size.bytes()); - let align = C_i32(ccx, align.abi() as i32); + let cx = bx.cx; + let (size, align) = cx.size_and_align_of(ty); + let size = C_usize(cx, size.bytes()); + let align = C_i32(cx, align.abi() as i32); let operation = if allow_overlap { "memmove" @@ -717,53 +717,53 @@ fn copy_intrinsic<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, }; let name = format!("llvm.{}.p0i8.p0i8.i{}", operation, - ccx.data_layout().pointer_size.bits()); + cx.data_layout().pointer_size.bits()); - let dst_ptr = bcx.pointercast(dst, Type::i8p(ccx)); - let src_ptr = bcx.pointercast(src, Type::i8p(ccx)); - let llfn = ccx.get_intrinsic(&name); + let dst_ptr = bx.pointercast(dst, Type::i8p(cx)); + let src_ptr = bx.pointercast(src, Type::i8p(cx)); + let llfn = cx.get_intrinsic(&name); - bcx.call(llfn, + bx.call(llfn, &[dst_ptr, src_ptr, - bcx.mul(size, count), + bx.mul(size, count), align, - C_bool(ccx, volatile)], + C_bool(cx, volatile)], None) } fn memset_intrinsic<'a, 'tcx>( - bcx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'tcx>, volatile: bool, ty: Ty<'tcx>, dst: ValueRef, val: ValueRef, count: ValueRef ) -> ValueRef { - let ccx = bcx.ccx; - let (size, align) = ccx.size_and_align_of(ty); - let size = C_usize(ccx, size.bytes()); - let align = C_i32(ccx, align.abi() as i32); - let dst = bcx.pointercast(dst, Type::i8p(ccx)); - call_memset(bcx, dst, val, bcx.mul(size, count), align, volatile) + let cx = bx.cx; + let (size, align) = cx.size_and_align_of(ty); + let size = C_usize(cx, size.bytes()); + let align = C_i32(cx, align.abi() as i32); + let dst = bx.pointercast(dst, Type::i8p(cx)); + call_memset(bx, dst, val, bx.mul(size, count), align, volatile) } fn try_intrinsic<'a, 'tcx>( - bcx: &Builder<'a, 'tcx>, - ccx: &CrateContext, + bx: &Builder<'a, 'tcx>, + cx: &CodegenCx, func: ValueRef, data: ValueRef, local_ptr: ValueRef, dest: ValueRef, ) { - if bcx.sess().no_landing_pads() { - bcx.call(func, &[data], None); - let ptr_align = bcx.tcx().data_layout.pointer_align; - bcx.store(C_null(Type::i8p(&bcx.ccx)), dest, ptr_align); - } else if wants_msvc_seh(bcx.sess()) { - trans_msvc_try(bcx, ccx, func, data, local_ptr, dest); + if bx.sess().no_landing_pads() { + bx.call(func, &[data], None); + let ptr_align = bx.tcx().data_layout.pointer_align; + bx.store(C_null(Type::i8p(&bx.cx)), dest, ptr_align); + } else if wants_msvc_seh(bx.sess()) { + trans_msvc_try(bx, cx, func, data, local_ptr, dest); } else { - trans_gnu_try(bcx, ccx, func, data, local_ptr, dest); + trans_gnu_try(bx, cx, func, data, local_ptr, dest); } } @@ -774,25 +774,25 @@ fn try_intrinsic<'a, 'tcx>( // instructions are meant to work for all targets, as of the time of this // writing, however, LLVM does not recommend the usage of these new instructions // as the old ones are still more optimized. -fn trans_msvc_try<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, - ccx: &CrateContext, +fn trans_msvc_try<'a, 'tcx>(bx: &Builder<'a, 'tcx>, + cx: &CodegenCx, func: ValueRef, data: ValueRef, local_ptr: ValueRef, dest: ValueRef) { - let llfn = get_rust_try_fn(ccx, &mut |bcx| { - let ccx = bcx.ccx; + let llfn = get_rust_try_fn(cx, &mut |bx| { + let cx = bx.cx; - bcx.set_personality_fn(bcx.ccx.eh_personality()); + bx.set_personality_fn(bx.cx.eh_personality()); - let normal = bcx.build_sibling_block("normal"); - let catchswitch = bcx.build_sibling_block("catchswitch"); - let catchpad = bcx.build_sibling_block("catchpad"); - let caught = bcx.build_sibling_block("caught"); + let normal = bx.build_sibling_block("normal"); + let catchswitch = bx.build_sibling_block("catchswitch"); + let catchpad = bx.build_sibling_block("catchpad"); + let caught = bx.build_sibling_block("caught"); - let func = llvm::get_param(bcx.llfn(), 0); - let data = llvm::get_param(bcx.llfn(), 1); - let local_ptr = llvm::get_param(bcx.llfn(), 2); + let func = llvm::get_param(bx.llfn(), 0); + let data = llvm::get_param(bx.llfn(), 1); + let local_ptr = llvm::get_param(bx.llfn(), 2); // We're generating an IR snippet that looks like: // @@ -833,42 +833,42 @@ fn trans_msvc_try<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, // } // // More information can be found in libstd's seh.rs implementation. - let i64p = Type::i64(ccx).ptr_to(); - let ptr_align = bcx.tcx().data_layout.pointer_align; - let slot = bcx.alloca(i64p, "slot", ptr_align); - bcx.invoke(func, &[data], normal.llbb(), catchswitch.llbb(), + let i64p = Type::i64(cx).ptr_to(); + let ptr_align = bx.tcx().data_layout.pointer_align; + let slot = bx.alloca(i64p, "slot", ptr_align); + bx.invoke(func, &[data], normal.llbb(), catchswitch.llbb(), None); - normal.ret(C_i32(ccx, 0)); + normal.ret(C_i32(cx, 0)); let cs = catchswitch.catch_switch(None, None, 1); catchswitch.add_handler(cs, catchpad.llbb()); - let tcx = ccx.tcx(); + let tcx = cx.tcx; let tydesc = match tcx.lang_items().msvc_try_filter() { - Some(did) => ::consts::get_static(ccx, did), + Some(did) => ::consts::get_static(cx, did), None => bug!("msvc_try_filter not defined"), }; - let tok = catchpad.catch_pad(cs, &[tydesc, C_i32(ccx, 0), slot]); + let tok = catchpad.catch_pad(cs, &[tydesc, C_i32(cx, 0), slot]); let addr = catchpad.load(slot, ptr_align); - let i64_align = bcx.tcx().data_layout.i64_align; + let i64_align = bx.tcx().data_layout.i64_align; let arg1 = catchpad.load(addr, i64_align); - let val1 = C_i32(ccx, 1); + let val1 = C_i32(cx, 1); let arg2 = catchpad.load(catchpad.inbounds_gep(addr, &[val1]), i64_align); let local_ptr = catchpad.bitcast(local_ptr, i64p); catchpad.store(arg1, local_ptr, i64_align); catchpad.store(arg2, catchpad.inbounds_gep(local_ptr, &[val1]), i64_align); catchpad.catch_ret(tok, caught.llbb()); - caught.ret(C_i32(ccx, 1)); + caught.ret(C_i32(cx, 1)); }); // Note that no invoke is used here because by definition this function // can't panic (that's what it's catching). - let ret = bcx.call(llfn, &[func, data, local_ptr], None); - let i32_align = bcx.tcx().data_layout.i32_align; - bcx.store(ret, dest, i32_align); + let ret = bx.call(llfn, &[func, data, local_ptr], None); + let i32_align = bx.tcx().data_layout.i32_align; + bx.store(ret, dest, i32_align); } // Definition of the standard "try" function for Rust using the GNU-like model @@ -882,18 +882,18 @@ fn trans_msvc_try<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, // function calling it, and that function may already have other personality // functions in play. By calling a shim we're guaranteed that our shim will have // the right personality function. -fn trans_gnu_try<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, - ccx: &CrateContext, +fn trans_gnu_try<'a, 'tcx>(bx: &Builder<'a, 'tcx>, + cx: &CodegenCx, func: ValueRef, data: ValueRef, local_ptr: ValueRef, dest: ValueRef) { - let llfn = get_rust_try_fn(ccx, &mut |bcx| { - let ccx = bcx.ccx; + let llfn = get_rust_try_fn(cx, &mut |bx| { + let cx = bx.cx; // Translates the shims described above: // - // bcx: + // bx: // invoke %func(%args...) normal %normal unwind %catch // // normal: @@ -908,14 +908,14 @@ fn trans_gnu_try<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, // expected to be `*mut *mut u8` for this to actually work, but that's // managed by the standard library. - let then = bcx.build_sibling_block("then"); - let catch = bcx.build_sibling_block("catch"); + let then = bx.build_sibling_block("then"); + let catch = bx.build_sibling_block("catch"); - let func = llvm::get_param(bcx.llfn(), 0); - let data = llvm::get_param(bcx.llfn(), 1); - let local_ptr = llvm::get_param(bcx.llfn(), 2); - bcx.invoke(func, &[data], then.llbb(), catch.llbb(), None); - then.ret(C_i32(ccx, 0)); + let func = llvm::get_param(bx.llfn(), 0); + let data = llvm::get_param(bx.llfn(), 1); + let local_ptr = llvm::get_param(bx.llfn(), 2); + bx.invoke(func, &[data], then.llbb(), catch.llbb(), None); + then.ret(C_i32(cx, 0)); // Type indicator for the exception being thrown. // @@ -923,41 +923,41 @@ fn trans_gnu_try<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, // being thrown. The second value is a "selector" indicating which of // the landing pad clauses the exception's type had been matched to. // rust_try ignores the selector. - let lpad_ty = Type::struct_(ccx, &[Type::i8p(ccx), Type::i32(ccx)], + let lpad_ty = Type::struct_(cx, &[Type::i8p(cx), Type::i32(cx)], false); - let vals = catch.landing_pad(lpad_ty, bcx.ccx.eh_personality(), 1); - catch.add_clause(vals, C_null(Type::i8p(ccx))); + let vals = catch.landing_pad(lpad_ty, bx.cx.eh_personality(), 1); + catch.add_clause(vals, C_null(Type::i8p(cx))); let ptr = catch.extract_value(vals, 0); - let ptr_align = bcx.tcx().data_layout.pointer_align; - catch.store(ptr, catch.bitcast(local_ptr, Type::i8p(ccx).ptr_to()), ptr_align); - catch.ret(C_i32(ccx, 1)); + let ptr_align = bx.tcx().data_layout.pointer_align; + catch.store(ptr, catch.bitcast(local_ptr, Type::i8p(cx).ptr_to()), ptr_align); + catch.ret(C_i32(cx, 1)); }); // Note that no invoke is used here because by definition this function // can't panic (that's what it's catching). - let ret = bcx.call(llfn, &[func, data, local_ptr], None); - let i32_align = bcx.tcx().data_layout.i32_align; - bcx.store(ret, dest, i32_align); + let ret = bx.call(llfn, &[func, data, local_ptr], None); + let i32_align = bx.tcx().data_layout.i32_align; + bx.store(ret, dest, i32_align); } // Helper function to give a Block to a closure to translate a shim function. // This is currently primarily used for the `try` intrinsic functions above. -fn gen_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, +fn gen_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, name: &str, inputs: Vec<Ty<'tcx>>, output: Ty<'tcx>, trans: &mut for<'b> FnMut(Builder<'b, 'tcx>)) -> ValueRef { - let rust_fn_ty = ccx.tcx().mk_fn_ptr(ty::Binder(ccx.tcx().mk_fn_sig( + let rust_fn_ty = cx.tcx.mk_fn_ptr(ty::Binder(cx.tcx.mk_fn_sig( inputs.into_iter(), output, false, hir::Unsafety::Unsafe, Abi::Rust ))); - let llfn = declare::define_internal_fn(ccx, name, rust_fn_ty); - let bcx = Builder::new_block(ccx, llfn, "entry-block"); - trans(bcx); + let llfn = declare::define_internal_fn(cx, name, rust_fn_ty); + let bx = Builder::new_block(cx, llfn, "entry-block"); + trans(bx); llfn } @@ -965,15 +965,15 @@ fn gen_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, // catch exceptions. // // This function is only generated once and is then cached. -fn get_rust_try_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, +fn get_rust_try_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, trans: &mut for<'b> FnMut(Builder<'b, 'tcx>)) -> ValueRef { - if let Some(llfn) = ccx.rust_try_fn().get() { + if let Some(llfn) = cx.rust_try_fn.get() { return llfn; } // Define the type up front for the signature of the rust_try function. - let tcx = ccx.tcx(); + let tcx = cx.tcx; let i8p = tcx.mk_mut_ptr(tcx.types.i8); let fn_ty = tcx.mk_fn_ptr(ty::Binder(tcx.mk_fn_sig( iter::once(i8p), @@ -983,8 +983,8 @@ fn get_rust_try_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, Abi::Rust ))); let output = tcx.types.i32; - let rust_try = gen_fn(ccx, "__rust_try", vec![fn_ty, i8p, i8p], output, trans); - ccx.rust_try_fn().set(Some(rust_try)); + let rust_try = gen_fn(cx, "__rust_try", vec![fn_ty, i8p, i8p], output, trans); + cx.rust_try_fn.set(Some(rust_try)); return rust_try } @@ -993,7 +993,7 @@ fn span_invalid_monomorphization_error(a: &Session, b: Span, c: &str) { } fn generic_simd_intrinsic<'a, 'tcx>( - bcx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'tcx>, name: &str, callee_ty: Ty<'tcx>, args: &[OperandRef<'tcx>], @@ -1008,7 +1008,7 @@ fn generic_simd_intrinsic<'a, 'tcx>( }; ($msg: tt, $($fmt: tt)*) => { span_invalid_monomorphization_error( - bcx.sess(), span, + bx.sess(), span, &format!(concat!("invalid monomorphization of `{}` intrinsic: ", $msg), name, $($fmt)*)); @@ -1030,7 +1030,7 @@ fn generic_simd_intrinsic<'a, 'tcx>( - let tcx = bcx.tcx(); + let tcx = bx.tcx(); let sig = tcx.erase_late_bound_regions_and_normalize(&callee_ty.fn_sig(tcx)); let arg_tys = sig.inputs(); @@ -1064,7 +1064,7 @@ fn generic_simd_intrinsic<'a, 'tcx>( ret_ty, ret_ty.simd_type(tcx)); - return Ok(compare_simd_types(bcx, + return Ok(compare_simd_types(bx, args[0].immediate(), args[1].immediate(), in_elem, @@ -1109,7 +1109,7 @@ fn generic_simd_intrinsic<'a, 'tcx>( arg_idx, total_len); None } - Some(idx) => Some(C_i32(bcx.ccx, idx as i32)), + Some(idx) => Some(C_i32(bx.cx, idx as i32)), } }) .collect(); @@ -1118,7 +1118,7 @@ fn generic_simd_intrinsic<'a, 'tcx>( None => return Ok(C_null(llret_ty)) }; - return Ok(bcx.shuffle_vector(args[0].immediate(), + return Ok(bx.shuffle_vector(args[0].immediate(), args[1].immediate(), C_vector(&indices))) } @@ -1127,7 +1127,7 @@ fn generic_simd_intrinsic<'a, 'tcx>( require!(in_elem == arg_tys[2], "expected inserted type `{}` (element of input `{}`), found `{}`", in_elem, in_ty, arg_tys[2]); - return Ok(bcx.insert_element(args[0].immediate(), + return Ok(bx.insert_element(args[0].immediate(), args[2].immediate(), args[1].immediate())) } @@ -1135,7 +1135,7 @@ fn generic_simd_intrinsic<'a, 'tcx>( require!(ret_ty == in_elem, "expected return type `{}` (element of input `{}`), found `{}`", in_elem, in_ty, ret_ty); - return Ok(bcx.extract_element(args[0].immediate(), args[1].immediate())) + return Ok(bx.extract_element(args[0].immediate(), args[1].immediate())) } if name == "simd_cast" { @@ -1171,34 +1171,34 @@ fn generic_simd_intrinsic<'a, 'tcx>( match (in_style, out_style) { (Style::Int(in_is_signed), Style::Int(_)) => { return Ok(match in_width.cmp(&out_width) { - Ordering::Greater => bcx.trunc(args[0].immediate(), llret_ty), + Ordering::Greater => bx.trunc(args[0].immediate(), llret_ty), Ordering::Equal => args[0].immediate(), Ordering::Less => if in_is_signed { - bcx.sext(args[0].immediate(), llret_ty) + bx.sext(args[0].immediate(), llret_ty) } else { - bcx.zext(args[0].immediate(), llret_ty) + bx.zext(args[0].immediate(), llret_ty) } }) } (Style::Int(in_is_signed), Style::Float) => { return Ok(if in_is_signed { - bcx.sitofp(args[0].immediate(), llret_ty) + bx.sitofp(args[0].immediate(), llret_ty) } else { - bcx.uitofp(args[0].immediate(), llret_ty) + bx.uitofp(args[0].immediate(), llret_ty) }) } (Style::Float, Style::Int(out_is_signed)) => { return Ok(if out_is_signed { - bcx.fptosi(args[0].immediate(), llret_ty) + bx.fptosi(args[0].immediate(), llret_ty) } else { - bcx.fptoui(args[0].immediate(), llret_ty) + bx.fptoui(args[0].immediate(), llret_ty) }) } (Style::Float, Style::Float) => { return Ok(match in_width.cmp(&out_width) { - Ordering::Greater => bcx.fptrunc(args[0].immediate(), llret_ty), + Ordering::Greater => bx.fptrunc(args[0].immediate(), llret_ty), Ordering::Equal => args[0].immediate(), - Ordering::Less => bcx.fpext(args[0].immediate(), llret_ty) + Ordering::Less => bx.fpext(args[0].immediate(), llret_ty) }) } _ => {/* Unsupported. Fallthrough. */} @@ -1213,7 +1213,7 @@ fn generic_simd_intrinsic<'a, 'tcx>( $(if name == stringify!($name) { match in_elem.sty { $($(ty::$p(_))|* => { - return Ok(bcx.$call(args[0].immediate(), args[1].immediate())) + return Ok(bx.$call(args[0].immediate(), args[1].immediate())) })* _ => {}, } @@ -1243,11 +1243,11 @@ fn generic_simd_intrinsic<'a, 'tcx>( // Returns None if the type is not an integer // FIXME: there’s multiple of this functions, investigate using some of the already existing // stuffs. -fn int_type_width_signed(ty: Ty, ccx: &CrateContext) -> Option<(u64, bool)> { +fn int_type_width_signed(ty: Ty, cx: &CodegenCx) -> Option<(u64, bool)> { match ty.sty { ty::TyInt(t) => Some((match t { ast::IntTy::Isize => { - match &ccx.tcx().sess.target.target.target_pointer_width[..] { + match &cx.tcx.sess.target.target.target_pointer_width[..] { "16" => 16, "32" => 32, "64" => 64, @@ -1262,7 +1262,7 @@ fn int_type_width_signed(ty: Ty, ccx: &CrateContext) -> Option<(u64, bool)> { }, true)), ty::TyUint(t) => Some((match t { ast::UintTy::Usize => { - match &ccx.tcx().sess.target.target.target_pointer_width[..] { + match &cx.tcx.sess.target.target.target_pointer_width[..] { "16" => 16, "32" => 32, "64" => 64, diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 974c268749b..b67997081aa 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -33,6 +33,7 @@ #![feature(rustc_diagnostic_macros)] #![feature(slice_patterns)] #![feature(conservative_impl_trait)] +#![feature(optin_builtin_traits)] use rustc::dep_graph::WorkProduct; use syntax_pos::symbol::Symbol; @@ -66,11 +67,9 @@ extern crate serialize; extern crate cc; // Used to locate MSVC extern crate tempdir; -pub use base::trans_crate; use back::bytecode::RLIB_BYTECODE_EXTENSION; -pub use metadata::LlvmMetadataLoader; -pub use llvm_util::{init, target_features, print_version, print_passes, print}; +pub use llvm_util::{target_features, print_version, print_passes}; use std::any::Any; use std::path::PathBuf; @@ -81,24 +80,24 @@ use rustc::dep_graph::DepGraph; use rustc::hir::def_id::CrateNum; use rustc::middle::cstore::MetadataLoader; use rustc::middle::cstore::{NativeLibrary, CrateSource, LibSource}; -use rustc::session::Session; -use rustc::session::config::{OutputFilenames, OutputType}; +use rustc::session::{Session, CompileIncomplete}; +use rustc::session::config::{OutputFilenames, OutputType, PrintRequest}; use rustc::ty::{self, TyCtxt}; use rustc::util::nodemap::{FxHashSet, FxHashMap}; - use rustc_mir::monomorphize; +use rustc_trans_utils::trans_crate::TransCrate; mod diagnostics; -pub mod back { +mod back { + pub use rustc_trans_utils::symbol_names; mod archive; pub mod bytecode; mod command; - pub(crate) mod linker; + pub mod linker; pub mod link; mod lto; - pub(crate) mod symbol_export; - pub(crate) mod symbol_names; + pub mod symbol_export; pub mod write; mod rpath; } @@ -106,7 +105,6 @@ pub mod back { mod abi; mod allocator; mod asm; -mod assert_module_sources; mod attributes; mod base; mod builder; @@ -139,7 +137,6 @@ mod llvm_util; mod metadata; mod meth; mod mir; -mod symbol_names_test; mod time_graph; mod trans_item; mod type_; @@ -148,57 +145,118 @@ mod value; pub struct LlvmTransCrate(()); +impl !Send for LlvmTransCrate {} // Llvm is on a per-thread basis +impl !Sync for LlvmTransCrate {} + impl LlvmTransCrate { - pub fn new() -> Self { - LlvmTransCrate(()) + pub fn new(sess: &Session) -> Box<TransCrate> { + llvm_util::init(sess); // Make sure llvm is inited + box LlvmTransCrate(()) } } -impl rustc_trans_utils::trans_crate::TransCrate for LlvmTransCrate { - type MetadataLoader = metadata::LlvmMetadataLoader; - type OngoingCrateTranslation = back::write::OngoingCrateTranslation; - type TranslatedCrate = CrateTranslation; +impl TransCrate for LlvmTransCrate { + fn print(&self, req: PrintRequest, sess: &Session) { + match req { + PrintRequest::RelocationModels => { + println!("Available relocation models:"); + for &(name, _) in back::write::RELOC_MODEL_ARGS.iter() { + println!(" {}", name); + } + println!(""); + } + PrintRequest::CodeModels => { + println!("Available code models:"); + for &(name, _) in back::write::CODE_GEN_MODEL_ARGS.iter(){ + println!(" {}", name); + } + println!(""); + } + PrintRequest::TlsModels => { + println!("Available TLS models:"); + for &(name, _) in back::write::TLS_MODEL_ARGS.iter(){ + println!(" {}", name); + } + println!(""); + } + req => llvm_util::print(req, sess), + } + } - fn metadata_loader() -> Box<MetadataLoader> { + fn target_features(&self, sess: &Session) -> Vec<Symbol> { + target_features(sess) + } + + fn metadata_loader(&self) -> Box<MetadataLoader> { box metadata::LlvmMetadataLoader } - fn provide(providers: &mut ty::maps::Providers) { + fn provide(&self, providers: &mut ty::maps::Providers) { back::symbol_names::provide(providers); back::symbol_export::provide(providers); base::provide(providers); attributes::provide(providers); } - fn provide_extern(providers: &mut ty::maps::Providers) { + fn provide_extern(&self, providers: &mut ty::maps::Providers) { back::symbol_export::provide_extern(providers); } fn trans_crate<'a, 'tcx>( + &self, tcx: TyCtxt<'a, 'tcx, 'tcx>, rx: mpsc::Receiver<Box<Any + Send>> - ) -> Self::OngoingCrateTranslation { - base::trans_crate(tcx, rx) + ) -> Box<Any> { + box base::trans_crate(tcx, rx) } - fn join_trans( - trans: Self::OngoingCrateTranslation, + fn join_trans_and_link( + &self, + trans: Box<Any>, sess: &Session, - dep_graph: &DepGraph - ) -> Self::TranslatedCrate { - trans.join(sess, dep_graph) - } + dep_graph: &DepGraph, + outputs: &OutputFilenames, + ) -> Result<(), CompileIncomplete>{ + use rustc::util::common::time; + let trans = trans.downcast::<::back::write::OngoingCrateTranslation>() + .expect("Expected LlvmTransCrate's OngoingCrateTranslation, found Box<Any>") + .join(sess, dep_graph); + if sess.opts.debugging_opts.incremental_info { + back::write::dump_incremental_data(&trans); + } - fn link_binary(sess: &Session, trans: &Self::TranslatedCrate, outputs: &OutputFilenames) { - back::link::link_binary(sess, trans, outputs, &trans.crate_name.as_str()); - } + time(sess.time_passes(), + "serialize work products", + move || rustc_incremental::save_work_products(sess, &dep_graph)); - fn dump_incremental_data(trans: &Self::TranslatedCrate) { - back::write::dump_incremental_data(trans); + sess.compile_status()?; + + if !sess.opts.output_types.keys().any(|&i| i == OutputType::Exe || + i == OutputType::Metadata) { + return Ok(()); + } + + // Run the linker on any artifacts that resulted from the LLVM run. + // This should produce either a finished executable or library. + time(sess.time_passes(), "linking", || { + back::link::link_binary(sess, &trans, outputs, &trans.crate_name.as_str()); + }); + + // Now that we won't touch anything in the incremental compilation directory + // any more, we can finalize it (which involves renaming it) + rustc_incremental::finalize_session_directory(sess, trans.link.crate_hash); + + Ok(()) } } -pub struct ModuleTranslation { +/// This is the entrypoint for a hot plugged rustc_trans +#[no_mangle] +pub fn __rustc_codegen_backend(sess: &Session) -> Box<TransCrate> { + LlvmTransCrate::new(sess) +} + +struct ModuleTranslation { /// The name of the module. When the crate may be saved between /// compilations, incremental compilation requires that name be /// unique amongst **all** crates. Therefore, it should contain @@ -206,26 +264,26 @@ pub struct ModuleTranslation { /// as the crate name and disambiguator. name: String, llmod_id: String, - pub source: ModuleSource, - pub kind: ModuleKind, + source: ModuleSource, + kind: ModuleKind, } #[derive(Copy, Clone, Debug, PartialEq)] -pub enum ModuleKind { +enum ModuleKind { Regular, Metadata, Allocator, } impl ModuleTranslation { - pub fn llvm(&self) -> Option<&ModuleLlvm> { + fn llvm(&self) -> Option<&ModuleLlvm> { match self.source { ModuleSource::Translated(ref llvm) => Some(llvm), ModuleSource::Preexisting(_) => None, } } - pub fn into_compiled_module(self, + fn into_compiled_module(self, emit_obj: bool, emit_bc: bool, emit_bc_compressed: bool, @@ -264,17 +322,17 @@ impl ModuleTranslation { } #[derive(Debug)] -pub struct CompiledModule { - pub name: String, - pub llmod_id: String, - pub kind: ModuleKind, - pub pre_existing: bool, - pub object: Option<PathBuf>, - pub bytecode: Option<PathBuf>, - pub bytecode_compressed: Option<PathBuf>, +struct CompiledModule { + name: String, + llmod_id: String, + kind: ModuleKind, + pre_existing: bool, + object: Option<PathBuf>, + bytecode: Option<PathBuf>, + bytecode_compressed: Option<PathBuf>, } -pub enum ModuleSource { +enum ModuleSource { /// Copy the `.o` files or whatever from the incr. comp. directory. Preexisting(WorkProduct), @@ -283,9 +341,9 @@ pub enum ModuleSource { } #[derive(Debug)] -pub struct ModuleLlvm { +struct ModuleLlvm { llcx: llvm::ContextRef, - pub llmod: llvm::ModuleRef, + llmod: llvm::ModuleRef, tm: llvm::TargetMachineRef, } @@ -302,20 +360,20 @@ impl Drop for ModuleLlvm { } } -pub struct CrateTranslation { - pub crate_name: Symbol, - pub modules: Vec<CompiledModule>, +struct CrateTranslation { + crate_name: Symbol, + modules: Vec<CompiledModule>, allocator_module: Option<CompiledModule>, metadata_module: CompiledModule, - pub link: rustc::middle::cstore::LinkMeta, - pub metadata: rustc::middle::cstore::EncodedMetadata, + link: rustc::middle::cstore::LinkMeta, + metadata: rustc::middle::cstore::EncodedMetadata, windows_subsystem: Option<String>, linker_info: back::linker::LinkerInfo, crate_info: CrateInfo, } // Misc info we load from metadata to persist beyond the tcx -pub struct CrateInfo { +struct CrateInfo { panic_runtime: Option<CrateNum>, compiler_builtins: Option<CrateNum>, profiler_runtime: Option<CrateNum>, diff --git a/src/librustc_trans/llvm_util.rs b/src/librustc_trans/llvm_util.rs index 8112a9eeab1..15988008de2 100644 --- a/src/librustc_trans/llvm_util.rs +++ b/src/librustc_trans/llvm_util.rs @@ -19,11 +19,12 @@ use std::ffi::{CStr, CString}; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Once; -pub fn init(sess: &Session) { +static POISONED: AtomicBool = AtomicBool::new(false); +static INIT: Once = Once::new(); + +pub(crate) fn init(sess: &Session) { unsafe { // Before we touch LLVM, make sure that multithreading is enabled. - static POISONED: AtomicBool = AtomicBool::new(false); - static INIT: Once = Once::new(); INIT.call_once(|| { if llvm::LLVMStartMultithreaded() != 1 { // use an extra bool to make sure that all future usage of LLVM @@ -40,6 +41,13 @@ pub fn init(sess: &Session) { } } +fn require_inited() { + INIT.call_once(|| bug!("llvm is not initialized")); + if POISONED.load(Ordering::SeqCst) { + bug!("couldn't enable multi-threaded LLVM"); + } +} + unsafe fn configure_llvm(sess: &Session) { let mut llvm_c_strs = Vec::new(); let mut llvm_args = Vec::new(); @@ -85,7 +93,8 @@ const X86_WHITELIST: &'static [&'static str] = &["avx\0", "avx2\0", "bmi\0", "bm "avx512dq\0", "avx512er\0", "avx512f\0", "avx512ifma\0", "avx512pf\0", "avx512vbmi\0", - "avx512vl\0", "avx512vpopcntdq\0", "mmx\0"]; + "avx512vl\0", "avx512vpopcntdq\0", + "mmx\0", "fxsr\0"]; const HEXAGON_WHITELIST: &'static [&'static str] = &["hvx\0", "hvx-double\0"]; @@ -124,6 +133,7 @@ pub fn target_feature_whitelist(sess: &Session) -> Vec<&CStr> { } pub fn print_version() { + // Can be called without initializing LLVM unsafe { println!("LLVM version: {}.{}", llvm::LLVMRustVersionMajor(), llvm::LLVMRustVersionMinor()); @@ -131,10 +141,12 @@ pub fn print_version() { } pub fn print_passes() { + // Can be called without initializing LLVM unsafe { llvm::LLVMRustPrintPasses(); } } -pub fn print(req: PrintRequest, sess: &Session) { +pub(crate) fn print(req: PrintRequest, sess: &Session) { + require_inited(); let tm = create_target_machine(sess); unsafe { match req { diff --git a/src/librustc_trans/meth.rs b/src/librustc_trans/meth.rs index 4be2774d3c2..6b542ae2e93 100644 --- a/src/librustc_trans/meth.rs +++ b/src/librustc_trans/meth.rs @@ -33,30 +33,30 @@ impl<'a, 'tcx> VirtualIndex { VirtualIndex(index as u64 + 3) } - pub fn get_fn(self, bcx: &Builder<'a, 'tcx>, + pub fn get_fn(self, bx: &Builder<'a, 'tcx>, llvtable: ValueRef, fn_ty: &FnType<'tcx>) -> ValueRef { // Load the data pointer from the object. debug!("get_fn({:?}, {:?})", Value(llvtable), self); - let llvtable = bcx.pointercast(llvtable, fn_ty.llvm_type(bcx.ccx).ptr_to().ptr_to()); - let ptr_align = bcx.tcx().data_layout.pointer_align; - let ptr = bcx.load(bcx.inbounds_gep(llvtable, &[C_usize(bcx.ccx, self.0)]), ptr_align); - bcx.nonnull_metadata(ptr); + let llvtable = bx.pointercast(llvtable, fn_ty.llvm_type(bx.cx).ptr_to().ptr_to()); + let ptr_align = bx.tcx().data_layout.pointer_align; + let ptr = bx.load(bx.inbounds_gep(llvtable, &[C_usize(bx.cx, self.0)]), ptr_align); + bx.nonnull_metadata(ptr); // Vtable loads are invariant - bcx.set_invariant_load(ptr); + bx.set_invariant_load(ptr); ptr } - pub fn get_usize(self, bcx: &Builder<'a, 'tcx>, llvtable: ValueRef) -> ValueRef { + pub fn get_usize(self, bx: &Builder<'a, 'tcx>, llvtable: ValueRef) -> ValueRef { // Load the data pointer from the object. debug!("get_int({:?}, {:?})", Value(llvtable), self); - let llvtable = bcx.pointercast(llvtable, Type::isize(bcx.ccx).ptr_to()); - let usize_align = bcx.tcx().data_layout.pointer_align; - let ptr = bcx.load(bcx.inbounds_gep(llvtable, &[C_usize(bcx.ccx, self.0)]), usize_align); + let llvtable = bx.pointercast(llvtable, Type::isize(bx.cx).ptr_to()); + let usize_align = bx.tcx().data_layout.pointer_align; + let ptr = bx.load(bx.inbounds_gep(llvtable, &[C_usize(bx.cx, self.0)]), usize_align); // Vtable loads are invariant - bcx.set_invariant_load(ptr); + bx.set_invariant_load(ptr); ptr } } @@ -69,28 +69,28 @@ impl<'a, 'tcx> VirtualIndex { /// The `trait_ref` encodes the erased self type. Hence if we are /// making an object `Foo<Trait>` from a value of type `Foo<T>`, then /// `trait_ref` would map `T:Trait`. -pub fn get_vtable<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, +pub fn get_vtable<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ty: Ty<'tcx>, trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>) -> ValueRef { - let tcx = ccx.tcx(); + let tcx = cx.tcx; debug!("get_vtable(ty={:?}, trait_ref={:?})", ty, trait_ref); // Check the cache. - if let Some(&val) = ccx.vtables().borrow().get(&(ty, trait_ref)) { + if let Some(&val) = cx.vtables.borrow().get(&(ty, trait_ref)) { return val; } // Not in the cache. Build it. - let nullptr = C_null(Type::i8p(ccx)); + let nullptr = C_null(Type::i8p(cx)); - let (size, align) = ccx.size_and_align_of(ty); + let (size, align) = cx.size_and_align_of(ty); let mut components: Vec<_> = [ - callee::get_fn(ccx, monomorphize::resolve_drop_in_place(ccx.tcx(), ty)), - C_usize(ccx, size.bytes()), - C_usize(ccx, align.abi()) + callee::get_fn(cx, monomorphize::resolve_drop_in_place(cx.tcx, ty)), + C_usize(cx, size.bytes()), + C_usize(cx, align.abi()) ].iter().cloned().collect(); if let Some(trait_ref) = trait_ref { @@ -98,18 +98,18 @@ pub fn get_vtable<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let methods = tcx.vtable_methods(trait_ref); let methods = methods.iter().cloned().map(|opt_mth| { opt_mth.map_or(nullptr, |(def_id, substs)| { - callee::resolve_and_get_fn(ccx, def_id, substs) + callee::resolve_and_get_fn(cx, def_id, substs) }) }); components.extend(methods); } - let vtable_const = C_struct(ccx, &components, false); - let align = ccx.data_layout().pointer_align; - let vtable = consts::addr_of(ccx, vtable_const, align, "vtable"); + let vtable_const = C_struct(cx, &components, false); + let align = cx.data_layout().pointer_align; + let vtable = consts::addr_of(cx, vtable_const, align, "vtable"); - debuginfo::create_vtable_metadata(ccx, ty, vtable); + debuginfo::create_vtable_metadata(cx, ty, vtable); - ccx.vtables().borrow_mut().insert((ty, trait_ref), vtable); + cx.vtables.borrow_mut().insert((ty, trait_ref), vtable); vtable } diff --git a/src/librustc_trans/mir/analyze.rs b/src/librustc_trans/mir/analyze.rs index 31cbb07dbe6..bf82e1d50c4 100644 --- a/src/librustc_trans/mir/analyze.rs +++ b/src/librustc_trans/mir/analyze.rs @@ -20,18 +20,18 @@ use rustc::mir::traversal; use rustc::ty; use rustc::ty::layout::LayoutOf; use type_of::LayoutLlvmExt; -use super::MirContext; +use super::FunctionCx; -pub fn memory_locals<'a, 'tcx>(mircx: &MirContext<'a, 'tcx>) -> BitVector { - let mir = mircx.mir; - let mut analyzer = LocalAnalyzer::new(mircx); +pub fn memory_locals<'a, 'tcx>(fx: &FunctionCx<'a, 'tcx>) -> BitVector { + let mir = fx.mir; + let mut analyzer = LocalAnalyzer::new(fx); analyzer.visit_mir(mir); for (index, ty) in mir.local_decls.iter().map(|l| l.ty).enumerate() { - let ty = mircx.monomorphize(&ty); + let ty = fx.monomorphize(&ty); debug!("local {} has type {:?}", index, ty); - let layout = mircx.ccx.layout_of(ty); + let layout = fx.cx.layout_of(ty); if layout.is_llvm_immediate() { // These sorts of types are immediates that we can store // in an ValueRef without an alloca. @@ -52,21 +52,21 @@ pub fn memory_locals<'a, 'tcx>(mircx: &MirContext<'a, 'tcx>) -> BitVector { } struct LocalAnalyzer<'mir, 'a: 'mir, 'tcx: 'a> { - cx: &'mir MirContext<'a, 'tcx>, + fx: &'mir FunctionCx<'a, 'tcx>, memory_locals: BitVector, seen_assigned: BitVector } impl<'mir, 'a, 'tcx> LocalAnalyzer<'mir, 'a, 'tcx> { - fn new(mircx: &'mir MirContext<'a, 'tcx>) -> LocalAnalyzer<'mir, 'a, 'tcx> { + fn new(fx: &'mir FunctionCx<'a, 'tcx>) -> LocalAnalyzer<'mir, 'a, 'tcx> { let mut analyzer = LocalAnalyzer { - cx: mircx, - memory_locals: BitVector::new(mircx.mir.local_decls.len()), - seen_assigned: BitVector::new(mircx.mir.local_decls.len()) + fx, + memory_locals: BitVector::new(fx.mir.local_decls.len()), + seen_assigned: BitVector::new(fx.mir.local_decls.len()) }; // Arguments get assigned to by means of the function being called - for idx in 0..mircx.mir.arg_count { + for idx in 0..fx.mir.arg_count { analyzer.seen_assigned.insert(idx + 1); } @@ -95,7 +95,7 @@ impl<'mir, 'a, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx> { if let mir::Place::Local(index) = *place { self.mark_assigned(index); - if !self.cx.rvalue_creates_operand(rvalue) { + if !self.fx.rvalue_creates_operand(rvalue) { self.mark_as_memory(index); } } else { @@ -117,7 +117,7 @@ impl<'mir, 'a, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx> { }, .. }), ref args, .. - } if Some(def_id) == self.cx.ccx.tcx().lang_items().box_free_fn() => { + } if Some(def_id) == self.fx.cx.tcx.lang_items().box_free_fn() => { // box_free(x) shares with `drop x` the property that it // is not guaranteed to be statically dominated by the // definition of x, so x must always be in an alloca. @@ -136,7 +136,7 @@ impl<'mir, 'a, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx> { context: PlaceContext<'tcx>, location: Location) { debug!("visit_place(place={:?}, context={:?})", place, context); - let ccx = self.cx.ccx; + let cx = self.fx.cx; if let mir::Place::Projection(ref proj) = *place { // Allow uses of projections that are ZSTs or from scalar fields. @@ -145,18 +145,18 @@ impl<'mir, 'a, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx> { _ => false }; if is_consume { - let base_ty = proj.base.ty(self.cx.mir, ccx.tcx()); - let base_ty = self.cx.monomorphize(&base_ty); + let base_ty = proj.base.ty(self.fx.mir, cx.tcx); + let base_ty = self.fx.monomorphize(&base_ty); // ZSTs don't require any actual memory access. - let elem_ty = base_ty.projection_ty(ccx.tcx(), &proj.elem).to_ty(ccx.tcx()); - let elem_ty = self.cx.monomorphize(&elem_ty); - if ccx.layout_of(elem_ty).is_zst() { + let elem_ty = base_ty.projection_ty(cx.tcx, &proj.elem).to_ty(cx.tcx); + let elem_ty = self.fx.monomorphize(&elem_ty); + if cx.layout_of(elem_ty).is_zst() { return; } if let mir::ProjectionElem::Field(..) = proj.elem { - let layout = ccx.layout_of(base_ty.to_ty(ccx.tcx())); + let layout = cx.layout_of(base_ty.to_ty(cx.tcx)); if layout.is_llvm_immediate() || layout.is_llvm_scalar_pair() { // Recurse with the same context, instead of `Projection`, // potentially stopping at non-operand projections, @@ -200,11 +200,11 @@ impl<'mir, 'a, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx> { } PlaceContext::Drop => { - let ty = mir::Place::Local(index).ty(self.cx.mir, self.cx.ccx.tcx()); - let ty = self.cx.monomorphize(&ty.to_ty(self.cx.ccx.tcx())); + let ty = mir::Place::Local(index).ty(self.fx.mir, self.fx.cx.tcx); + let ty = self.fx.monomorphize(&ty.to_ty(self.fx.cx.tcx)); // Only need the place if we're actually dropping it. - if self.cx.ccx.shared().type_needs_drop(ty) { + if self.fx.cx.type_needs_drop(ty) { self.mark_as_memory(index); } } diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index 8c9fb039545..af1e30a4b19 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -29,35 +29,35 @@ use type_::Type; use syntax::symbol::Symbol; use syntax_pos::Pos; -use super::{MirContext, LocalRef}; +use super::{FunctionCx, LocalRef}; use super::constant::Const; use super::place::PlaceRef; use super::operand::OperandRef; use super::operand::OperandValue::{Pair, Ref, Immediate}; -impl<'a, 'tcx> MirContext<'a, 'tcx> { +impl<'a, 'tcx> FunctionCx<'a, 'tcx> { pub fn trans_block(&mut self, bb: mir::BasicBlock) { - let mut bcx = self.get_builder(bb); + let mut bx = self.build_block(bb); let data = &self.mir[bb]; debug!("trans_block({:?}={:?})", bb, data); for statement in &data.statements { - bcx = self.trans_statement(bcx, statement); + bx = self.trans_statement(bx, statement); } - self.trans_terminator(bcx, bb, data.terminator()); + self.trans_terminator(bx, bb, data.terminator()); } fn trans_terminator(&mut self, - mut bcx: Builder<'a, 'tcx>, + mut bx: Builder<'a, 'tcx>, bb: mir::BasicBlock, terminator: &mir::Terminator<'tcx>) { debug!("trans_terminator: {:?}", terminator); // Create the cleanup bundle, if needed. - let tcx = bcx.tcx(); + let tcx = bx.tcx(); let span = terminator.source_info.span; let funclet_bb = self.cleanup_kinds[bb].funclet_bb(bb); let funclet = funclet_bb.and_then(|funclet_bb| self.funclets[funclet_bb].as_ref()); @@ -99,20 +99,20 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { } }; - let funclet_br = |this: &mut Self, bcx: Builder, target: mir::BasicBlock| { + let funclet_br = |this: &mut Self, bx: Builder, target: mir::BasicBlock| { let (lltarget, is_cleanupret) = lltarget(this, target); if is_cleanupret { // micro-optimization: generate a `ret` rather than a jump // to a trampoline. - bcx.cleanup_ret(cleanup_pad.unwrap(), Some(lltarget)); + bx.cleanup_ret(cleanup_pad.unwrap(), Some(lltarget)); } else { - bcx.br(lltarget); + bx.br(lltarget); } }; let do_call = | this: &mut Self, - bcx: Builder<'a, 'tcx>, + bx: Builder<'a, 'tcx>, fn_ty: FnType<'tcx>, fn_ptr: ValueRef, llargs: &[ValueRef], @@ -120,25 +120,25 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { cleanup: Option<mir::BasicBlock> | { if let Some(cleanup) = cleanup { - let ret_bcx = if let Some((_, target)) = destination { + let ret_bx = if let Some((_, target)) = destination { this.blocks[target] } else { this.unreachable_block() }; - let invokeret = bcx.invoke(fn_ptr, + let invokeret = bx.invoke(fn_ptr, &llargs, - ret_bcx, + ret_bx, llblock(this, cleanup), cleanup_bundle); fn_ty.apply_attrs_callsite(invokeret); if let Some((ret_dest, target)) = destination { - let ret_bcx = this.get_builder(target); - this.set_debug_loc(&ret_bcx, terminator.source_info); - this.store_return(&ret_bcx, ret_dest, &fn_ty.ret, invokeret); + let ret_bx = this.build_block(target); + this.set_debug_loc(&ret_bx, terminator.source_info); + this.store_return(&ret_bx, ret_dest, &fn_ty.ret, invokeret); } } else { - let llret = bcx.call(fn_ptr, &llargs, cleanup_bundle); + let llret = bx.call(fn_ptr, &llargs, cleanup_bundle); fn_ty.apply_attrs_callsite(llret); if this.mir[bb].is_cleanup { // Cleanup is always the cold path. Don't inline @@ -149,66 +149,66 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { } if let Some((ret_dest, target)) = destination { - this.store_return(&bcx, ret_dest, &fn_ty.ret, llret); - funclet_br(this, bcx, target); + this.store_return(&bx, ret_dest, &fn_ty.ret, llret); + funclet_br(this, bx, target); } else { - bcx.unreachable(); + bx.unreachable(); } } }; - self.set_debug_loc(&bcx, terminator.source_info); + self.set_debug_loc(&bx, terminator.source_info); match terminator.kind { mir::TerminatorKind::Resume => { if let Some(cleanup_pad) = cleanup_pad { - bcx.cleanup_ret(cleanup_pad, None); + bx.cleanup_ret(cleanup_pad, None); } else { - let slot = self.get_personality_slot(&bcx); - let lp0 = slot.project_field(&bcx, 0).load(&bcx).immediate(); - let lp1 = slot.project_field(&bcx, 1).load(&bcx).immediate(); - slot.storage_dead(&bcx); + let slot = self.get_personality_slot(&bx); + let lp0 = slot.project_field(&bx, 0).load(&bx).immediate(); + let lp1 = slot.project_field(&bx, 1).load(&bx).immediate(); + slot.storage_dead(&bx); - if !bcx.sess().target.target.options.custom_unwind_resume { + if !bx.sess().target.target.options.custom_unwind_resume { let mut lp = C_undef(self.landing_pad_type()); - lp = bcx.insert_value(lp, lp0, 0); - lp = bcx.insert_value(lp, lp1, 1); - bcx.resume(lp); + lp = bx.insert_value(lp, lp0, 0); + lp = bx.insert_value(lp, lp1, 1); + bx.resume(lp); } else { - bcx.call(bcx.ccx.eh_unwind_resume(), &[lp0], cleanup_bundle); - bcx.unreachable(); + bx.call(bx.cx.eh_unwind_resume(), &[lp0], cleanup_bundle); + bx.unreachable(); } } } mir::TerminatorKind::Abort => { // Call core::intrinsics::abort() - let fnname = bcx.ccx.get_intrinsic(&("llvm.trap")); - bcx.call(fnname, &[], None); - bcx.unreachable(); + let fnname = bx.cx.get_intrinsic(&("llvm.trap")); + bx.call(fnname, &[], None); + bx.unreachable(); } mir::TerminatorKind::Goto { target } => { - funclet_br(self, bcx, target); + funclet_br(self, bx, target); } mir::TerminatorKind::SwitchInt { ref discr, switch_ty, ref values, ref targets } => { - let discr = self.trans_operand(&bcx, discr); - if switch_ty == bcx.tcx().types.bool { + let discr = self.trans_operand(&bx, discr); + if switch_ty == bx.tcx().types.bool { let lltrue = llblock(self, targets[0]); let llfalse = llblock(self, targets[1]); if let [ConstInt::U8(0)] = values[..] { - bcx.cond_br(discr.immediate(), llfalse, lltrue); + bx.cond_br(discr.immediate(), llfalse, lltrue); } else { - bcx.cond_br(discr.immediate(), lltrue, llfalse); + bx.cond_br(discr.immediate(), lltrue, llfalse); } } else { let (otherwise, targets) = targets.split_last().unwrap(); - let switch = bcx.switch(discr.immediate(), + let switch = bx.switch(discr.immediate(), llblock(self, *otherwise), values.len()); for (value, target) in values.iter().zip(targets) { - let val = Const::from_constint(bcx.ccx, value); + let val = Const::from_constint(bx.cx, value); let llbb = llblock(self, *target); - bcx.add_case(switch, val.llval, llbb) + bx.add_case(switch, val.llval, llbb) } } } @@ -216,16 +216,16 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { mir::TerminatorKind::Return => { let llval = match self.fn_ty.ret.mode { PassMode::Ignore | PassMode::Indirect(_) => { - bcx.ret_void(); + bx.ret_void(); return; } PassMode::Direct(_) | PassMode::Pair(..) => { - let op = self.trans_consume(&bcx, &mir::Place::Local(mir::RETURN_PLACE)); + let op = self.trans_consume(&bx, &mir::Place::Local(mir::RETURN_PLACE)); if let Ref(llval, align) = op.val { - bcx.load(llval, align) + bx.load(llval, align) } else { - op.immediate_or_packed_pair(&bcx) + op.immediate_or_packed_pair(&bx) } } @@ -242,8 +242,8 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { }; let llslot = match op.val { Immediate(_) | Pair(..) => { - let scratch = PlaceRef::alloca(&bcx, self.fn_ty.ret.layout, "ret"); - op.val.store(&bcx, scratch); + let scratch = PlaceRef::alloca(&bx, self.fn_ty.ret.layout, "ret"); + op.val.store(&bx, scratch); scratch.llval } Ref(llval, align) => { @@ -252,53 +252,53 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { llval } }; - bcx.load( - bcx.pointercast(llslot, cast_ty.llvm_type(bcx.ccx).ptr_to()), + bx.load( + bx.pointercast(llslot, cast_ty.llvm_type(bx.cx).ptr_to()), self.fn_ty.ret.layout.align) } }; - bcx.ret(llval); + bx.ret(llval); } mir::TerminatorKind::Unreachable => { - bcx.unreachable(); + bx.unreachable(); } mir::TerminatorKind::Drop { ref location, target, unwind } => { - let ty = location.ty(self.mir, bcx.tcx()).to_ty(bcx.tcx()); + let ty = location.ty(self.mir, bx.tcx()).to_ty(bx.tcx()); let ty = self.monomorphize(&ty); - let drop_fn = monomorphize::resolve_drop_in_place(bcx.ccx.tcx(), ty); + let drop_fn = monomorphize::resolve_drop_in_place(bx.cx.tcx, ty); if let ty::InstanceDef::DropGlue(_, None) = drop_fn.def { // we don't actually need to drop anything. - funclet_br(self, bcx, target); + funclet_br(self, bx, target); return } - let place = self.trans_place(&bcx, location); + let place = self.trans_place(&bx, location); let mut args: &[_] = &[place.llval, place.llextra]; args = &args[..1 + place.has_extra() as usize]; let (drop_fn, fn_ty) = match ty.sty { ty::TyDynamic(..) => { - let fn_ty = drop_fn.ty(bcx.ccx.tcx()); - let sig = common::ty_fn_sig(bcx.ccx, fn_ty); - let sig = bcx.tcx().erase_late_bound_regions_and_normalize(&sig); - let fn_ty = FnType::new_vtable(bcx.ccx, sig, &[]); + let fn_ty = drop_fn.ty(bx.cx.tcx); + let sig = common::ty_fn_sig(bx.cx, fn_ty); + let sig = bx.tcx().erase_late_bound_regions_and_normalize(&sig); + let fn_ty = FnType::new_vtable(bx.cx, sig, &[]); args = &args[..1]; - (meth::DESTRUCTOR.get_fn(&bcx, place.llextra, &fn_ty), fn_ty) + (meth::DESTRUCTOR.get_fn(&bx, place.llextra, &fn_ty), fn_ty) } _ => { - (callee::get_fn(bcx.ccx, drop_fn), - FnType::of_instance(bcx.ccx, &drop_fn)) + (callee::get_fn(bx.cx, drop_fn), + FnType::of_instance(bx.cx, &drop_fn)) } }; - do_call(self, bcx, fn_ty, drop_fn, args, + do_call(self, bx, fn_ty, drop_fn, args, Some((ReturnDest::Nothing, target)), unwind); } mir::TerminatorKind::Assert { ref cond, expected, ref msg, target, cleanup } => { - let cond = self.trans_operand(&bcx, cond).immediate(); + let cond = self.trans_operand(&bx, cond).immediate(); let mut const_cond = common::const_to_opt_u128(cond, false).map(|c| c == 1); // This case can currently arise only from functions marked @@ -308,7 +308,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { // NOTE: Unlike binops, negation doesn't have its own // checked operation, just a comparison with the minimum // value, so we have to check for the assert message. - if !bcx.ccx.check_overflow() { + if !bx.cx.check_overflow { use rustc_const_math::ConstMathErr::Overflow; use rustc_const_math::Op::Neg; @@ -319,33 +319,33 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { // Don't translate the panic block if success if known. if const_cond == Some(expected) { - funclet_br(self, bcx, target); + funclet_br(self, bx, target); return; } // Pass the condition through llvm.expect for branch hinting. - let expect = bcx.ccx.get_intrinsic(&"llvm.expect.i1"); - let cond = bcx.call(expect, &[cond, C_bool(bcx.ccx, expected)], None); + let expect = bx.cx.get_intrinsic(&"llvm.expect.i1"); + let cond = bx.call(expect, &[cond, C_bool(bx.cx, expected)], None); // Create the failure block and the conditional branch to it. let lltarget = llblock(self, target); let panic_block = self.new_block("panic"); if expected { - bcx.cond_br(cond, lltarget, panic_block.llbb()); + bx.cond_br(cond, lltarget, panic_block.llbb()); } else { - bcx.cond_br(cond, panic_block.llbb(), lltarget); + bx.cond_br(cond, panic_block.llbb(), lltarget); } - // After this point, bcx is the block for the call to panic. - bcx = panic_block; - self.set_debug_loc(&bcx, terminator.source_info); + // After this point, bx is the block for the call to panic. + bx = panic_block; + self.set_debug_loc(&bx, terminator.source_info); // Get the location information. - let loc = bcx.sess().codemap().lookup_char_pos(span.lo()); + let loc = bx.sess().codemap().lookup_char_pos(span.lo()); let filename = Symbol::intern(&loc.file.name.to_string()).as_str(); - let filename = C_str_slice(bcx.ccx, filename); - let line = C_u32(bcx.ccx, loc.line as u32); - let col = C_u32(bcx.ccx, loc.col.to_usize() as u32 + 1); + let filename = C_str_slice(bx.cx, filename); + let line = C_u32(bx.cx, loc.line as u32); + let col = C_u32(bx.cx, 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); @@ -353,8 +353,8 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { // Put together the arguments to the panic entry point. let (lang_item, args, const_err) = match *msg { mir::AssertMessage::BoundsCheck { ref len, ref index } => { - let len = self.trans_operand(&mut bcx, len).immediate(); - let index = self.trans_operand(&mut bcx, index).immediate(); + let len = self.trans_operand(&mut bx, len).immediate(); + let index = self.trans_operand(&mut bx, index).immediate(); let const_err = common::const_to_opt_u128(len, false) .and_then(|len| common::const_to_opt_u128(index, false) @@ -363,8 +363,8 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { index: index as u64 })); - let file_line_col = C_struct(bcx.ccx, &[filename, line, col], false); - let file_line_col = consts::addr_of(bcx.ccx, + let file_line_col = C_struct(bx.cx, &[filename, line, col], false); + let file_line_col = consts::addr_of(bx.cx, file_line_col, align, "panic_bounds_check_loc"); @@ -374,11 +374,11 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { } mir::AssertMessage::Math(ref err) => { let msg_str = Symbol::intern(err.description()).as_str(); - let msg_str = C_str_slice(bcx.ccx, msg_str); - let msg_file_line_col = C_struct(bcx.ccx, + let msg_str = C_str_slice(bx.cx, msg_str); + let msg_file_line_col = C_struct(bx.cx, &[msg_str, filename, line, col], false); - let msg_file_line_col = consts::addr_of(bcx.ccx, + let msg_file_line_col = consts::addr_of(bx.cx, msg_file_line_col, align, "panic_loc"); @@ -394,11 +394,11 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { "generator resumed after panicking" }; let msg_str = Symbol::intern(str).as_str(); - let msg_str = C_str_slice(bcx.ccx, msg_str); - let msg_file_line_col = C_struct(bcx.ccx, + let msg_str = C_str_slice(bx.cx, msg_str); + let msg_file_line_col = C_struct(bx.cx, &[msg_str, filename, line, col], false); - let msg_file_line_col = consts::addr_of(bcx.ccx, + let msg_file_line_col = consts::addr_of(bx.cx, msg_file_line_col, align, "panic_loc"); @@ -413,21 +413,21 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { if const_cond == Some(!expected) { if let Some(err) = const_err { let err = ConstEvalErr{ span: span, kind: err }; - let mut diag = bcx.tcx().sess.struct_span_warn( + let mut diag = bx.tcx().sess.struct_span_warn( span, "this expression will panic at run-time"); - err.note(bcx.tcx(), span, "expression", &mut diag); + err.note(bx.tcx(), span, "expression", &mut diag); diag.emit(); } } // Obtain the panic entry point. - let def_id = common::langcall(bcx.tcx(), Some(span), "", lang_item); - let instance = ty::Instance::mono(bcx.tcx(), def_id); - let fn_ty = FnType::of_instance(bcx.ccx, &instance); - let llfn = callee::get_fn(bcx.ccx, instance); + let def_id = common::langcall(bx.tcx(), Some(span), "", lang_item); + let instance = ty::Instance::mono(bx.tcx(), def_id); + let fn_ty = FnType::of_instance(bx.cx, &instance); + let llfn = callee::get_fn(bx.cx, instance); // Translate the actual panic invoke/call. - do_call(self, bcx, fn_ty, llfn, &args, None, cleanup); + do_call(self, bx, fn_ty, llfn, &args, None, cleanup); } mir::TerminatorKind::DropAndReplace { .. } => { @@ -436,11 +436,11 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { mir::TerminatorKind::Call { ref func, ref args, ref destination, cleanup } => { // Create the callee. This is a fn ptr or zero-sized and hence a kind of scalar. - let callee = self.trans_operand(&bcx, func); + let callee = self.trans_operand(&bx, func); let (instance, mut llfn) = match callee.layout.ty.sty { ty::TyFnDef(def_id, substs) => { - (Some(ty::Instance::resolve(bcx.ccx.tcx(), + (Some(ty::Instance::resolve(bx.cx.tcx, ty::ParamEnv::empty(traits::Reveal::All), def_id, substs).unwrap()), @@ -452,42 +452,42 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { _ => bug!("{} is not callable", callee.layout.ty) }; let def = instance.map(|i| i.def); - let sig = callee.layout.ty.fn_sig(bcx.tcx()); - let sig = bcx.tcx().erase_late_bound_regions_and_normalize(&sig); + let sig = callee.layout.ty.fn_sig(bx.tcx()); + let sig = bx.tcx().erase_late_bound_regions_and_normalize(&sig); let abi = sig.abi; // Handle intrinsics old trans wants Expr's for, ourselves. let intrinsic = match def { Some(ty::InstanceDef::Intrinsic(def_id)) - => Some(bcx.tcx().item_name(def_id)), + => Some(bx.tcx().item_name(def_id)), _ => None }; let intrinsic = intrinsic.as_ref().map(|s| &s[..]); if intrinsic == Some("transmute") { let &(ref dest, target) = destination.as_ref().unwrap(); - self.trans_transmute(&bcx, &args[0], dest); - funclet_br(self, bcx, target); + self.trans_transmute(&bx, &args[0], dest); + funclet_br(self, bx, target); return; } let extra_args = &args[sig.inputs().len()..]; let extra_args = extra_args.iter().map(|op_arg| { - let op_ty = op_arg.ty(self.mir, bcx.tcx()); + let op_ty = op_arg.ty(self.mir, bx.tcx()); self.monomorphize(&op_ty) }).collect::<Vec<_>>(); let fn_ty = match def { Some(ty::InstanceDef::Virtual(..)) => { - FnType::new_vtable(bcx.ccx, sig, &extra_args) + FnType::new_vtable(bx.cx, sig, &extra_args) } Some(ty::InstanceDef::DropGlue(_, None)) => { // empty drop glue - a nop. let &(_, target) = destination.as_ref().unwrap(); - funclet_br(self, bcx, target); + funclet_br(self, bx, target); return; } - _ => FnType::new(bcx.ccx, sig, &extra_args) + _ => FnType::new(bx.cx, sig, &extra_args) }; // The arguments we'll be passing. Plus one to account for outptr, if used. @@ -497,7 +497,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { // Prepare the return value destination let ret_dest = if let Some((ref dest, _)) = *destination { let is_intrinsic = intrinsic.is_some(); - self.make_return_dest(&bcx, dest, &fn_ty.ret, &mut llargs, + self.make_return_dest(&bx, dest, &fn_ty.ret, &mut llargs, is_intrinsic) } else { ReturnDest::Nothing @@ -509,7 +509,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { let dest = match ret_dest { _ if fn_ty.ret.is_indirect() => llargs[0], ReturnDest::Nothing => { - C_undef(fn_ty.ret.memory_ty(bcx.ccx).ptr_to()) + C_undef(fn_ty.ret.memory_ty(bx.cx).ptr_to()) } ReturnDest::IndirectOperand(dst, _) | ReturnDest::Store(dst) => dst.llval, @@ -529,31 +529,31 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { span_bug!(span, "shuffle indices must be constant"); } mir::Operand::Constant(ref constant) => { - let val = self.trans_constant(&bcx, constant); + let val = self.trans_constant(&bx, constant); return OperandRef { val: Immediate(val.llval), - layout: bcx.ccx.layout_of(val.ty) + layout: bx.cx.layout_of(val.ty) }; } } } - self.trans_operand(&bcx, arg) + self.trans_operand(&bx, arg) }).collect(); - let callee_ty = instance.as_ref().unwrap().ty(bcx.ccx.tcx()); - trans_intrinsic_call(&bcx, callee_ty, &fn_ty, &args, dest, + let callee_ty = instance.as_ref().unwrap().ty(bx.cx.tcx); + trans_intrinsic_call(&bx, callee_ty, &fn_ty, &args, dest, terminator.source_info.span); if let ReturnDest::IndirectOperand(dst, _) = ret_dest { - self.store_return(&bcx, ret_dest, &fn_ty.ret, dst.llval); + self.store_return(&bx, ret_dest, &fn_ty.ret, dst.llval); } if let Some((_, target)) = *destination { - funclet_br(self, bcx, target); + funclet_br(self, bx, target); } else { - bcx.unreachable(); + bx.unreachable(); } return; @@ -568,11 +568,11 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { }; for (i, arg) in first_args.iter().enumerate() { - let mut op = self.trans_operand(&bcx, arg); + let mut op = self.trans_operand(&bx, arg); if let (0, Some(ty::InstanceDef::Virtual(_, idx))) = (i, def) { if let Pair(data_ptr, meta) = op.val { llfn = Some(meth::VirtualIndex::from_index(idx) - .get_fn(&bcx, meta, &fn_ty)); + .get_fn(&bx, meta, &fn_ty)); llargs.push(data_ptr); continue; } @@ -583,27 +583,27 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { match (arg, op.val) { (&mir::Operand::Copy(_), Ref(..)) | (&mir::Operand::Constant(_), Ref(..)) => { - let tmp = PlaceRef::alloca(&bcx, op.layout, "const"); - op.val.store(&bcx, tmp); + let tmp = PlaceRef::alloca(&bx, op.layout, "const"); + op.val.store(&bx, tmp); op.val = Ref(tmp.llval, tmp.align); } _ => {} } - self.trans_argument(&bcx, op, &mut llargs, &fn_ty.args[i]); + self.trans_argument(&bx, op, &mut llargs, &fn_ty.args[i]); } if let Some(tup) = untuple { - self.trans_arguments_untupled(&bcx, tup, &mut llargs, + self.trans_arguments_untupled(&bx, tup, &mut llargs, &fn_ty.args[first_args.len()..]) } let fn_ptr = match (llfn, instance) { (Some(llfn), _) => llfn, - (None, Some(instance)) => callee::get_fn(bcx.ccx, instance), + (None, Some(instance)) => callee::get_fn(bx.cx, instance), _ => span_bug!(span, "no llfn for call"), }; - do_call(self, bcx, fn_ty, fn_ptr, &llargs, + do_call(self, bx, fn_ty, fn_ptr, &llargs, destination.as_ref().map(|&(_, target)| (ret_dest, target)), cleanup); } @@ -614,13 +614,13 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { } fn trans_argument(&mut self, - bcx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'tcx>, op: OperandRef<'tcx>, llargs: &mut Vec<ValueRef>, arg: &ArgType<'tcx>) { // Fill padding with undef value, where applicable. if let Some(ty) = arg.pad { - llargs.push(C_undef(ty.llvm_type(bcx.ccx))); + llargs.push(C_undef(ty.llvm_type(bx.cx))); } if arg.is_ignore() { @@ -643,12 +643,12 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { Immediate(_) | Pair(..) => { match arg.mode { PassMode::Indirect(_) | PassMode::Cast(_) => { - let scratch = PlaceRef::alloca(bcx, arg.layout, "arg"); - op.val.store(bcx, scratch); + let scratch = PlaceRef::alloca(bx, arg.layout, "arg"); + op.val.store(bx, scratch); (scratch.llval, scratch.align, true) } _ => { - (op.immediate_or_packed_pair(bcx), arg.layout.align, false) + (op.immediate_or_packed_pair(bx), arg.layout.align, false) } } } @@ -658,8 +658,8 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { // think that ATM (Rust 1.16) we only pass temporaries, but we shouldn't // have scary latent bugs around. - let scratch = PlaceRef::alloca(bcx, arg.layout, "arg"); - base::memcpy_ty(bcx, scratch.llval, llval, op.layout, align); + let scratch = PlaceRef::alloca(bx, arg.layout, "arg"); + base::memcpy_ty(bx, scratch.llval, llval, op.layout, align); (scratch.llval, scratch.align, true) } else { (llval, align, true) @@ -670,7 +670,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { if by_ref && !arg.is_indirect() { // Have to load the argument, maybe while casting it. if let PassMode::Cast(ty) = arg.mode { - llval = bcx.load(bcx.pointercast(llval, ty.llvm_type(bcx.ccx).ptr_to()), + llval = bx.load(bx.pointercast(llval, ty.llvm_type(bx.cx).ptr_to()), align.min(arg.layout.align)); } else { // We can't use `PlaceRef::load` here because the argument @@ -678,14 +678,14 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { // used for this call is passing it by-value. In that case, // the load would just produce `OperandValue::Ref` instead // of the `OperandValue::Immediate` we need for the call. - llval = bcx.load(llval, align); + llval = bx.load(llval, align); if let layout::Abi::Scalar(ref scalar) = arg.layout.abi { if scalar.is_bool() { - bcx.range_metadata(llval, 0..2); + bx.range_metadata(llval, 0..2); } } // We store bools as i8 so we need to truncate to i1. - llval = base::to_immediate(bcx, llval, arg.layout); + llval = base::to_immediate(bx, llval, arg.layout); } } @@ -693,38 +693,38 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { } fn trans_arguments_untupled(&mut self, - bcx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'tcx>, operand: &mir::Operand<'tcx>, llargs: &mut Vec<ValueRef>, args: &[ArgType<'tcx>]) { - let tuple = self.trans_operand(bcx, operand); + let tuple = self.trans_operand(bx, operand); // Handle both by-ref and immediate tuples. if let Ref(llval, align) = tuple.val { let tuple_ptr = PlaceRef::new_sized(llval, tuple.layout, align); for i in 0..tuple.layout.fields.count() { - let field_ptr = tuple_ptr.project_field(bcx, i); - self.trans_argument(bcx, field_ptr.load(bcx), llargs, &args[i]); + let field_ptr = tuple_ptr.project_field(bx, i); + self.trans_argument(bx, field_ptr.load(bx), llargs, &args[i]); } } else { // If the tuple is immediate, the elements are as well. for i in 0..tuple.layout.fields.count() { - let op = tuple.extract_field(bcx, i); - self.trans_argument(bcx, op, llargs, &args[i]); + let op = tuple.extract_field(bx, i); + self.trans_argument(bx, op, llargs, &args[i]); } } } - fn get_personality_slot(&mut self, bcx: &Builder<'a, 'tcx>) -> PlaceRef<'tcx> { - let ccx = bcx.ccx; + fn get_personality_slot(&mut self, bx: &Builder<'a, 'tcx>) -> PlaceRef<'tcx> { + let cx = bx.cx; if let Some(slot) = self.personality_slot { slot } else { - let layout = ccx.layout_of(ccx.tcx().intern_tup(&[ - ccx.tcx().mk_mut_ptr(ccx.tcx().types.u8), - ccx.tcx().types.i32 + let layout = cx.layout_of(cx.tcx.intern_tup(&[ + cx.tcx.mk_mut_ptr(cx.tcx.types.u8), + cx.tcx.types.i32 ], false)); - let slot = PlaceRef::alloca(bcx, layout, "personalityslot"); + let slot = PlaceRef::alloca(bx, layout, "personalityslot"); self.personality_slot = Some(slot); slot } @@ -745,28 +745,28 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { } fn landing_pad_uncached(&mut self, target_bb: BasicBlockRef) -> BasicBlockRef { - if base::wants_msvc_seh(self.ccx.sess()) { + if base::wants_msvc_seh(self.cx.sess()) { span_bug!(self.mir.span, "landing pad was not inserted?") } - let bcx = self.new_block("cleanup"); + let bx = self.new_block("cleanup"); - let llpersonality = self.ccx.eh_personality(); + let llpersonality = self.cx.eh_personality(); let llretty = self.landing_pad_type(); - let lp = bcx.landing_pad(llretty, llpersonality, 1); - bcx.set_cleanup(lp); + let lp = bx.landing_pad(llretty, llpersonality, 1); + bx.set_cleanup(lp); - let slot = self.get_personality_slot(&bcx); - slot.storage_live(&bcx); - Pair(bcx.extract_value(lp, 0), bcx.extract_value(lp, 1)).store(&bcx, slot); + let slot = self.get_personality_slot(&bx); + slot.storage_live(&bx); + Pair(bx.extract_value(lp, 0), bx.extract_value(lp, 1)).store(&bx, slot); - bcx.br(target_bb); - bcx.llbb() + bx.br(target_bb); + bx.llbb() } fn landing_pad_type(&self) -> Type { - let ccx = self.ccx; - Type::struct_(ccx, &[Type::i8p(ccx), Type::i32(ccx)], false) + let cx = self.cx; + Type::struct_(cx, &[Type::i8p(cx), Type::i32(cx)], false) } fn unreachable_block(&mut self) -> BasicBlockRef { @@ -779,16 +779,16 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { } pub fn new_block(&self, name: &str) -> Builder<'a, 'tcx> { - Builder::new_block(self.ccx, self.llfn, name) + Builder::new_block(self.cx, self.llfn, name) } - pub fn get_builder(&self, bb: mir::BasicBlock) -> Builder<'a, 'tcx> { - let builder = Builder::with_ccx(self.ccx); - builder.position_at_end(self.blocks[bb]); - builder + pub fn build_block(&self, bb: mir::BasicBlock) -> Builder<'a, 'tcx> { + let bx = Builder::with_cx(self.cx); + bx.position_at_end(self.blocks[bb]); + bx } - fn make_return_dest(&mut self, bcx: &Builder<'a, 'tcx>, + fn make_return_dest(&mut self, bx: &Builder<'a, 'tcx>, dest: &mir::Place<'tcx>, fn_ret: &ArgType<'tcx>, llargs: &mut Vec<ValueRef>, is_intrinsic: bool) -> ReturnDest<'tcx> { @@ -805,16 +805,16 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { return if fn_ret.is_indirect() { // Odd, but possible, case, we have an operand temporary, // but the calling convention has an indirect return. - let tmp = PlaceRef::alloca(bcx, fn_ret.layout, "tmp_ret"); - tmp.storage_live(bcx); + let tmp = PlaceRef::alloca(bx, fn_ret.layout, "tmp_ret"); + tmp.storage_live(bx); llargs.push(tmp.llval); ReturnDest::IndirectOperand(tmp, index) } else if is_intrinsic { // Currently, intrinsics always need a location to store // the result. so we create a temporary alloca for the // result - let tmp = PlaceRef::alloca(bcx, fn_ret.layout, "tmp_ret"); - tmp.storage_live(bcx); + let tmp = PlaceRef::alloca(bx, fn_ret.layout, "tmp_ret"); + tmp.storage_live(bx); ReturnDest::IndirectOperand(tmp, index) } else { ReturnDest::DirectOperand(index) @@ -825,7 +825,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { } } } else { - self.trans_place(bcx, dest) + self.trans_place(bx, dest) }; if fn_ret.is_indirect() { if dest.align.abi() < dest.layout.align.abi() { @@ -844,20 +844,20 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { } } - fn trans_transmute(&mut self, bcx: &Builder<'a, 'tcx>, + fn trans_transmute(&mut self, bx: &Builder<'a, 'tcx>, src: &mir::Operand<'tcx>, dst: &mir::Place<'tcx>) { if let mir::Place::Local(index) = *dst { match self.locals[index] { - LocalRef::Place(place) => self.trans_transmute_into(bcx, src, place), + LocalRef::Place(place) => self.trans_transmute_into(bx, src, place), LocalRef::Operand(None) => { - let dst_layout = bcx.ccx.layout_of(self.monomorphized_place_ty(dst)); + let dst_layout = bx.cx.layout_of(self.monomorphized_place_ty(dst)); assert!(!dst_layout.ty.has_erasable_regions()); - let place = PlaceRef::alloca(bcx, dst_layout, "transmute_temp"); - place.storage_live(bcx); - self.trans_transmute_into(bcx, src, place); - let op = place.load(bcx); - place.storage_dead(bcx); + let place = PlaceRef::alloca(bx, dst_layout, "transmute_temp"); + place.storage_live(bx); + self.trans_transmute_into(bx, src, place); + let op = place.load(bx); + place.storage_dead(bx); self.locals[index] = LocalRef::Operand(Some(op)); } LocalRef::Operand(Some(op)) => { @@ -866,25 +866,25 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { } } } else { - let dst = self.trans_place(bcx, dst); - self.trans_transmute_into(bcx, src, dst); + let dst = self.trans_place(bx, dst); + self.trans_transmute_into(bx, src, dst); } } - fn trans_transmute_into(&mut self, bcx: &Builder<'a, 'tcx>, + fn trans_transmute_into(&mut self, bx: &Builder<'a, 'tcx>, src: &mir::Operand<'tcx>, dst: PlaceRef<'tcx>) { - let src = self.trans_operand(bcx, src); - let llty = src.layout.llvm_type(bcx.ccx); - let cast_ptr = bcx.pointercast(dst.llval, llty.ptr_to()); + let src = self.trans_operand(bx, src); + let llty = src.layout.llvm_type(bx.cx); + let cast_ptr = bx.pointercast(dst.llval, llty.ptr_to()); let align = src.layout.align.min(dst.layout.align); - src.val.store(bcx, PlaceRef::new_sized(cast_ptr, src.layout, align)); + src.val.store(bx, PlaceRef::new_sized(cast_ptr, src.layout, align)); } // Stores the return value of a function call into it's final location. fn store_return(&mut self, - bcx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'tcx>, dest: ReturnDest<'tcx>, ret_ty: &ArgType<'tcx>, llval: ValueRef) { @@ -892,23 +892,23 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { match dest { Nothing => (), - Store(dst) => ret_ty.store(bcx, llval, dst), + Store(dst) => ret_ty.store(bx, llval, dst), IndirectOperand(tmp, index) => { - let op = tmp.load(bcx); - tmp.storage_dead(bcx); + let op = tmp.load(bx); + tmp.storage_dead(bx); self.locals[index] = LocalRef::Operand(Some(op)); } DirectOperand(index) => { // If there is a cast, we have to store and reload. let op = if let PassMode::Cast(_) = ret_ty.mode { - let tmp = PlaceRef::alloca(bcx, ret_ty.layout, "tmp_ret"); - tmp.storage_live(bcx); - ret_ty.store(bcx, llval, tmp); - let op = tmp.load(bcx); - tmp.storage_dead(bcx); + let tmp = PlaceRef::alloca(bx, ret_ty.layout, "tmp_ret"); + tmp.storage_live(bx); + ret_ty.store(bx, llval, tmp); + let op = tmp.load(bx); + tmp.storage_dead(bx); op } else { - OperandRef::from_immediate_or_packed_pair(bcx, llval, ret_ty.layout) + OperandRef::from_immediate_or_packed_pair(bx, llval, ret_ty.layout) }; self.locals[index] = LocalRef::Operand(Some(op)); } diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs index aa640d3da3c..71ce0aa3da9 100644 --- a/src/librustc_trans/mir/constant.rs +++ b/src/librustc_trans/mir/constant.rs @@ -27,7 +27,7 @@ use base; use abi::{self, Abi}; use callee; use builder::Builder; -use common::{self, CrateContext, const_get_elt, val_ty}; +use common::{self, CodegenCx, const_get_elt, val_ty}; use common::{C_array, C_bool, C_bytes, C_int, C_uint, C_uint_big, C_u32, C_u64}; use common::{C_null, C_struct, C_str_slice, C_undef, C_usize, C_vector, C_fat_ptr}; use common::const_to_opt_u128; @@ -43,7 +43,7 @@ use std::fmt; use std::ptr; use super::operand::{OperandRef, OperandValue}; -use super::MirContext; +use super::FunctionCx; /// A sized constant rvalue. /// The LLVM type might not be the same for a single Rust type, @@ -62,46 +62,46 @@ impl<'a, 'tcx> Const<'tcx> { } } - pub fn from_constint(ccx: &CrateContext<'a, 'tcx>, ci: &ConstInt) -> Const<'tcx> { - let tcx = ccx.tcx(); + pub fn from_constint(cx: &CodegenCx<'a, 'tcx>, ci: &ConstInt) -> Const<'tcx> { + let tcx = cx.tcx; let (llval, ty) = match *ci { - I8(v) => (C_int(Type::i8(ccx), v as i64), tcx.types.i8), - I16(v) => (C_int(Type::i16(ccx), v as i64), tcx.types.i16), - I32(v) => (C_int(Type::i32(ccx), v as i64), tcx.types.i32), - I64(v) => (C_int(Type::i64(ccx), v as i64), tcx.types.i64), - I128(v) => (C_uint_big(Type::i128(ccx), v as u128), tcx.types.i128), - Isize(v) => (C_int(Type::isize(ccx), v.as_i64()), tcx.types.isize), - U8(v) => (C_uint(Type::i8(ccx), v as u64), tcx.types.u8), - U16(v) => (C_uint(Type::i16(ccx), v as u64), tcx.types.u16), - U32(v) => (C_uint(Type::i32(ccx), v as u64), tcx.types.u32), - U64(v) => (C_uint(Type::i64(ccx), v), tcx.types.u64), - U128(v) => (C_uint_big(Type::i128(ccx), v), tcx.types.u128), - Usize(v) => (C_uint(Type::isize(ccx), v.as_u64()), tcx.types.usize), + I8(v) => (C_int(Type::i8(cx), v as i64), tcx.types.i8), + I16(v) => (C_int(Type::i16(cx), v as i64), tcx.types.i16), + I32(v) => (C_int(Type::i32(cx), v as i64), tcx.types.i32), + I64(v) => (C_int(Type::i64(cx), v as i64), tcx.types.i64), + I128(v) => (C_uint_big(Type::i128(cx), v as u128), tcx.types.i128), + Isize(v) => (C_int(Type::isize(cx), v.as_i64()), tcx.types.isize), + U8(v) => (C_uint(Type::i8(cx), v as u64), tcx.types.u8), + U16(v) => (C_uint(Type::i16(cx), v as u64), tcx.types.u16), + U32(v) => (C_uint(Type::i32(cx), v as u64), tcx.types.u32), + U64(v) => (C_uint(Type::i64(cx), v), tcx.types.u64), + U128(v) => (C_uint_big(Type::i128(cx), v), tcx.types.u128), + Usize(v) => (C_uint(Type::isize(cx), v.as_u64()), tcx.types.usize), }; Const { llval: llval, ty: ty } } /// Translate ConstVal into a LLVM constant value. - pub fn from_constval(ccx: &CrateContext<'a, 'tcx>, + pub fn from_constval(cx: &CodegenCx<'a, 'tcx>, cv: &ConstVal, ty: Ty<'tcx>) -> Const<'tcx> { - let llty = ccx.layout_of(ty).llvm_type(ccx); + let llty = cx.layout_of(ty).llvm_type(cx); let val = match *cv { ConstVal::Float(v) => { let bits = match v.ty { - ast::FloatTy::F32 => C_u32(ccx, v.bits as u32), - ast::FloatTy::F64 => C_u64(ccx, v.bits as u64) + ast::FloatTy::F32 => C_u32(cx, v.bits as u32), + ast::FloatTy::F64 => C_u64(cx, v.bits as u64) }; consts::bitcast(bits, llty) } - ConstVal::Bool(v) => C_bool(ccx, v), - ConstVal::Integral(ref i) => return Const::from_constint(ccx, i), - ConstVal::Str(ref v) => C_str_slice(ccx, v.clone()), + ConstVal::Bool(v) => C_bool(cx, v), + ConstVal::Integral(ref i) => return Const::from_constint(cx, i), + ConstVal::Str(ref v) => C_str_slice(cx, v.clone()), ConstVal::ByteStr(v) => { - consts::addr_of(ccx, C_bytes(ccx, v.data), ccx.align_of(ty), "byte_str") + consts::addr_of(cx, C_bytes(cx, v.data), cx.align_of(ty), "byte_str") } - ConstVal::Char(c) => C_uint(Type::char(ccx), c as u64), + ConstVal::Char(c) => C_uint(Type::char(cx), c as u64), ConstVal::Function(..) => C_undef(llty), ConstVal::Variant(_) | ConstVal::Aggregate(..) | @@ -115,11 +115,11 @@ impl<'a, 'tcx> Const<'tcx> { Const::new(val, ty) } - fn get_field(&self, ccx: &CrateContext<'a, 'tcx>, i: usize) -> ValueRef { - let layout = ccx.layout_of(self.ty); - let field = layout.field(ccx, i); + fn get_field(&self, cx: &CodegenCx<'a, 'tcx>, i: usize) -> ValueRef { + let layout = cx.layout_of(self.ty); + let field = layout.field(cx, i); if field.is_zst() { - return C_undef(field.immediate_llvm_type(ccx)); + return C_undef(field.immediate_llvm_type(cx)); } let offset = layout.fields.offset(i); match layout.abi { @@ -130,12 +130,12 @@ impl<'a, 'tcx> Const<'tcx> { layout::Abi::ScalarPair(ref a, ref b) => { if offset.bytes() == 0 { - assert_eq!(field.size, a.value.size(ccx)); + assert_eq!(field.size, a.value.size(cx)); const_get_elt(self.llval, 0) } else { - assert_eq!(offset, a.value.size(ccx) - .abi_align(b.value.align(ccx))); - assert_eq!(field.size, b.value.size(ccx)); + assert_eq!(offset, a.value.size(cx) + .abi_align(b.value.align(cx))); + assert_eq!(field.size, b.value.size(cx)); const_get_elt(self.llval, 1) } } @@ -145,14 +145,14 @@ impl<'a, 'tcx> Const<'tcx> { } } - fn get_pair(&self, ccx: &CrateContext<'a, 'tcx>) -> (ValueRef, ValueRef) { - (self.get_field(ccx, 0), self.get_field(ccx, 1)) + fn get_pair(&self, cx: &CodegenCx<'a, 'tcx>) -> (ValueRef, ValueRef) { + (self.get_field(cx, 0), self.get_field(cx, 1)) } - fn get_fat_ptr(&self, ccx: &CrateContext<'a, 'tcx>) -> (ValueRef, ValueRef) { + fn get_fat_ptr(&self, cx: &CodegenCx<'a, 'tcx>) -> (ValueRef, ValueRef) { assert_eq!(abi::FAT_PTR_ADDR, 0); assert_eq!(abi::FAT_PTR_EXTRA, 1); - self.get_pair(ccx) + self.get_pair(cx) } fn as_place(&self) -> ConstPlace<'tcx> { @@ -163,9 +163,9 @@ impl<'a, 'tcx> Const<'tcx> { } } - pub fn to_operand(&self, ccx: &CrateContext<'a, 'tcx>) -> OperandRef<'tcx> { - let layout = ccx.layout_of(self.ty); - let llty = layout.immediate_llvm_type(ccx); + pub fn to_operand(&self, cx: &CodegenCx<'a, 'tcx>) -> OperandRef<'tcx> { + let layout = cx.layout_of(self.ty); + let llty = layout.immediate_llvm_type(cx); let llvalty = val_ty(self.llval); let val = if llty == llvalty && layout.is_llvm_scalar_pair() { @@ -178,9 +178,9 @@ impl<'a, 'tcx> Const<'tcx> { } else { // Otherwise, or if the value is not immediate, we create // a constant LLVM global and cast its address if necessary. - let align = ccx.align_of(self.ty); - let ptr = consts::addr_of(ccx, self.llval, align, "const"); - OperandValue::Ref(consts::ptrcast(ptr, layout.llvm_type(ccx).ptr_to()), + let align = cx.align_of(self.ty); + let ptr = consts::addr_of(cx, self.llval, align, "const"); + OperandValue::Ref(consts::ptrcast(ptr, layout.llvm_type(cx).ptr_to()), layout.align) }; @@ -232,10 +232,10 @@ impl<'tcx> ConstPlace<'tcx> { } } - pub fn len<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> ValueRef { + pub fn len<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> ValueRef { match self.ty.sty { ty::TyArray(_, n) => { - C_usize(ccx, n.val.to_const_int().unwrap().to_u64().unwrap()) + C_usize(cx, n.val.to_const_int().unwrap().to_u64().unwrap()) } ty::TySlice(_) | ty::TyStr => { assert!(self.llextra != ptr::null_mut()); @@ -249,7 +249,7 @@ impl<'tcx> ConstPlace<'tcx> { /// Machinery for translating a constant's MIR to LLVM values. /// FIXME(eddyb) use miri and lower its allocations to LLVM. struct MirConstContext<'a, 'tcx: 'a> { - ccx: &'a CrateContext<'a, 'tcx>, + cx: &'a CodegenCx<'a, 'tcx>, mir: &'a mir::Mir<'tcx>, /// Type parameters for const fn and associated constants. @@ -270,13 +270,13 @@ fn add_err<'tcx, U, V>(failure: &mut Result<U, ConstEvalErr<'tcx>>, } impl<'a, 'tcx> MirConstContext<'a, 'tcx> { - fn new(ccx: &'a CrateContext<'a, 'tcx>, + fn new(cx: &'a CodegenCx<'a, 'tcx>, mir: &'a mir::Mir<'tcx>, substs: &'tcx Substs<'tcx>, args: IndexVec<mir::Local, Result<Const<'tcx>, ConstEvalErr<'tcx>>>) -> MirConstContext<'a, 'tcx> { let mut context = MirConstContext { - ccx, + cx, mir, substs, locals: (0..mir.local_decls.len()).map(|_| None).collect(), @@ -289,27 +289,27 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { context } - fn trans_def(ccx: &'a CrateContext<'a, 'tcx>, + fn trans_def(cx: &'a CodegenCx<'a, 'tcx>, def_id: DefId, substs: &'tcx Substs<'tcx>, args: IndexVec<mir::Local, Result<Const<'tcx>, ConstEvalErr<'tcx>>>) -> Result<Const<'tcx>, ConstEvalErr<'tcx>> { - let instance = ty::Instance::resolve(ccx.tcx(), + let instance = ty::Instance::resolve(cx.tcx, ty::ParamEnv::empty(traits::Reveal::All), def_id, substs).unwrap(); - let mir = ccx.tcx().instance_mir(instance.def); - MirConstContext::new(ccx, &mir, instance.substs, args).trans() + let mir = cx.tcx.instance_mir(instance.def); + MirConstContext::new(cx, &mir, instance.substs, args).trans() } fn monomorphize<T>(&self, value: &T) -> T where T: TransNormalize<'tcx> { - self.ccx.tcx().trans_apply_param_substs(self.substs, value) + self.cx.tcx.trans_apply_param_substs(self.substs, value) } fn trans(&mut self) -> Result<Const<'tcx>, ConstEvalErr<'tcx>> { - let tcx = self.ccx.tcx(); + let tcx = self.cx.tcx; let mut bb = mir::START_BLOCK; // Make sure to evaluate all statemenets to @@ -399,13 +399,13 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { let result = if fn_ty.fn_sig(tcx).abi() == Abi::RustIntrinsic { match &tcx.item_name(def_id)[..] { "size_of" => { - let llval = C_usize(self.ccx, - self.ccx.size_of(substs.type_at(0)).bytes()); + let llval = C_usize(self.cx, + self.cx.size_of(substs.type_at(0)).bytes()); Ok(Const::new(llval, tcx.types.usize)) } "min_align_of" => { - let llval = C_usize(self.ccx, - self.ccx.align_of(substs.type_at(0)).abi()); + let llval = C_usize(self.cx, + self.cx.align_of(substs.type_at(0)).abi()); Ok(Const::new(llval, tcx.types.usize)) } _ => span_bug!(span, "{:?} in constant", terminator.kind) @@ -430,12 +430,12 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { match const_scalar_checked_binop(tcx, op, lhs, rhs, ty) { Some((llval, of)) => { Ok(trans_const_adt( - self.ccx, + self.cx, binop_ty, &mir::AggregateKind::Tuple, &[ Const::new(llval, val_ty), - Const::new(C_bool(self.ccx, of), tcx.types.bool) + Const::new(C_bool(self.cx, of), tcx.types.bool) ])) } None => { @@ -447,7 +447,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { } })() } else { - MirConstContext::trans_def(self.ccx, def_id, substs, arg_vals) + MirConstContext::trans_def(self.cx, def_id, substs, arg_vals) }; add_err(&mut failure, &result); self.store(dest, result, span); @@ -462,7 +462,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { } fn is_binop_lang_item(&mut self, def_id: DefId) -> Option<(mir::BinOp, bool)> { - let tcx = self.ccx.tcx(); + let tcx = self.cx.tcx; let items = tcx.lang_items(); let def_id = Some(def_id); if items.i128_add_fn() == def_id { Some((mir::BinOp::Add, false)) } @@ -505,7 +505,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { fn const_place(&self, place: &mir::Place<'tcx>, span: Span) -> Result<ConstPlace<'tcx>, ConstEvalErr<'tcx>> { - let tcx = self.ccx.tcx(); + let tcx = self.cx.tcx; if let mir::Place::Local(index) = *place { return self.locals[index].clone().unwrap_or_else(|| { @@ -517,7 +517,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { mir::Place::Local(_) => bug!(), // handled above mir::Place::Static(box mir::Static { def_id, ty }) => { ConstPlace { - base: Base::Static(consts::get_static(self.ccx, def_id)), + base: Base::Static(consts::get_static(self.cx, def_id)), llextra: ptr::null_mut(), ty: self.monomorphize(&ty), } @@ -528,30 +528,30 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { .projection_ty(tcx, &projection.elem); let base = tr_base.to_const(span); let projected_ty = self.monomorphize(&projected_ty).to_ty(tcx); - let has_metadata = self.ccx.shared().type_has_metadata(projected_ty); + let has_metadata = self.cx.type_has_metadata(projected_ty); let (projected, llextra) = match projection.elem { mir::ProjectionElem::Deref => { let (base, extra) = if !has_metadata { (base.llval, ptr::null_mut()) } else { - base.get_fat_ptr(self.ccx) + base.get_fat_ptr(self.cx) }; - if self.ccx.statics().borrow().contains_key(&base) { + if self.cx.statics.borrow().contains_key(&base) { (Base::Static(base), extra) } else if let ty::TyStr = projected_ty.sty { (Base::Str(base), extra) } else { let v = base; - let v = self.ccx.const_unsized().borrow().get(&v).map_or(v, |&v| v); + let v = self.cx.const_unsized.borrow().get(&v).map_or(v, |&v| v); let mut val = unsafe { llvm::LLVMGetInitializer(v) }; if val.is_null() { span_bug!(span, "dereference of non-constant pointer `{:?}`", Value(base)); } - let layout = self.ccx.layout_of(projected_ty); + let layout = self.cx.layout_of(projected_ty); if let layout::Abi::Scalar(ref scalar) = layout.abi { - let i1_type = Type::i1(self.ccx); + let i1_type = Type::i1(self.cx); if scalar.is_bool() && val_ty(val) != i1_type { unsafe { val = llvm::LLVMConstTrunc(val, i1_type.to_ref()); @@ -562,7 +562,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { } } mir::ProjectionElem::Field(ref field, _) => { - let llprojected = base.get_field(self.ccx, field.index()); + let llprojected = base.get_field(self.cx, field.index()); let llextra = if !has_metadata { ptr::null_mut() } else { @@ -581,11 +581,11 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { }; // Produce an undef instead of a LLVM assertion on OOB. - let len = common::const_to_uint(tr_base.len(self.ccx)); + let len = common::const_to_uint(tr_base.len(self.cx)); let llelem = if iv < len as u128 { const_get_elt(base.llval, iv as u64) } else { - C_undef(self.ccx.layout_of(projected_ty).llvm_type(self.ccx)) + C_undef(self.cx.layout_of(projected_ty).llvm_type(self.cx)) }; (Base::Value(llelem), ptr::null_mut()) @@ -616,14 +616,14 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { match constant.literal.clone() { mir::Literal::Promoted { index } => { let mir = &self.mir.promoted[index]; - MirConstContext::new(self.ccx, mir, self.substs, IndexVec::new()).trans() + MirConstContext::new(self.cx, mir, self.substs, IndexVec::new()).trans() } mir::Literal::Value { value } => { if let ConstVal::Unevaluated(def_id, substs) = value.val { let substs = self.monomorphize(&substs); - MirConstContext::trans_def(self.ccx, def_id, substs, IndexVec::new()) + MirConstContext::trans_def(self.cx, def_id, substs, IndexVec::new()) } else { - Ok(Const::from_constval(self.ccx, &value.val, ty)) + Ok(Const::from_constval(self.cx, &value.val, ty)) } } } @@ -640,12 +640,12 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { let elem_ty = array_ty.builtin_index().unwrap_or_else(|| { bug!("bad array type {:?}", array_ty) }); - let llunitty = self.ccx.layout_of(elem_ty).llvm_type(self.ccx); + let llunitty = self.cx.layout_of(elem_ty).llvm_type(self.cx); // If the array contains enums, an LLVM array won't work. let val = if fields.iter().all(|&f| val_ty(f) == llunitty) { C_array(llunitty, fields) } else { - C_struct(self.ccx, fields, false) + C_struct(self.cx, fields, false) }; Const::new(val, array_ty) } @@ -653,7 +653,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { fn const_rvalue(&self, rvalue: &mir::Rvalue<'tcx>, dest_ty: Ty<'tcx>, span: Span) -> Result<Const<'tcx>, ConstEvalErr<'tcx>> { - let tcx = self.ccx.tcx(); + let tcx = self.cx.tcx; debug!("const_rvalue({:?}: {:?} @ {:?})", rvalue, dest_ty, span); let val = match *rvalue { mir::Rvalue::Use(ref operand) => self.const_operand(operand, span)?, @@ -695,7 +695,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { } failure?; - trans_const_adt(self.ccx, dest_ty, kind, &fields) + trans_const_adt(self.cx, dest_ty, kind, &fields) } mir::Rvalue::Cast(ref kind, ref source, cast_ty) => { @@ -706,7 +706,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { mir::CastKind::ReifyFnPointer => { match operand.ty.sty { ty::TyFnDef(def_id, substs) => { - callee::resolve_and_get_fn(self.ccx, def_id, substs) + callee::resolve_and_get_fn(self.cx, def_id, substs) } _ => { span_bug!(span, "{} cannot be reified to a fn ptr", @@ -728,7 +728,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { let input = tcx.erase_late_bound_regions_and_normalize(&input); let substs = tcx.mk_substs([operand.ty, input] .iter().cloned().map(Kind::from)); - callee::resolve_and_get_fn(self.ccx, call_once, substs) + callee::resolve_and_get_fn(self.cx, call_once, substs) } _ => { bug!("{} cannot be cast to a fn ptr", operand.ty) @@ -742,14 +742,14 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { mir::CastKind::Unsize => { let pointee_ty = operand.ty.builtin_deref(true, ty::NoPreference) .expect("consts: unsizing got non-pointer type").ty; - let (base, old_info) = if !self.ccx.shared().type_is_sized(pointee_ty) { + let (base, old_info) = if !self.cx.type_is_sized(pointee_ty) { // Normally, the source is a thin pointer and we are // adding extra info to make a fat pointer. The exception // is when we are upcasting an existing object fat pointer // to use a different vtable. In that case, we want to // load out the original data pointer so we can repackage // it. - let (base, extra) = operand.get_fat_ptr(self.ccx); + let (base, extra) = operand.get_fat_ptr(self.cx); (base, Some(extra)) } else { (operand.llval, None) @@ -757,28 +757,28 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { let unsized_ty = cast_ty.builtin_deref(true, ty::NoPreference) .expect("consts: unsizing got non-pointer target type").ty; - let ptr_ty = self.ccx.layout_of(unsized_ty).llvm_type(self.ccx).ptr_to(); + let ptr_ty = self.cx.layout_of(unsized_ty).llvm_type(self.cx).ptr_to(); let base = consts::ptrcast(base, ptr_ty); - let info = base::unsized_info(self.ccx, pointee_ty, + let info = base::unsized_info(self.cx, pointee_ty, unsized_ty, old_info); if old_info.is_none() { - let prev_const = self.ccx.const_unsized().borrow_mut() + let prev_const = self.cx.const_unsized.borrow_mut() .insert(base, operand.llval); assert!(prev_const.is_none() || prev_const == Some(operand.llval)); } - C_fat_ptr(self.ccx, base, info) + C_fat_ptr(self.cx, base, info) } - mir::CastKind::Misc if self.ccx.layout_of(operand.ty).is_llvm_immediate() => { + mir::CastKind::Misc if self.cx.layout_of(operand.ty).is_llvm_immediate() => { let r_t_in = CastTy::from_ty(operand.ty).expect("bad input type for cast"); let r_t_out = CastTy::from_ty(cast_ty).expect("bad output type for cast"); - let cast_layout = self.ccx.layout_of(cast_ty); + let cast_layout = self.cx.layout_of(cast_ty); assert!(cast_layout.is_llvm_immediate()); - let ll_t_out = cast_layout.immediate_llvm_type(self.ccx); + let ll_t_out = cast_layout.immediate_llvm_type(self.cx); let llval = operand.llval; let mut signed = false; - let l = self.ccx.layout_of(operand.ty); + let l = self.cx.layout_of(operand.ty); if let layout::Abi::Scalar(ref scalar) = l.abi { if let layout::Int(_, true) = scalar.value { signed = true; @@ -792,17 +792,17 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { llvm::LLVMConstIntCast(llval, ll_t_out.to_ref(), s) } (CastTy::Int(_), CastTy::Float) => { - cast_const_int_to_float(self.ccx, llval, signed, ll_t_out) + cast_const_int_to_float(self.cx, llval, signed, ll_t_out) } (CastTy::Float, CastTy::Float) => { llvm::LLVMConstFPCast(llval, ll_t_out.to_ref()) } (CastTy::Float, CastTy::Int(IntTy::I)) => { - cast_const_float_to_int(self.ccx, &operand, + cast_const_float_to_int(self.cx, &operand, true, ll_t_out, span) } (CastTy::Float, CastTy::Int(_)) => { - cast_const_float_to_int(self.ccx, &operand, + cast_const_float_to_int(self.cx, &operand, false, ll_t_out, span) } (CastTy::Ptr(_), CastTy::Ptr(_)) | @@ -813,7 +813,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { (CastTy::Int(_), CastTy::Ptr(_)) => { let s = signed as llvm::Bool; let usize_llval = llvm::LLVMConstIntCast(llval, - self.ccx.isize_ty().to_ref(), s); + self.cx.isize_ty.to_ref(), s); llvm::LLVMConstIntToPtr(usize_llval, ll_t_out.to_ref()) } (CastTy::Ptr(_), CastTy::Int(_)) | @@ -825,18 +825,18 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { } } mir::CastKind::Misc => { // Casts from a fat-ptr. - let l = self.ccx.layout_of(operand.ty); - let cast = self.ccx.layout_of(cast_ty); + let l = self.cx.layout_of(operand.ty); + let cast = self.cx.layout_of(cast_ty); if l.is_llvm_scalar_pair() { - let (data_ptr, meta) = operand.get_fat_ptr(self.ccx); + let (data_ptr, meta) = operand.get_fat_ptr(self.cx); if cast.is_llvm_scalar_pair() { let data_cast = consts::ptrcast(data_ptr, - cast.scalar_pair_element_llvm_type(self.ccx, 0)); - C_fat_ptr(self.ccx, data_cast, meta) + cast.scalar_pair_element_llvm_type(self.cx, 0)); + C_fat_ptr(self.cx, data_cast, meta) } else { // cast to thin-ptr // Cast of fat-ptr to thin-ptr is an extraction of data-ptr and // pointer-cast of that pointer to desired pointer type. - let llcast_ty = cast.immediate_llvm_type(self.ccx); + let llcast_ty = cast.immediate_llvm_type(self.cx); consts::ptrcast(data_ptr, llcast_ty) } } else { @@ -857,32 +857,32 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { let base = match tr_place.base { Base::Value(llval) => { // FIXME: may be wrong for &*(&simd_vec as &fmt::Debug) - let align = if self.ccx.shared().type_is_sized(ty) { - self.ccx.align_of(ty) + let align = if self.cx.type_is_sized(ty) { + self.cx.align_of(ty) } else { - self.ccx.tcx().data_layout.pointer_align + self.cx.tcx.data_layout.pointer_align }; if bk == mir::BorrowKind::Mut { - consts::addr_of_mut(self.ccx, llval, align, "ref_mut") + consts::addr_of_mut(self.cx, llval, align, "ref_mut") } else { - consts::addr_of(self.ccx, llval, align, "ref") + consts::addr_of(self.cx, llval, align, "ref") } } Base::Str(llval) | Base::Static(llval) => llval }; - let ptr = if self.ccx.shared().type_is_sized(ty) { + let ptr = if self.cx.type_is_sized(ty) { base } else { - C_fat_ptr(self.ccx, base, tr_place.llextra) + C_fat_ptr(self.cx, base, tr_place.llextra) }; Const::new(ptr, ref_ty) } mir::Rvalue::Len(ref place) => { let tr_place = self.const_place(place, span)?; - Const::new(tr_place.len(self.ccx), tcx.types.usize) + Const::new(tr_place.len(self.cx), tcx.types.usize) } mir::Rvalue::BinaryOp(op, ref lhs, ref rhs) => { @@ -905,9 +905,9 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { match const_scalar_checked_binop(tcx, op, lhs, rhs, ty) { Some((llval, of)) => { - trans_const_adt(self.ccx, binop_ty, &mir::AggregateKind::Tuple, &[ + trans_const_adt(self.cx, binop_ty, &mir::AggregateKind::Tuple, &[ Const::new(llval, val_ty), - Const::new(C_bool(self.ccx, of), tcx.types.bool) + Const::new(C_bool(self.cx, of), tcx.types.bool) ]) } None => { @@ -941,8 +941,8 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { } mir::Rvalue::NullaryOp(mir::NullOp::SizeOf, ty) => { - assert!(self.ccx.shared().type_is_sized(ty)); - let llval = C_usize(self.ccx, self.ccx.size_of(ty).bytes()); + assert!(self.cx.type_is_sized(ty)); + let llval = C_usize(self.cx, self.cx.size_of(ty).bytes()); Const::new(llval, tcx.types.usize) } @@ -1060,7 +1060,7 @@ pub fn const_scalar_checked_binop<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } } -unsafe fn cast_const_float_to_int(ccx: &CrateContext, +unsafe fn cast_const_float_to_int(cx: &CodegenCx, operand: &Const, signed: bool, int_ty: Type, @@ -1074,7 +1074,7 @@ unsafe fn cast_const_float_to_int(ccx: &CrateContext, // One way that might happen would be if addresses could be turned into integers in constant // expressions, but that doesn't appear to be possible? // In any case, an ICE is better than producing undef. - let llval_bits = consts::bitcast(llval, Type::ix(ccx, float_bits as u64)); + let llval_bits = consts::bitcast(llval, Type::ix(cx, float_bits as u64)); let bits = const_to_opt_u128(llval_bits, false).unwrap_or_else(|| { panic!("could not get bits of constant float {:?}", Value(llval)); @@ -1090,12 +1090,12 @@ unsafe fn cast_const_float_to_int(ccx: &CrateContext, }; if cast_result.status.contains(Status::INVALID_OP) { let err = ConstEvalErr { span: span, kind: ErrKind::CannotCast }; - err.report(ccx.tcx(), span, "expression"); + err.report(cx.tcx, span, "expression"); } C_uint_big(int_ty, cast_result.value) } -unsafe fn cast_const_int_to_float(ccx: &CrateContext, +unsafe fn cast_const_int_to_float(cx: &CodegenCx, llval: ValueRef, signed: bool, float_ty: Type) -> ValueRef { @@ -1111,16 +1111,16 @@ unsafe fn cast_const_int_to_float(ccx: &CrateContext, llvm::LLVMConstSIToFP(llval, float_ty.to_ref()) } else if float_ty.float_width() == 32 && value >= MAX_F32_PLUS_HALF_ULP { // We're casting to f32 and the value is > f32::MAX + 0.5 ULP -> round up to infinity. - let infinity_bits = C_u32(ccx, ieee::Single::INFINITY.to_bits() as u32); + let infinity_bits = C_u32(cx, ieee::Single::INFINITY.to_bits() as u32); consts::bitcast(infinity_bits, float_ty) } else { llvm::LLVMConstUIToFP(llval, float_ty.to_ref()) } } -impl<'a, 'tcx> MirContext<'a, 'tcx> { +impl<'a, 'tcx> FunctionCx<'a, 'tcx> { pub fn trans_constant(&mut self, - bcx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'tcx>, constant: &mir::Constant<'tcx>) -> Const<'tcx> { @@ -1129,21 +1129,21 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { let result = match constant.literal.clone() { mir::Literal::Promoted { index } => { let mir = &self.mir.promoted[index]; - MirConstContext::new(bcx.ccx, mir, self.param_substs, IndexVec::new()).trans() + MirConstContext::new(bx.cx, mir, self.param_substs, IndexVec::new()).trans() } mir::Literal::Value { value } => { if let ConstVal::Unevaluated(def_id, substs) = value.val { let substs = self.monomorphize(&substs); - MirConstContext::trans_def(bcx.ccx, def_id, substs, IndexVec::new()) + MirConstContext::trans_def(bx.cx, def_id, substs, IndexVec::new()) } else { - Ok(Const::from_constval(bcx.ccx, &value.val, ty)) + Ok(Const::from_constval(bx.cx, &value.val, ty)) } } }; let result = result.unwrap_or_else(|_| { // We've errored, so we don't have to produce working code. - let llty = bcx.ccx.layout_of(ty).llvm_type(bcx.ccx); + let llty = bx.cx.layout_of(ty).llvm_type(bx.cx); Const::new(C_undef(llty), ty) }); @@ -1154,11 +1154,11 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { pub fn trans_static_initializer<'a, 'tcx>( - ccx: &CrateContext<'a, 'tcx>, + cx: &CodegenCx<'a, 'tcx>, def_id: DefId) -> Result<ValueRef, ConstEvalErr<'tcx>> { - MirConstContext::trans_def(ccx, def_id, Substs::empty(), IndexVec::new()) + MirConstContext::trans_def(cx, def_id, Substs::empty(), IndexVec::new()) .map(|c| c.llval) } @@ -1182,19 +1182,19 @@ pub fn trans_static_initializer<'a, 'tcx>( /// this could be changed in the future to avoid allocating unnecessary /// space after values of shorter-than-maximum cases. fn trans_const_adt<'a, 'tcx>( - ccx: &CrateContext<'a, 'tcx>, + cx: &CodegenCx<'a, 'tcx>, t: Ty<'tcx>, kind: &mir::AggregateKind, vals: &[Const<'tcx>] ) -> Const<'tcx> { - let l = ccx.layout_of(t); + let l = cx.layout_of(t); let variant_index = match *kind { mir::AggregateKind::Adt(_, index, _, _) => index, _ => 0, }; if let layout::Abi::Uninhabited = l.abi { - return Const::new(C_undef(l.llvm_type(ccx)), t); + return Const::new(C_undef(l.llvm_type(cx)), t); } match l.variants { @@ -1203,14 +1203,14 @@ fn trans_const_adt<'a, 'tcx>( if let layout::FieldPlacement::Union(_) = l.fields { assert_eq!(variant_index, 0); assert_eq!(vals.len(), 1); - let (field_size, field_align) = ccx.size_and_align_of(vals[0].ty); + let (field_size, field_align) = cx.size_and_align_of(vals[0].ty); let contents = [ vals[0].llval, - padding(ccx, l.size - field_size) + padding(cx, l.size - field_size) ]; let packed = l.align.abi() < field_align.abi(); - Const::new(C_struct(ccx, &contents, packed), t) + Const::new(C_struct(cx, &contents, packed), t) } else { if let layout::Abi::Vector { .. } = l.abi { if let layout::FieldPlacement::Array { .. } = l.fields { @@ -1218,24 +1218,24 @@ fn trans_const_adt<'a, 'tcx>( .collect::<Vec<_>>()), t); } } - build_const_struct(ccx, l, vals, None) + build_const_struct(cx, l, vals, None) } } layout::Variants::Tagged { .. } => { let discr = match *kind { mir::AggregateKind::Adt(adt_def, _, _, _) => { - adt_def.discriminant_for_variant(ccx.tcx(), variant_index) + adt_def.discriminant_for_variant(cx.tcx, variant_index) .to_u128_unchecked() as u64 }, _ => 0, }; - let discr_field = l.field(ccx, 0); - let discr = C_int(discr_field.llvm_type(ccx), discr as i64); + let discr_field = l.field(cx, 0); + let discr = C_int(discr_field.llvm_type(cx), discr as i64); if let layout::Abi::Scalar(_) = l.abi { Const::new(discr, t) } else { let discr = Const::new(discr, discr_field.ty); - build_const_struct(ccx, l.for_variant(ccx, variant_index), vals, Some(discr)) + build_const_struct(cx, l.for_variant(cx, variant_index), vals, Some(discr)) } } layout::Variants::NicheFilling { @@ -1245,10 +1245,10 @@ fn trans_const_adt<'a, 'tcx>( .. } => { if variant_index == dataful_variant { - build_const_struct(ccx, l.for_variant(ccx, dataful_variant), vals, None) + build_const_struct(cx, l.for_variant(cx, dataful_variant), vals, None) } else { - let niche = l.field(ccx, 0); - let niche_llty = niche.llvm_type(ccx); + let niche = l.field(cx, 0); + let niche_llty = niche.llvm_type(cx); let niche_value = ((variant_index - niche_variants.start) as u128) .wrapping_add(niche_start); // FIXME(eddyb) Check the actual primitive type here. @@ -1258,7 +1258,7 @@ fn trans_const_adt<'a, 'tcx>( } else { C_uint_big(niche_llty, niche_value) }; - build_const_struct(ccx, l, &[Const::new(niche_llval, niche.ty)], None) + build_const_struct(cx, l, &[Const::new(niche_llval, niche.ty)], None) } } } @@ -1272,7 +1272,7 @@ fn trans_const_adt<'a, 'tcx>( /// initializer is 4-byte aligned then simply translating the tuple as /// a two-element struct will locate it at offset 4, and accesses to it /// will read the wrong memory. -fn build_const_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, +fn build_const_struct<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, layout: layout::TyLayout<'tcx>, vals: &[Const<'tcx>], discr: Option<Const<'tcx>>) @@ -1285,16 +1285,16 @@ fn build_const_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, layout::Abi::Vector { .. } if discr.is_none() => { let mut non_zst_fields = vals.iter().enumerate().map(|(i, f)| { (f, layout.fields.offset(i)) - }).filter(|&(f, _)| !ccx.layout_of(f.ty).is_zst()); + }).filter(|&(f, _)| !cx.layout_of(f.ty).is_zst()); match (non_zst_fields.next(), non_zst_fields.next()) { (Some((x, offset)), None) if offset.bytes() == 0 => { return Const::new(x.llval, layout.ty); } (Some((a, a_offset)), Some((b, _))) if a_offset.bytes() == 0 => { - return Const::new(C_struct(ccx, &[a.llval, b.llval], false), layout.ty); + return Const::new(C_struct(cx, &[a.llval, b.llval], false), layout.ty); } (Some((a, _)), Some((b, b_offset))) if b_offset.bytes() == 0 => { - return Const::new(C_struct(ccx, &[b.llval, a.llval], false), layout.ty); + return Const::new(C_struct(cx, &[b.llval, a.llval], false), layout.ty); } _ => {} } @@ -1309,7 +1309,7 @@ fn build_const_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, cfields.reserve(discr.is_some() as usize + 1 + layout.fields.count() * 2); if let Some(discr) = discr { - let (field_size, field_align) = ccx.size_and_align_of(discr.ty); + let (field_size, field_align) = cx.size_and_align_of(discr.ty); packed |= layout.align.abi() < field_align.abi(); cfields.push(discr.llval); offset = field_size; @@ -1319,19 +1319,19 @@ fn build_const_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, (vals[i], layout.fields.offset(i)) }); for (val, target_offset) in parts { - let (field_size, field_align) = ccx.size_and_align_of(val.ty); + let (field_size, field_align) = cx.size_and_align_of(val.ty); packed |= layout.align.abi() < field_align.abi(); - cfields.push(padding(ccx, target_offset - offset)); + cfields.push(padding(cx, target_offset - offset)); cfields.push(val.llval); offset = target_offset + field_size; } // Pad to the size of the whole type, not e.g. the variant. - cfields.push(padding(ccx, ccx.size_of(layout.ty) - offset)); + cfields.push(padding(cx, cx.size_of(layout.ty) - offset)); - Const::new(C_struct(ccx, &cfields, packed), layout.ty) + Const::new(C_struct(cx, &cfields, packed), layout.ty) } -fn padding(ccx: &CrateContext, size: Size) -> ValueRef { - C_undef(Type::array(&Type::i8(ccx), size.bytes())) +fn padding(cx: &CodegenCx, size: Size) -> ValueRef { + C_undef(Type::array(&Type::i8(cx), size.bytes())) } diff --git a/src/librustc_trans/mir/mod.rs b/src/librustc_trans/mir/mod.rs index 917ff87a674..3064e2f7c7a 100644 --- a/src/librustc_trans/mir/mod.rs +++ b/src/librustc_trans/mir/mod.rs @@ -19,7 +19,7 @@ use rustc::infer::TransNormalize; use rustc::session::config::FullDebugInfo; use base; use builder::Builder; -use common::{CrateContext, Funclet}; +use common::{CodegenCx, Funclet}; use debuginfo::{self, declare_local, VariableAccess, VariableKind, FunctionDebugContext}; use monomorphize::Instance; use abi::{ArgAttribute, FnType, PassMode}; @@ -41,14 +41,14 @@ use rustc::mir::traversal; use self::operand::{OperandRef, OperandValue}; /// Master context for translating MIR. -pub struct MirContext<'a, 'tcx:'a> { +pub struct FunctionCx<'a, 'tcx:'a> { mir: &'a mir::Mir<'tcx>, debug_context: debuginfo::FunctionDebugContext, llfn: ValueRef, - ccx: &'a CrateContext<'a, 'tcx>, + cx: &'a CodegenCx<'a, 'tcx>, fn_ty: FnType<'tcx>, @@ -102,16 +102,16 @@ pub struct MirContext<'a, 'tcx:'a> { param_substs: &'tcx Substs<'tcx>, } -impl<'a, 'tcx> MirContext<'a, 'tcx> { +impl<'a, 'tcx> FunctionCx<'a, 'tcx> { pub fn monomorphize<T>(&self, value: &T) -> T where T: TransNormalize<'tcx> { - self.ccx.tcx().trans_apply_param_substs(self.param_substs, value) + self.cx.tcx.trans_apply_param_substs(self.param_substs, value) } - pub fn set_debug_loc(&mut self, bcx: &Builder, source_info: mir::SourceInfo) { + pub fn set_debug_loc(&mut self, bx: &Builder, source_info: mir::SourceInfo) { let (scope, span) = self.debug_loc(source_info); - debuginfo::set_source_location(&self.debug_context, bcx, scope, span); + debuginfo::set_source_location(&self.debug_context, bx, scope, span); } pub fn debug_loc(&mut self, source_info: mir::SourceInfo) -> (DIScope, Span) { @@ -128,7 +128,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { // locations of macro expansions with that of the outermost expansion site // (unless the crate is being compiled with `-Z debug-macros`). if source_info.span.ctxt() == NO_EXPANSION || - self.ccx.sess().opts.debugging_opts.debug_macros { + self.cx.sess().opts.debugging_opts.debug_macros { let scope = self.scope_metadata_for_loc(source_info.scope, source_info.span.lo()); (scope, source_info.span) } else { @@ -158,9 +158,9 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { let scope_metadata = self.scopes[scope_id].scope_metadata; if pos < self.scopes[scope_id].file_start_pos || pos >= self.scopes[scope_id].file_end_pos { - let cm = self.ccx.sess().codemap(); + let cm = self.cx.sess().codemap(); let defining_crate = self.debug_context.get_ref(DUMMY_SP).defining_crate; - debuginfo::extend_scope_to_file(self.ccx, + debuginfo::extend_scope_to_file(self.cx, scope_metadata, &cm.lookup_char_pos(pos).file, defining_crate) @@ -176,12 +176,12 @@ enum LocalRef<'tcx> { } impl<'a, 'tcx> LocalRef<'tcx> { - fn new_operand(ccx: &CrateContext<'a, 'tcx>, layout: TyLayout<'tcx>) -> LocalRef<'tcx> { + fn new_operand(cx: &CodegenCx<'a, 'tcx>, layout: TyLayout<'tcx>) -> LocalRef<'tcx> { if layout.is_zst() { // Zero-size temporaries aren't always initialized, which // doesn't matter because they don't contain data, but // we need something in the operand. - LocalRef::Operand(Some(OperandRef::new_zst(ccx, layout))) + LocalRef::Operand(Some(OperandRef::new_zst(cx, layout))) } else { LocalRef::Operand(None) } @@ -191,46 +191,46 @@ impl<'a, 'tcx> LocalRef<'tcx> { /////////////////////////////////////////////////////////////////////////// pub fn trans_mir<'a, 'tcx: 'a>( - ccx: &'a CrateContext<'a, 'tcx>, + cx: &'a CodegenCx<'a, 'tcx>, llfn: ValueRef, mir: &'a Mir<'tcx>, instance: Instance<'tcx>, sig: ty::FnSig<'tcx>, ) { - let fn_ty = FnType::new(ccx, sig, &[]); + let fn_ty = FnType::new(cx, sig, &[]); debug!("fn_ty: {:?}", fn_ty); let debug_context = - debuginfo::create_function_debug_context(ccx, instance, sig, llfn, mir); - let bcx = Builder::new_block(ccx, llfn, "start"); + debuginfo::create_function_debug_context(cx, instance, sig, llfn, mir); + let bx = Builder::new_block(cx, llfn, "start"); if mir.basic_blocks().iter().any(|bb| bb.is_cleanup) { - bcx.set_personality_fn(ccx.eh_personality()); + bx.set_personality_fn(cx.eh_personality()); } let cleanup_kinds = analyze::cleanup_kinds(&mir); // Allocate a `Block` for every basic block, except // the start block, if nothing loops back to it. let reentrant_start_block = !mir.predecessors_for(mir::START_BLOCK).is_empty(); - let block_bcxs: IndexVec<mir::BasicBlock, BasicBlockRef> = + let block_bxs: IndexVec<mir::BasicBlock, BasicBlockRef> = mir.basic_blocks().indices().map(|bb| { if bb == mir::START_BLOCK && !reentrant_start_block { - bcx.llbb() + bx.llbb() } else { - bcx.build_sibling_block(&format!("{:?}", bb)).llbb() + bx.build_sibling_block(&format!("{:?}", bb)).llbb() } }).collect(); // Compute debuginfo scopes from MIR scopes. - let scopes = debuginfo::create_mir_scopes(ccx, mir, &debug_context); - let (landing_pads, funclets) = create_funclets(&bcx, &cleanup_kinds, &block_bcxs); + let scopes = debuginfo::create_mir_scopes(cx, mir, &debug_context); + let (landing_pads, funclets) = create_funclets(&bx, &cleanup_kinds, &block_bxs); - let mut mircx = MirContext { + let mut fx = FunctionCx { mir, llfn, fn_ty, - ccx, + cx, personality_slot: None, - blocks: block_bcxs, + blocks: block_bxs, unreachable_block: None, cleanup_kinds, landing_pads, @@ -244,51 +244,51 @@ pub fn trans_mir<'a, 'tcx: 'a>( }, }; - let memory_locals = analyze::memory_locals(&mircx); + let memory_locals = analyze::memory_locals(&fx); // Allocate variable and temp allocas - mircx.locals = { - let args = arg_local_refs(&bcx, &mircx, &mircx.scopes, &memory_locals); + fx.locals = { + let args = arg_local_refs(&bx, &fx, &fx.scopes, &memory_locals); let mut allocate_local = |local| { let decl = &mir.local_decls[local]; - let layout = bcx.ccx.layout_of(mircx.monomorphize(&decl.ty)); + let layout = bx.cx.layout_of(fx.monomorphize(&decl.ty)); assert!(!layout.ty.has_erasable_regions()); if let Some(name) = decl.name { // User variable - let debug_scope = mircx.scopes[decl.source_info.scope]; - let dbg = debug_scope.is_valid() && bcx.sess().opts.debuginfo == FullDebugInfo; + let debug_scope = fx.scopes[decl.source_info.scope]; + let dbg = debug_scope.is_valid() && bx.sess().opts.debuginfo == FullDebugInfo; if !memory_locals.contains(local.index()) && !dbg { debug!("alloc: {:?} ({}) -> operand", local, name); - return LocalRef::new_operand(bcx.ccx, layout); + return LocalRef::new_operand(bx.cx, layout); } debug!("alloc: {:?} ({}) -> place", local, name); - let place = PlaceRef::alloca(&bcx, layout, &name.as_str()); + let place = PlaceRef::alloca(&bx, layout, &name.as_str()); if dbg { - let (scope, span) = mircx.debug_loc(decl.source_info); - declare_local(&bcx, &mircx.debug_context, name, layout.ty, scope, + let (scope, span) = fx.debug_loc(decl.source_info); + declare_local(&bx, &fx.debug_context, name, layout.ty, scope, VariableAccess::DirectVariable { alloca: place.llval }, VariableKind::LocalVariable, span); } LocalRef::Place(place) } else { // Temporary or return place - if local == mir::RETURN_PLACE && mircx.fn_ty.ret.is_indirect() { + if local == mir::RETURN_PLACE && fx.fn_ty.ret.is_indirect() { debug!("alloc: {:?} (return place) -> place", local); let llretptr = llvm::get_param(llfn, 0); LocalRef::Place(PlaceRef::new_sized(llretptr, layout, layout.align)) } else if memory_locals.contains(local.index()) { debug!("alloc: {:?} -> place", local); - LocalRef::Place(PlaceRef::alloca(&bcx, layout, &format!("{:?}", local))) + LocalRef::Place(PlaceRef::alloca(&bx, layout, &format!("{:?}", local))) } else { // If this is an immediate local, we do not create an // alloca in advance. Instead we wait until we see the // definition and update the operand there. debug!("alloc: {:?} -> operand", local); - LocalRef::new_operand(bcx.ccx, layout) + LocalRef::new_operand(bx.cx, layout) } } }; @@ -302,13 +302,13 @@ pub fn trans_mir<'a, 'tcx: 'a>( // Branch to the START block, if it's not the entry block. if reentrant_start_block { - bcx.br(mircx.blocks[mir::START_BLOCK]); + bx.br(fx.blocks[mir::START_BLOCK]); } // Up until here, IR instructions for this function have explicitly not been annotated with // source code location, so we don't step into call setup code. From here on, source location // emitting should be enabled. - debuginfo::start_emitting_source_locations(&mircx.debug_context); + debuginfo::start_emitting_source_locations(&fx.debug_context); let rpo = traversal::reverse_postorder(&mir); let mut visited = BitVector::new(mir.basic_blocks().len()); @@ -316,7 +316,7 @@ pub fn trans_mir<'a, 'tcx: 'a>( // Translate the body of each block using reverse postorder for (bb, _) in rpo { visited.insert(bb.index()); - mircx.trans_block(bb); + fx.trans_block(bb); } // Remove blocks that haven't been visited, or have no @@ -326,26 +326,26 @@ pub fn trans_mir<'a, 'tcx: 'a>( if !visited.contains(bb.index()) { debug!("trans_mir: block {:?} was not visited", bb); unsafe { - llvm::LLVMDeleteBasicBlock(mircx.blocks[bb]); + llvm::LLVMDeleteBasicBlock(fx.blocks[bb]); } } } } fn create_funclets<'a, 'tcx>( - bcx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'tcx>, cleanup_kinds: &IndexVec<mir::BasicBlock, CleanupKind>, - block_bcxs: &IndexVec<mir::BasicBlock, BasicBlockRef>) + block_bxs: &IndexVec<mir::BasicBlock, BasicBlockRef>) -> (IndexVec<mir::BasicBlock, Option<BasicBlockRef>>, IndexVec<mir::BasicBlock, Option<Funclet>>) { - block_bcxs.iter_enumerated().zip(cleanup_kinds).map(|((bb, &llbb), cleanup_kind)| { + block_bxs.iter_enumerated().zip(cleanup_kinds).map(|((bb, &llbb), cleanup_kind)| { match *cleanup_kind { - CleanupKind::Funclet if base::wants_msvc_seh(bcx.sess()) => { - let cleanup_bcx = bcx.build_sibling_block(&format!("funclet_{:?}", bb)); - let cleanup = cleanup_bcx.cleanup_pad(None, &[]); - cleanup_bcx.br(llbb); - (Some(cleanup_bcx.llbb()), Some(Funclet::new(cleanup))) + CleanupKind::Funclet if base::wants_msvc_seh(bx.sess()) => { + let cleanup_bx = bx.build_sibling_block(&format!("funclet_{:?}", bb)); + let cleanup = cleanup_bx.cleanup_pad(None, &[]); + cleanup_bx.br(llbb); + (Some(cleanup_bx.llbb()), Some(Funclet::new(cleanup))) } _ => (None, None) } @@ -355,19 +355,19 @@ fn create_funclets<'a, 'tcx>( /// Produce, for each argument, a `ValueRef` pointing at the /// argument's value. As arguments are places, these are always /// indirect. -fn arg_local_refs<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, - mircx: &MirContext<'a, 'tcx>, +fn arg_local_refs<'a, 'tcx>(bx: &Builder<'a, 'tcx>, + fx: &FunctionCx<'a, 'tcx>, scopes: &IndexVec<mir::VisibilityScope, debuginfo::MirDebugScope>, memory_locals: &BitVector) -> Vec<LocalRef<'tcx>> { - let mir = mircx.mir; - let tcx = bcx.tcx(); + let mir = fx.mir; + let tcx = bx.tcx(); let mut idx = 0; - let mut llarg_idx = mircx.fn_ty.ret.is_indirect() as usize; + let mut llarg_idx = fx.fn_ty.ret.is_indirect() as usize; // Get the argument scope, if it exists and if we need it. let arg_scope = scopes[mir::ARGUMENT_VISIBILITY_SCOPE]; - let arg_scope = if arg_scope.is_valid() && bcx.sess().opts.debuginfo == FullDebugInfo { + let arg_scope = if arg_scope.is_valid() && bx.sess().opts.debuginfo == FullDebugInfo { Some(arg_scope.scope_metadata) } else { None @@ -392,17 +392,20 @@ fn arg_local_refs<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, // to reconstruct it into a tuple local variable, from multiple // individual LLVM function arguments. - let arg_ty = mircx.monomorphize(&arg_decl.ty); + let arg_ty = fx.monomorphize(&arg_decl.ty); let tupled_arg_tys = match arg_ty.sty { ty::TyTuple(ref tys, _) => tys, _ => bug!("spread argument isn't a tuple?!") }; - let place = PlaceRef::alloca(bcx, bcx.ccx.layout_of(arg_ty), &name); + let place = PlaceRef::alloca(bx, bx.cx.layout_of(arg_ty), &name); for i in 0..tupled_arg_tys.len() { - let arg = &mircx.fn_ty.args[idx]; + let arg = &fx.fn_ty.args[idx]; idx += 1; - arg.store_fn_arg(bcx, &mut llarg_idx, place.project_field(bcx, i)); + if arg.pad.is_some() { + llarg_idx += 1; + } + arg.store_fn_arg(bx, &mut llarg_idx, place.project_field(bx, i)); } // Now that we have one alloca that contains the aggregate value, @@ -412,8 +415,8 @@ fn arg_local_refs<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, alloca: place.llval }; declare_local( - bcx, - &mircx.debug_context, + bx, + &fx.debug_context, arg_decl.name.unwrap_or(keywords::Invalid.name()), arg_ty, scope, variable_access, @@ -425,7 +428,7 @@ fn arg_local_refs<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, return LocalRef::Place(place); } - let arg = &mircx.fn_ty.args[idx]; + let arg = &fx.fn_ty.args[idx]; idx += 1; if arg.pad.is_some() { llarg_idx += 1; @@ -438,22 +441,22 @@ fn arg_local_refs<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, let local = |op| LocalRef::Operand(Some(op)); match arg.mode { PassMode::Ignore => { - return local(OperandRef::new_zst(bcx.ccx, arg.layout)); + return local(OperandRef::new_zst(bx.cx, arg.layout)); } PassMode::Direct(_) => { - let llarg = llvm::get_param(bcx.llfn(), llarg_idx as c_uint); - bcx.set_value_name(llarg, &name); + let llarg = llvm::get_param(bx.llfn(), llarg_idx as c_uint); + bx.set_value_name(llarg, &name); llarg_idx += 1; return local( - OperandRef::from_immediate_or_packed_pair(bcx, llarg, arg.layout)); + OperandRef::from_immediate_or_packed_pair(bx, llarg, arg.layout)); } PassMode::Pair(..) => { - let a = llvm::get_param(bcx.llfn(), llarg_idx as c_uint); - bcx.set_value_name(a, &(name.clone() + ".0")); + let a = llvm::get_param(bx.llfn(), llarg_idx as c_uint); + bx.set_value_name(a, &(name.clone() + ".0")); llarg_idx += 1; - let b = llvm::get_param(bcx.llfn(), llarg_idx as c_uint); - bcx.set_value_name(b, &(name + ".1")); + let b = llvm::get_param(bx.llfn(), llarg_idx as c_uint); + bx.set_value_name(b, &(name + ".1")); llarg_idx += 1; return local(OperandRef { @@ -469,13 +472,13 @@ fn arg_local_refs<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, // Don't copy an indirect argument to an alloca, the caller // already put it in a temporary alloca and gave it up. // FIXME: lifetimes - let llarg = llvm::get_param(bcx.llfn(), llarg_idx as c_uint); - bcx.set_value_name(llarg, &name); + let llarg = llvm::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) } else { - let tmp = PlaceRef::alloca(bcx, arg.layout, &name); - arg.store_fn_arg(bcx, &mut llarg_idx, tmp); + let tmp = PlaceRef::alloca(bx, arg.layout, &name); + arg.store_fn_arg(bx, &mut llarg_idx, tmp); tmp }; arg_scope.map(|scope| { @@ -498,8 +501,8 @@ fn arg_local_refs<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, } declare_local( - bcx, - &mircx.debug_context, + bx, + &fx.debug_context, arg_decl.name.unwrap_or(keywords::Invalid.name()), arg.layout.ty, scope, @@ -512,7 +515,7 @@ fn arg_local_refs<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, // Or is it the closure environment? let (closure_layout, env_ref) = match arg.layout.ty.sty { - ty::TyRef(_, mt) | ty::TyRawPtr(mt) => (bcx.ccx.layout_of(mt.ty), true), + ty::TyRef(_, mt) | ty::TyRawPtr(mt) => (bx.cx.layout_of(mt.ty), true), _ => (arg.layout, false) }; @@ -530,10 +533,10 @@ fn arg_local_refs<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, // doesn't actually strip the offset when splitting the closure // environment into its components so it ends up out of bounds. let env_ptr = if !env_ref { - let scratch = PlaceRef::alloca(bcx, - bcx.ccx.layout_of(tcx.mk_mut_ptr(arg.layout.ty)), + let scratch = PlaceRef::alloca(bx, + bx.cx.layout_of(tcx.mk_mut_ptr(arg.layout.ty)), "__debuginfo_env_ptr"); - bcx.store(place.llval, scratch.llval, scratch.align); + bx.store(place.llval, scratch.llval, scratch.align); scratch.llval } else { place.llval @@ -567,8 +570,8 @@ fn arg_local_refs<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, address_operations: &ops }; declare_local( - bcx, - &mircx.debug_context, + bx, + &fx.debug_context, decl.debug_name, ty, scope, diff --git a/src/librustc_trans/mir/operand.rs b/src/librustc_trans/mir/operand.rs index 05af48761a1..25db9f9b4c8 100644 --- a/src/librustc_trans/mir/operand.rs +++ b/src/librustc_trans/mir/operand.rs @@ -15,7 +15,7 @@ use rustc::mir; use rustc_data_structures::indexed_vec::Idx; use base; -use common::{self, CrateContext, C_undef, C_usize}; +use common::{self, CodegenCx, C_undef, C_usize}; use builder::Builder; use value::Value; use type_of::LayoutLlvmExt; @@ -24,7 +24,7 @@ use type_::Type; use std::fmt; use std::ptr; -use super::{MirContext, LocalRef}; +use super::{FunctionCx, LocalRef}; use super::place::PlaceRef; /// The representation of a Rust value. The enum variant is in fact @@ -81,11 +81,11 @@ impl<'tcx> fmt::Debug for OperandRef<'tcx> { } impl<'a, 'tcx> OperandRef<'tcx> { - pub fn new_zst(ccx: &CrateContext<'a, 'tcx>, + pub fn new_zst(cx: &CodegenCx<'a, 'tcx>, layout: TyLayout<'tcx>) -> OperandRef<'tcx> { assert!(layout.is_zst()); OperandRef { - val: OperandValue::Immediate(C_undef(layout.immediate_llvm_type(ccx))), + val: OperandValue::Immediate(C_undef(layout.immediate_llvm_type(cx))), layout } } @@ -99,7 +99,7 @@ impl<'a, 'tcx> OperandRef<'tcx> { } } - pub fn deref(self, ccx: &CrateContext<'a, 'tcx>) -> PlaceRef<'tcx> { + pub fn deref(self, cx: &CodegenCx<'a, 'tcx>) -> PlaceRef<'tcx> { let projected_ty = self.layout.ty.builtin_deref(true, ty::NoPreference) .unwrap_or_else(|| bug!("deref of non-pointer {:?}", self)).ty; let (llptr, llextra) = match self.val { @@ -107,7 +107,7 @@ impl<'a, 'tcx> OperandRef<'tcx> { OperandValue::Pair(llptr, llextra) => (llptr, llextra), OperandValue::Ref(..) => bug!("Deref of by-Ref operand {:?}", self) }; - let layout = ccx.layout_of(projected_ty); + let layout = cx.layout_of(projected_ty); PlaceRef { llval: llptr, llextra, @@ -118,15 +118,15 @@ impl<'a, 'tcx> OperandRef<'tcx> { /// If this operand is a `Pair`, we return an aggregate with the two values. /// For other cases, see `immediate`. - pub fn immediate_or_packed_pair(self, bcx: &Builder<'a, 'tcx>) -> ValueRef { + pub fn immediate_or_packed_pair(self, bx: &Builder<'a, 'tcx>) -> ValueRef { if let OperandValue::Pair(a, b) = self.val { - let llty = self.layout.llvm_type(bcx.ccx); + let llty = self.layout.llvm_type(bx.cx); debug!("Operand::immediate_or_packed_pair: packing {:?} into {:?}", self, llty); // Reconstruct the immediate aggregate. let mut llpair = C_undef(llty); - llpair = bcx.insert_value(llpair, a, 0); - llpair = bcx.insert_value(llpair, b, 1); + llpair = bx.insert_value(llpair, a, 0); + llpair = bx.insert_value(llpair, b, 1); llpair } else { self.immediate() @@ -134,7 +134,7 @@ impl<'a, 'tcx> OperandRef<'tcx> { } /// If the type is a pair, we return a `Pair`, otherwise, an `Immediate`. - pub fn from_immediate_or_packed_pair(bcx: &Builder<'a, 'tcx>, + pub fn from_immediate_or_packed_pair(bx: &Builder<'a, 'tcx>, llval: ValueRef, layout: TyLayout<'tcx>) -> OperandRef<'tcx> { @@ -143,23 +143,23 @@ impl<'a, 'tcx> OperandRef<'tcx> { llval, layout); // Deconstruct the immediate aggregate. - OperandValue::Pair(bcx.extract_value(llval, 0), - bcx.extract_value(llval, 1)) + OperandValue::Pair(bx.extract_value(llval, 0), + bx.extract_value(llval, 1)) } else { OperandValue::Immediate(llval) }; OperandRef { val, layout } } - pub fn extract_field(&self, bcx: &Builder<'a, 'tcx>, i: usize) -> OperandRef<'tcx> { - let field = self.layout.field(bcx.ccx, i); + pub fn extract_field(&self, bx: &Builder<'a, 'tcx>, i: usize) -> OperandRef<'tcx> { + let field = self.layout.field(bx.cx, i); let offset = self.layout.fields.offset(i); let mut val = match (self.val, &self.layout.abi) { // If we're uninhabited, or the field is ZST, it has no data. _ if self.layout.abi == layout::Abi::Uninhabited || field.is_zst() => { return OperandRef { - val: OperandValue::Immediate(C_undef(field.immediate_llvm_type(bcx.ccx))), + val: OperandValue::Immediate(C_undef(field.immediate_llvm_type(bx.cx))), layout: field }; } @@ -174,12 +174,12 @@ impl<'a, 'tcx> OperandRef<'tcx> { // Extract a scalar component from a pair. (OperandValue::Pair(a_llval, b_llval), &layout::Abi::ScalarPair(ref a, ref b)) => { if offset.bytes() == 0 { - assert_eq!(field.size, a.value.size(bcx.ccx)); + assert_eq!(field.size, a.value.size(bx.cx)); OperandValue::Immediate(a_llval) } else { - assert_eq!(offset, a.value.size(bcx.ccx) - .abi_align(b.value.align(bcx.ccx))); - assert_eq!(field.size, b.value.size(bcx.ccx)); + assert_eq!(offset, a.value.size(bx.cx) + .abi_align(b.value.align(bx.cx))); + assert_eq!(field.size, b.value.size(bx.cx)); OperandValue::Immediate(b_llval) } } @@ -187,7 +187,7 @@ impl<'a, 'tcx> OperandRef<'tcx> { // `#[repr(simd)]` types are also immediate. (OperandValue::Immediate(llval), &layout::Abi::Vector { .. }) => { OperandValue::Immediate( - bcx.extract_element(llval, C_usize(bcx.ccx, i as u64))) + bx.extract_element(llval, C_usize(bx.cx, i as u64))) } _ => bug!("OperandRef::extract_field({:?}): not applicable", self) @@ -196,11 +196,11 @@ impl<'a, 'tcx> OperandRef<'tcx> { // HACK(eddyb) have to bitcast pointers until LLVM removes pointee types. match val { OperandValue::Immediate(ref mut llval) => { - *llval = bcx.bitcast(*llval, field.immediate_llvm_type(bcx.ccx)); + *llval = bx.bitcast(*llval, field.immediate_llvm_type(bx.cx)); } OperandValue::Pair(ref mut a, ref mut b) => { - *a = bcx.bitcast(*a, field.scalar_pair_element_llvm_type(bcx.ccx, 0)); - *b = bcx.bitcast(*b, field.scalar_pair_element_llvm_type(bcx.ccx, 1)); + *a = bx.bitcast(*a, field.scalar_pair_element_llvm_type(bx.cx, 0)); + *b = bx.bitcast(*b, field.scalar_pair_element_llvm_type(bx.cx, 1)); } OperandValue::Ref(..) => bug!() } @@ -213,7 +213,7 @@ impl<'a, 'tcx> OperandRef<'tcx> { } impl<'a, 'tcx> OperandValue { - pub fn store(self, bcx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) { + pub fn store(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) { debug!("OperandRef::store: operand={:?}, dest={:?}", self, dest); // Avoid generating stores of zero-sized values, because the only way to have a zero-sized // value is through `undef`, and store itself is useless. @@ -222,28 +222,28 @@ impl<'a, 'tcx> OperandValue { } match self { OperandValue::Ref(r, source_align) => - base::memcpy_ty(bcx, dest.llval, r, dest.layout, + base::memcpy_ty(bx, dest.llval, r, dest.layout, source_align.min(dest.align)), OperandValue::Immediate(s) => { - bcx.store(base::from_immediate(bcx, s), dest.llval, dest.align); + bx.store(base::from_immediate(bx, s), dest.llval, dest.align); } OperandValue::Pair(a, b) => { for (i, &x) in [a, b].iter().enumerate() { - let mut llptr = bcx.struct_gep(dest.llval, i as u64); + let mut llptr = bx.struct_gep(dest.llval, i as u64); // Make sure to always store i1 as i8. - if common::val_ty(x) == Type::i1(bcx.ccx) { - llptr = bcx.pointercast(llptr, Type::i8p(bcx.ccx)); + if common::val_ty(x) == Type::i1(bx.cx) { + llptr = bx.pointercast(llptr, Type::i8p(bx.cx)); } - bcx.store(base::from_immediate(bcx, x), llptr, dest.align); + bx.store(base::from_immediate(bx, x), llptr, dest.align); } } } } } -impl<'a, 'tcx> MirContext<'a, 'tcx> { +impl<'a, 'tcx> FunctionCx<'a, 'tcx> { fn maybe_trans_consume_direct(&mut self, - bcx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'tcx>, place: &mir::Place<'tcx>) -> Option<OperandRef<'tcx>> { @@ -267,19 +267,19 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { // Moves out of scalar and scalar pair fields are trivial. if let &mir::Place::Projection(ref proj) = place { - if let Some(o) = self.maybe_trans_consume_direct(bcx, &proj.base) { + if let Some(o) = self.maybe_trans_consume_direct(bx, &proj.base) { match proj.elem { mir::ProjectionElem::Field(ref f, _) => { - return Some(o.extract_field(bcx, f.index())); + return Some(o.extract_field(bx, f.index())); } mir::ProjectionElem::Index(_) | mir::ProjectionElem::ConstantIndex { .. } => { // ZSTs don't require any actual memory access. // FIXME(eddyb) deduplicate this with the identical // checks in `trans_consume` and `extract_field`. - let elem = o.layout.field(bcx.ccx, 0); + let elem = o.layout.field(bx.cx, 0); if elem.is_zst() { - return Some(OperandRef::new_zst(bcx.ccx, elem)); + return Some(OperandRef::new_zst(bx.cx, elem)); } } _ => {} @@ -291,31 +291,31 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { } pub fn trans_consume(&mut self, - bcx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'tcx>, place: &mir::Place<'tcx>) -> OperandRef<'tcx> { debug!("trans_consume(place={:?})", place); let ty = self.monomorphized_place_ty(place); - let layout = bcx.ccx.layout_of(ty); + let layout = bx.cx.layout_of(ty); // ZSTs don't require any actual memory access. if layout.is_zst() { - return OperandRef::new_zst(bcx.ccx, layout); + return OperandRef::new_zst(bx.cx, layout); } - if let Some(o) = self.maybe_trans_consume_direct(bcx, place) { + if let Some(o) = self.maybe_trans_consume_direct(bx, place) { return o; } // for most places, to consume them we just load them // out from their home - self.trans_place(bcx, place).load(bcx) + self.trans_place(bx, place).load(bx) } pub fn trans_operand(&mut self, - bcx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'tcx>, operand: &mir::Operand<'tcx>) -> OperandRef<'tcx> { @@ -324,15 +324,15 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { match *operand { mir::Operand::Copy(ref place) | mir::Operand::Move(ref place) => { - self.trans_consume(bcx, place) + self.trans_consume(bx, place) } mir::Operand::Constant(ref constant) => { - let val = self.trans_constant(&bcx, constant); - let operand = val.to_operand(bcx.ccx); + let val = self.trans_constant(&bx, constant); + let operand = val.to_operand(bx.cx); if let OperandValue::Ref(ptr, align) = operand.val { // If this is a OperandValue::Ref to an immediate constant, load it. - PlaceRef::new_sized(ptr, operand.layout, align).load(bcx) + PlaceRef::new_sized(ptr, operand.layout, align).load(bx) } else { operand } diff --git a/src/librustc_trans/mir/place.rs b/src/librustc_trans/mir/place.rs index b556b6a1323..99770476e12 100644 --- a/src/librustc_trans/mir/place.rs +++ b/src/librustc_trans/mir/place.rs @@ -16,7 +16,7 @@ use rustc::mir::tcx::PlaceTy; use rustc_data_structures::indexed_vec::Idx; use base; use builder::Builder; -use common::{CrateContext, C_usize, C_u8, C_u32, C_uint, C_int, C_null, C_uint_big}; +use common::{CodegenCx, C_usize, C_u8, C_u32, C_uint, C_int, C_null, C_uint_big}; use consts; use type_of::LayoutLlvmExt; use type_::Type; @@ -25,7 +25,7 @@ use glue; use std::ptr; -use super::{MirContext, LocalRef}; +use super::{FunctionCx, LocalRef}; use super::operand::{OperandRef, OperandValue}; #[derive(Copy, Clone, Debug)] @@ -56,21 +56,21 @@ impl<'a, 'tcx> PlaceRef<'tcx> { } } - pub fn alloca(bcx: &Builder<'a, 'tcx>, layout: TyLayout<'tcx>, name: &str) + pub fn alloca(bx: &Builder<'a, 'tcx>, layout: TyLayout<'tcx>, name: &str) -> PlaceRef<'tcx> { debug!("alloca({:?}: {:?})", name, layout); - let tmp = bcx.alloca(layout.llvm_type(bcx.ccx), name, layout.align); + let tmp = bx.alloca(layout.llvm_type(bx.cx), name, layout.align); Self::new_sized(tmp, layout, layout.align) } - pub fn len(&self, ccx: &CrateContext<'a, 'tcx>) -> ValueRef { + pub fn len(&self, cx: &CodegenCx<'a, 'tcx>) -> ValueRef { if let layout::FieldPlacement::Array { count, .. } = self.layout.fields { if self.layout.is_unsized() { assert!(self.has_extra()); assert_eq!(count, 0); self.llextra } else { - C_usize(ccx, count) + C_usize(cx, count) } } else { bug!("unexpected layout `{:#?}` in PlaceRef::len", self.layout) @@ -81,19 +81,19 @@ impl<'a, 'tcx> PlaceRef<'tcx> { !self.llextra.is_null() } - pub fn load(&self, bcx: &Builder<'a, 'tcx>) -> OperandRef<'tcx> { + pub fn load(&self, bx: &Builder<'a, 'tcx>) -> OperandRef<'tcx> { debug!("PlaceRef::load: {:?}", self); assert!(!self.has_extra()); if self.layout.is_zst() { - return OperandRef::new_zst(bcx.ccx, self.layout); + return OperandRef::new_zst(bx.cx, self.layout); } let scalar_load_metadata = |load, scalar: &layout::Scalar| { let (min, max) = (scalar.valid_range.start, scalar.valid_range.end); let max_next = max.wrapping_add(1); - let bits = scalar.value.size(bcx.ccx).bits(); + let bits = scalar.value.size(bx.cx).bits(); assert!(bits <= 128); let mask = !0u128 >> (128 - bits); // For a (max) value of -1, max will be `-1 as usize`, which overflows. @@ -106,10 +106,10 @@ impl<'a, 'tcx> PlaceRef<'tcx> { layout::Int(..) if max_next & mask != min & mask => { // llvm::ConstantRange can deal with ranges that wrap around, // so an overflow on (max + 1) is fine. - bcx.range_metadata(load, min..max_next); + bx.range_metadata(load, min..max_next); } layout::Pointer if 0 < min && min < max => { - bcx.nonnull_metadata(load); + bx.nonnull_metadata(load); } _ => {} } @@ -127,24 +127,24 @@ impl<'a, 'tcx> PlaceRef<'tcx> { let llval = if !const_llval.is_null() { const_llval } else { - let load = bcx.load(self.llval, self.align); + let load = bx.load(self.llval, self.align); if let layout::Abi::Scalar(ref scalar) = self.layout.abi { scalar_load_metadata(load, scalar); } load }; - OperandValue::Immediate(base::to_immediate(bcx, llval, self.layout)) + OperandValue::Immediate(base::to_immediate(bx, llval, self.layout)) } else if let layout::Abi::ScalarPair(ref a, ref b) = self.layout.abi { let load = |i, scalar: &layout::Scalar| { - let mut llptr = bcx.struct_gep(self.llval, i as u64); + let mut llptr = bx.struct_gep(self.llval, i as u64); // Make sure to always load i1 as i8. if scalar.is_bool() { - llptr = bcx.pointercast(llptr, Type::i8p(bcx.ccx)); + llptr = bx.pointercast(llptr, Type::i8p(bx.cx)); } - let load = bcx.load(llptr, self.align); + let load = bx.load(llptr, self.align); scalar_load_metadata(load, scalar); if scalar.is_bool() { - bcx.trunc(load, Type::i1(bcx.ccx)) + bx.trunc(load, Type::i1(bx.cx)) } else { load } @@ -158,9 +158,9 @@ impl<'a, 'tcx> PlaceRef<'tcx> { } /// Access a field, at a point when the value's case is known. - pub fn project_field(self, bcx: &Builder<'a, 'tcx>, ix: usize) -> PlaceRef<'tcx> { - let ccx = bcx.ccx; - let field = self.layout.field(ccx, ix); + pub fn project_field(self, bx: &Builder<'a, 'tcx>, ix: usize) -> PlaceRef<'tcx> { + let cx = bx.cx; + let field = self.layout.field(cx, ix); let offset = self.layout.fields.offset(ix); let align = self.align.min(self.layout.align).min(field.align); @@ -170,15 +170,15 @@ impl<'a, 'tcx> PlaceRef<'tcx> { 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(ccx).abi_align(b.value.align(ccx))); - bcx.struct_gep(self.llval, 1) + assert_eq!(offset, a.value.size(cx).abi_align(b.value.align(cx))); + bx.struct_gep(self.llval, 1) } else { - bcx.struct_gep(self.llval, self.layout.llvm_field_index(ix)) + bx.struct_gep(self.llval, self.layout.llvm_field_index(ix)) }; PlaceRef { // HACK(eddyb) have to bitcast pointers until LLVM removes pointee types. - llval: bcx.pointercast(llval, field.llvm_type(ccx).ptr_to()), - llextra: if ccx.shared().type_has_metadata(field.ty) { + llval: bx.pointercast(llval, field.llvm_type(cx).ptr_to()), + llextra: if cx.type_has_metadata(field.ty) { self.llextra } else { ptr::null_mut() @@ -228,10 +228,10 @@ impl<'a, 'tcx> PlaceRef<'tcx> { let meta = self.llextra; - let unaligned_offset = C_usize(ccx, offset.bytes()); + let unaligned_offset = C_usize(cx, offset.bytes()); // Get the alignment of the field - let (_, unsized_align) = glue::size_and_align_of_dst(bcx, field.ty, meta); + let (_, unsized_align) = glue::size_and_align_of_dst(bx, field.ty, meta); // Bump the unaligned offset up to the appropriate alignment using the // following expression: @@ -239,22 +239,22 @@ impl<'a, 'tcx> PlaceRef<'tcx> { // (unaligned offset + (align - 1)) & -align // Calculate offset - let align_sub_1 = bcx.sub(unsized_align, C_usize(ccx, 1u64)); - let offset = bcx.and(bcx.add(unaligned_offset, align_sub_1), - bcx.neg(unsized_align)); + let align_sub_1 = bx.sub(unsized_align, C_usize(cx, 1u64)); + let offset = bx.and(bx.add(unaligned_offset, align_sub_1), + bx.neg(unsized_align)); debug!("struct_field_ptr: DST field offset: {:?}", Value(offset)); // Cast and adjust pointer - let byte_ptr = bcx.pointercast(self.llval, Type::i8p(ccx)); - let byte_ptr = bcx.gep(byte_ptr, &[offset]); + let byte_ptr = bx.pointercast(self.llval, Type::i8p(cx)); + let byte_ptr = bx.gep(byte_ptr, &[offset]); // Finally, cast back to the type expected - let ll_fty = field.llvm_type(ccx); + let ll_fty = field.llvm_type(cx); debug!("struct_field_ptr: Field type is {:?}", ll_fty); PlaceRef { - llval: bcx.pointercast(byte_ptr, ll_fty.ptr_to()), + llval: bx.pointercast(byte_ptr, ll_fty.ptr_to()), llextra: self.llextra, layout: field, align, @@ -262,8 +262,8 @@ impl<'a, 'tcx> PlaceRef<'tcx> { } /// Obtain the actual discriminant of a value. - pub fn trans_get_discr(self, bcx: &Builder<'a, 'tcx>, cast_to: Ty<'tcx>) -> ValueRef { - let cast_to = bcx.ccx.layout_of(cast_to).immediate_llvm_type(bcx.ccx); + pub fn trans_get_discr(self, bx: &Builder<'a, 'tcx>, cast_to: Ty<'tcx>) -> ValueRef { + let cast_to = bx.cx.layout_of(cast_to).immediate_llvm_type(bx.cx); match self.layout.variants { layout::Variants::Single { index } => { return C_uint(cast_to, index as u64); @@ -272,8 +272,8 @@ impl<'a, 'tcx> PlaceRef<'tcx> { layout::Variants::NicheFilling { .. } => {}, } - let discr = self.project_field(bcx, 0); - let lldiscr = discr.load(bcx).immediate(); + let discr = self.project_field(bx, 0); + let lldiscr = discr.load(bx).immediate(); match self.layout.variants { layout::Variants::Single { .. } => bug!(), layout::Variants::Tagged { ref discr, .. } => { @@ -281,7 +281,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> { layout::Int(_, signed) => signed, _ => false }; - bcx.intcast(lldiscr, cast_to, signed) + bx.intcast(lldiscr, cast_to, signed) } layout::Variants::NicheFilling { dataful_variant, @@ -289,7 +289,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> { niche_start, .. } => { - let niche_llty = discr.layout.immediate_llvm_type(bcx.ccx); + let niche_llty = discr.layout.immediate_llvm_type(bx.cx); if niche_variants.start == niche_variants.end { // FIXME(eddyb) Check the actual primitive type here. let niche_llval = if niche_start == 0 { @@ -298,16 +298,16 @@ impl<'a, 'tcx> PlaceRef<'tcx> { } else { C_uint_big(niche_llty, niche_start) }; - bcx.select(bcx.icmp(llvm::IntEQ, lldiscr, niche_llval), + bx.select(bx.icmp(llvm::IntEQ, lldiscr, niche_llval), C_uint(cast_to, niche_variants.start as u64), C_uint(cast_to, dataful_variant as u64)) } else { // Rebase from niche values to discriminant values. let delta = niche_start.wrapping_sub(niche_variants.start as u128); - let lldiscr = bcx.sub(lldiscr, C_uint_big(niche_llty, delta)); + let lldiscr = bx.sub(lldiscr, C_uint_big(niche_llty, delta)); let lldiscr_max = C_uint(niche_llty, niche_variants.end as u64); - bcx.select(bcx.icmp(llvm::IntULE, lldiscr, lldiscr_max), - bcx.intcast(lldiscr, cast_to, false), + bx.select(bx.icmp(llvm::IntULE, lldiscr, lldiscr_max), + bx.intcast(lldiscr, cast_to, false), C_uint(cast_to, dataful_variant as u64)) } } @@ -316,8 +316,8 @@ impl<'a, 'tcx> PlaceRef<'tcx> { /// Set the discriminant for a new value of the given case of the given /// representation. - pub fn trans_set_discr(&self, bcx: &Builder<'a, 'tcx>, variant_index: usize) { - if self.layout.for_variant(bcx.ccx, variant_index).abi == layout::Abi::Uninhabited { + pub fn trans_set_discr(&self, bx: &Builder<'a, 'tcx>, variant_index: usize) { + if self.layout.for_variant(bx.cx, variant_index).abi == layout::Abi::Uninhabited { return; } match self.layout.variants { @@ -325,11 +325,11 @@ impl<'a, 'tcx> PlaceRef<'tcx> { assert_eq!(index, variant_index); } layout::Variants::Tagged { .. } => { - let ptr = self.project_field(bcx, 0); + let ptr = self.project_field(bx, 0); let to = self.layout.ty.ty_adt_def().unwrap() - .discriminant_for_variant(bcx.tcx(), variant_index) + .discriminant_for_variant(bx.tcx(), variant_index) .to_u128_unchecked() as u64; - bcx.store(C_int(ptr.layout.llvm_type(bcx.ccx), to as i64), + bx.store(C_int(ptr.layout.llvm_type(bx.cx), to as i64), ptr.llval, ptr.align); } layout::Variants::NicheFilling { @@ -339,20 +339,20 @@ impl<'a, 'tcx> PlaceRef<'tcx> { .. } => { if variant_index != dataful_variant { - if bcx.sess().target.target.arch == "arm" || - bcx.sess().target.target.arch == "aarch64" { + if bx.sess().target.target.arch == "arm" || + bx.sess().target.target.arch == "aarch64" { // Issue #34427: As workaround for LLVM bug on ARM, // use memset of 0 before assigning niche value. - let llptr = bcx.pointercast(self.llval, Type::i8(bcx.ccx).ptr_to()); - let fill_byte = C_u8(bcx.ccx, 0); + let llptr = bx.pointercast(self.llval, Type::i8(bx.cx).ptr_to()); + let fill_byte = C_u8(bx.cx, 0); let (size, align) = self.layout.size_and_align(); - let size = C_usize(bcx.ccx, size.bytes()); - let align = C_u32(bcx.ccx, align.abi() as u32); - base::call_memset(bcx, llptr, fill_byte, size, align, false); + let size = C_usize(bx.cx, size.bytes()); + let align = C_u32(bx.cx, align.abi() as u32); + base::call_memset(bx, llptr, fill_byte, size, align, false); } - let niche = self.project_field(bcx, 0); - let niche_llty = niche.layout.immediate_llvm_type(bcx.ccx); + let niche = self.project_field(bx, 0); + let niche_llty = niche.layout.immediate_llvm_type(bx.cx); let niche_value = ((variant_index - niche_variants.start) as u128) .wrapping_add(niche_start); // FIXME(eddyb) Check the actual primitive type here. @@ -362,52 +362,52 @@ impl<'a, 'tcx> PlaceRef<'tcx> { } else { C_uint_big(niche_llty, niche_value) }; - OperandValue::Immediate(niche_llval).store(bcx, niche); + OperandValue::Immediate(niche_llval).store(bx, niche); } } } } - pub fn project_index(&self, bcx: &Builder<'a, 'tcx>, llindex: ValueRef) + pub fn project_index(&self, bx: &Builder<'a, 'tcx>, llindex: ValueRef) -> PlaceRef<'tcx> { PlaceRef { - llval: bcx.inbounds_gep(self.llval, &[C_usize(bcx.ccx, 0), llindex]), + llval: bx.inbounds_gep(self.llval, &[C_usize(bx.cx, 0), llindex]), llextra: ptr::null_mut(), - layout: self.layout.field(bcx.ccx, 0), + layout: self.layout.field(bx.cx, 0), align: self.align } } - pub fn project_downcast(&self, bcx: &Builder<'a, 'tcx>, variant_index: usize) + pub fn project_downcast(&self, bx: &Builder<'a, 'tcx>, variant_index: usize) -> PlaceRef<'tcx> { let mut downcast = *self; - downcast.layout = self.layout.for_variant(bcx.ccx, variant_index); + downcast.layout = self.layout.for_variant(bx.cx, variant_index); // Cast to the appropriate variant struct type. - let variant_ty = downcast.layout.llvm_type(bcx.ccx); - downcast.llval = bcx.pointercast(downcast.llval, variant_ty.ptr_to()); + let variant_ty = downcast.layout.llvm_type(bx.cx); + downcast.llval = bx.pointercast(downcast.llval, variant_ty.ptr_to()); downcast } - pub fn storage_live(&self, bcx: &Builder<'a, 'tcx>) { - bcx.lifetime_start(self.llval, self.layout.size); + pub fn storage_live(&self, bx: &Builder<'a, 'tcx>) { + bx.lifetime_start(self.llval, self.layout.size); } - pub fn storage_dead(&self, bcx: &Builder<'a, 'tcx>) { - bcx.lifetime_end(self.llval, self.layout.size); + pub fn storage_dead(&self, bx: &Builder<'a, 'tcx>) { + bx.lifetime_end(self.llval, self.layout.size); } } -impl<'a, 'tcx> MirContext<'a, 'tcx> { +impl<'a, 'tcx> FunctionCx<'a, 'tcx> { pub fn trans_place(&mut self, - bcx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'tcx>, place: &mir::Place<'tcx>) -> PlaceRef<'tcx> { debug!("trans_place(place={:?})", place); - let ccx = bcx.ccx; - let tcx = ccx.tcx(); + let cx = bx.cx; + let tcx = cx.tcx; if let mir::Place::Local(index) = *place { match self.locals[index] { @@ -423,66 +423,66 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { let result = match *place { mir::Place::Local(_) => bug!(), // handled above mir::Place::Static(box mir::Static { def_id, ty }) => { - let layout = ccx.layout_of(self.monomorphize(&ty)); - PlaceRef::new_sized(consts::get_static(ccx, def_id), layout, layout.align) + let layout = cx.layout_of(self.monomorphize(&ty)); + PlaceRef::new_sized(consts::get_static(cx, def_id), layout, layout.align) }, mir::Place::Projection(box mir::Projection { ref base, elem: mir::ProjectionElem::Deref }) => { // Load the pointer from its location. - self.trans_consume(bcx, base).deref(bcx.ccx) + self.trans_consume(bx, base).deref(bx.cx) } mir::Place::Projection(ref projection) => { - let tr_base = self.trans_place(bcx, &projection.base); + let tr_base = self.trans_place(bx, &projection.base); match projection.elem { mir::ProjectionElem::Deref => bug!(), mir::ProjectionElem::Field(ref field, _) => { - tr_base.project_field(bcx, field.index()) + tr_base.project_field(bx, field.index()) } mir::ProjectionElem::Index(index) => { let index = &mir::Operand::Copy(mir::Place::Local(index)); - let index = self.trans_operand(bcx, index); + let index = self.trans_operand(bx, index); let llindex = index.immediate(); - tr_base.project_index(bcx, llindex) + tr_base.project_index(bx, llindex) } mir::ProjectionElem::ConstantIndex { offset, from_end: false, min_length: _ } => { - let lloffset = C_usize(bcx.ccx, offset as u64); - tr_base.project_index(bcx, lloffset) + let lloffset = C_usize(bx.cx, offset as u64); + tr_base.project_index(bx, lloffset) } mir::ProjectionElem::ConstantIndex { offset, from_end: true, min_length: _ } => { - let lloffset = C_usize(bcx.ccx, offset as u64); - let lllen = tr_base.len(bcx.ccx); - let llindex = bcx.sub(lllen, lloffset); - tr_base.project_index(bcx, llindex) + let lloffset = C_usize(bx.cx, offset as u64); + let lllen = tr_base.len(bx.cx); + let llindex = bx.sub(lllen, lloffset); + tr_base.project_index(bx, llindex) } mir::ProjectionElem::Subslice { from, to } => { - let mut subslice = tr_base.project_index(bcx, - C_usize(bcx.ccx, from as u64)); + let mut subslice = tr_base.project_index(bx, + C_usize(bx.cx, from as u64)); let projected_ty = PlaceTy::Ty { ty: tr_base.layout.ty } - .projection_ty(tcx, &projection.elem).to_ty(bcx.tcx()); - subslice.layout = bcx.ccx.layout_of(self.monomorphize(&projected_ty)); + .projection_ty(tcx, &projection.elem).to_ty(bx.tcx()); + subslice.layout = bx.cx.layout_of(self.monomorphize(&projected_ty)); if subslice.layout.is_unsized() { assert!(tr_base.has_extra()); - subslice.llextra = bcx.sub(tr_base.llextra, - C_usize(bcx.ccx, (from as u64) + (to as u64))); + subslice.llextra = bx.sub(tr_base.llextra, + C_usize(bx.cx, (from as u64) + (to as u64))); } // Cast the place pointer type to the new // array or slice type (*[%_; new_len]). - subslice.llval = bcx.pointercast(subslice.llval, - subslice.layout.llvm_type(bcx.ccx).ptr_to()); + subslice.llval = bx.pointercast(subslice.llval, + subslice.layout.llvm_type(bx.cx).ptr_to()); subslice } mir::ProjectionElem::Downcast(_, v) => { - tr_base.project_downcast(bcx, v) + tr_base.project_downcast(bx, v) } } } @@ -492,7 +492,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { } pub fn monomorphized_place_ty(&self, place: &mir::Place<'tcx>) -> Ty<'tcx> { - let tcx = self.ccx.tcx(); + let tcx = self.cx.tcx; let place_ty = place.ty(self.mir, tcx); self.monomorphize(&place_ty.to_ty(tcx)) } diff --git a/src/librustc_trans/mir/rvalue.rs b/src/librustc_trans/mir/rvalue.rs index 56309f20dc1..d1bc4fe9001 100644 --- a/src/librustc_trans/mir/rvalue.rs +++ b/src/librustc_trans/mir/rvalue.rs @@ -29,14 +29,14 @@ use type_::Type; use type_of::LayoutLlvmExt; use value::Value; -use super::{MirContext, LocalRef}; +use super::{FunctionCx, LocalRef}; use super::constant::const_scalar_checked_binop; use super::operand::{OperandRef, OperandValue}; use super::place::PlaceRef; -impl<'a, 'tcx> MirContext<'a, 'tcx> { +impl<'a, 'tcx> FunctionCx<'a, 'tcx> { pub fn trans_rvalue(&mut self, - bcx: Builder<'a, 'tcx>, + bx: Builder<'a, 'tcx>, dest: PlaceRef<'tcx>, rvalue: &mir::Rvalue<'tcx>) -> Builder<'a, 'tcx> @@ -46,11 +46,11 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { match *rvalue { mir::Rvalue::Use(ref operand) => { - let tr_operand = self.trans_operand(&bcx, operand); + let tr_operand = self.trans_operand(&bx, operand); // FIXME: consider not copying constants through stack. (fixable by translating // constants into OperandValue::Ref, why don’t we do that yet if we don’t?) - tr_operand.val.store(&bcx, dest); - bcx + tr_operand.val.store(&bx, dest); + bx } mir::Rvalue::Cast(mir::CastKind::Unsize, ref source, _) => { @@ -59,16 +59,16 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { if dest.layout.is_llvm_scalar_pair() { // into-coerce of a thin pointer to a fat pointer - just // use the operand path. - let (bcx, temp) = self.trans_rvalue_operand(bcx, rvalue); - temp.val.store(&bcx, dest); - return bcx; + let (bx, temp) = self.trans_rvalue_operand(bx, rvalue); + temp.val.store(&bx, dest); + return bx; } // Unsize of a nontrivial struct. I would prefer for // this to be eliminated by MIR translation, but // `CoerceUnsized` can be passed by a where-clause, // so the (generic) MIR may not be able to expand it. - let operand = self.trans_operand(&bcx, source); + let operand = self.trans_operand(&bx, source); match operand.val { OperandValue::Pair(..) | OperandValue::Immediate(_) => { @@ -79,79 +79,79 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { // index into the struct, and this case isn't // important enough for it. debug!("trans_rvalue: creating ugly alloca"); - let scratch = PlaceRef::alloca(&bcx, operand.layout, "__unsize_temp"); - scratch.storage_live(&bcx); - operand.val.store(&bcx, scratch); - base::coerce_unsized_into(&bcx, scratch, dest); - scratch.storage_dead(&bcx); + let scratch = PlaceRef::alloca(&bx, operand.layout, "__unsize_temp"); + scratch.storage_live(&bx); + operand.val.store(&bx, scratch); + base::coerce_unsized_into(&bx, scratch, dest); + scratch.storage_dead(&bx); } OperandValue::Ref(llref, align) => { let source = PlaceRef::new_sized(llref, operand.layout, align); - base::coerce_unsized_into(&bcx, source, dest); + base::coerce_unsized_into(&bx, source, dest); } } - bcx + bx } mir::Rvalue::Repeat(ref elem, count) => { - let tr_elem = self.trans_operand(&bcx, elem); + let tr_elem = self.trans_operand(&bx, elem); // Do not generate the loop for zero-sized elements or empty arrays. if dest.layout.is_zst() { - return bcx; + return bx; } - let start = dest.project_index(&bcx, C_usize(bcx.ccx, 0)).llval; + let start = dest.project_index(&bx, C_usize(bx.cx, 0)).llval; if let OperandValue::Immediate(v) = tr_elem.val { - let align = C_i32(bcx.ccx, dest.align.abi() as i32); - let size = C_usize(bcx.ccx, dest.layout.size.bytes()); + let align = C_i32(bx.cx, dest.align.abi() as i32); + let size = C_usize(bx.cx, dest.layout.size.bytes()); // Use llvm.memset.p0i8.* to initialize all zero arrays if common::is_const_integral(v) && common::const_to_uint(v) == 0 { - let fill = C_u8(bcx.ccx, 0); - base::call_memset(&bcx, start, fill, size, align, false); - return bcx; + let fill = C_u8(bx.cx, 0); + base::call_memset(&bx, start, fill, size, align, false); + return bx; } // Use llvm.memset.p0i8.* to initialize byte arrays - let v = base::from_immediate(&bcx, v); - if common::val_ty(v) == Type::i8(bcx.ccx) { - base::call_memset(&bcx, start, v, size, align, false); - return bcx; + let v = base::from_immediate(&bx, v); + if common::val_ty(v) == Type::i8(bx.cx) { + base::call_memset(&bx, start, v, size, align, false); + return bx; } } let count = count.as_u64(); - let count = C_usize(bcx.ccx, count); - let end = dest.project_index(&bcx, count).llval; + let count = C_usize(bx.cx, count); + let end = dest.project_index(&bx, count).llval; - let header_bcx = bcx.build_sibling_block("repeat_loop_header"); - let body_bcx = bcx.build_sibling_block("repeat_loop_body"); - let next_bcx = bcx.build_sibling_block("repeat_loop_next"); + let header_bx = bx.build_sibling_block("repeat_loop_header"); + let body_bx = bx.build_sibling_block("repeat_loop_body"); + let next_bx = bx.build_sibling_block("repeat_loop_next"); - bcx.br(header_bcx.llbb()); - let current = header_bcx.phi(common::val_ty(start), &[start], &[bcx.llbb()]); + bx.br(header_bx.llbb()); + let current = header_bx.phi(common::val_ty(start), &[start], &[bx.llbb()]); - let keep_going = header_bcx.icmp(llvm::IntNE, current, end); - header_bcx.cond_br(keep_going, body_bcx.llbb(), next_bcx.llbb()); + let keep_going = header_bx.icmp(llvm::IntNE, current, end); + header_bx.cond_br(keep_going, body_bx.llbb(), next_bx.llbb()); - tr_elem.val.store(&body_bcx, + tr_elem.val.store(&body_bx, PlaceRef::new_sized(current, tr_elem.layout, dest.align)); - let next = body_bcx.inbounds_gep(current, &[C_usize(bcx.ccx, 1)]); - body_bcx.br(header_bcx.llbb()); - header_bcx.add_incoming_to_phi(current, next, body_bcx.llbb()); + let next = body_bx.inbounds_gep(current, &[C_usize(bx.cx, 1)]); + body_bx.br(header_bx.llbb()); + header_bx.add_incoming_to_phi(current, next, body_bx.llbb()); - next_bcx + next_bx } mir::Rvalue::Aggregate(ref kind, ref operands) => { let (dest, active_field_index) = match **kind { mir::AggregateKind::Adt(adt_def, variant_index, _, active_field_index) => { - dest.trans_set_discr(&bcx, variant_index); + dest.trans_set_discr(&bx, variant_index); if adt_def.is_enum() { - (dest.project_downcast(&bcx, variant_index), active_field_index) + (dest.project_downcast(&bx, variant_index), active_field_index) } else { (dest, active_field_index) } @@ -159,27 +159,27 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { _ => (dest, None) }; for (i, operand) in operands.iter().enumerate() { - let op = self.trans_operand(&bcx, operand); + let op = self.trans_operand(&bx, operand); // Do not generate stores and GEPis for zero-sized fields. if !op.layout.is_zst() { let field_index = active_field_index.unwrap_or(i); - op.val.store(&bcx, dest.project_field(&bcx, field_index)); + op.val.store(&bx, dest.project_field(&bx, field_index)); } } - bcx + bx } _ => { assert!(self.rvalue_creates_operand(rvalue)); - let (bcx, temp) = self.trans_rvalue_operand(bcx, rvalue); - temp.val.store(&bcx, dest); - bcx + let (bx, temp) = self.trans_rvalue_operand(bx, rvalue); + temp.val.store(&bx, dest); + bx } } } pub fn trans_rvalue_operand(&mut self, - bcx: Builder<'a, 'tcx>, + bx: Builder<'a, 'tcx>, rvalue: &mir::Rvalue<'tcx>) -> (Builder<'a, 'tcx>, OperandRef<'tcx>) { @@ -187,16 +187,16 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { match *rvalue { mir::Rvalue::Cast(ref kind, ref source, mir_cast_ty) => { - let operand = self.trans_operand(&bcx, source); + let operand = self.trans_operand(&bx, source); debug!("cast operand is {:?}", operand); - let cast = bcx.ccx.layout_of(self.monomorphize(&mir_cast_ty)); + let cast = bx.cx.layout_of(self.monomorphize(&mir_cast_ty)); let val = match *kind { mir::CastKind::ReifyFnPointer => { match operand.layout.ty.sty { ty::TyFnDef(def_id, substs) => { OperandValue::Immediate( - callee::resolve_and_get_fn(bcx.ccx, def_id, substs)) + callee::resolve_and_get_fn(bx.cx, def_id, substs)) } _ => { bug!("{} cannot be reified to a fn ptr", operand.layout.ty) @@ -207,8 +207,8 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { match operand.layout.ty.sty { ty::TyClosure(def_id, substs) => { let instance = monomorphize::resolve_closure( - bcx.ccx.tcx(), def_id, substs, ty::ClosureKind::FnOnce); - OperandValue::Immediate(callee::get_fn(bcx.ccx, instance)) + bx.cx.tcx, def_id, substs, ty::ClosureKind::FnOnce); + OperandValue::Immediate(callee::get_fn(bx.cx, instance)) } _ => { bug!("{} cannot be cast to a fn ptr", operand.layout.ty) @@ -230,13 +230,13 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { // HACK(eddyb) have to bitcast pointers // until LLVM removes pointee types. - let lldata = bcx.pointercast(lldata, - cast.scalar_pair_element_llvm_type(bcx.ccx, 0)); + let lldata = bx.pointercast(lldata, + cast.scalar_pair_element_llvm_type(bx.cx, 0)); OperandValue::Pair(lldata, llextra) } OperandValue::Immediate(lldata) => { // "standard" unsize - let (lldata, llextra) = base::unsize_thin_ptr(&bcx, lldata, + let (lldata, llextra) = base::unsize_thin_ptr(&bx, lldata, operand.layout.ty, cast.ty); OperandValue::Pair(lldata, llextra) } @@ -249,14 +249,14 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { mir::CastKind::Misc if operand.layout.is_llvm_scalar_pair() => { if let OperandValue::Pair(data_ptr, meta) = operand.val { if cast.is_llvm_scalar_pair() { - let data_cast = bcx.pointercast(data_ptr, - cast.scalar_pair_element_llvm_type(bcx.ccx, 0)); + let data_cast = bx.pointercast(data_ptr, + cast.scalar_pair_element_llvm_type(bx.cx, 0)); OperandValue::Pair(data_cast, meta) } else { // cast to thin-ptr // Cast of fat-ptr to thin-ptr is an extraction of data-ptr and // pointer-cast of that pointer to desired pointer type. - let llcast_ty = cast.immediate_llvm_type(bcx.ccx); - let llval = bcx.pointercast(data_ptr, llcast_ty); + let llcast_ty = cast.immediate_llvm_type(bx.cx); + let llval = bx.pointercast(data_ptr, llcast_ty); OperandValue::Immediate(llval) } } else { @@ -268,8 +268,8 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { let r_t_in = CastTy::from_ty(operand.layout.ty) .expect("bad input type for cast"); let r_t_out = CastTy::from_ty(cast.ty).expect("bad output type for cast"); - let ll_t_in = operand.layout.immediate_llvm_type(bcx.ccx); - let ll_t_out = cast.immediate_llvm_type(bcx.ccx); + let ll_t_in = operand.layout.immediate_llvm_type(bx.cx); + let ll_t_out = cast.immediate_llvm_type(bx.cx); let llval = operand.immediate(); let mut signed = false; @@ -282,7 +282,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { // have bound checks, and this is the most // convenient place to put the `assume`. - base::call_assume(&bcx, bcx.icmp( + base::call_assume(&bx, bx.icmp( llvm::IntULE, llval, C_uint_big(ll_t_in, scalar.valid_range.end) @@ -293,15 +293,15 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { let newval = match (r_t_in, r_t_out) { (CastTy::Int(_), CastTy::Int(_)) => { - bcx.intcast(llval, ll_t_out, signed) + bx.intcast(llval, ll_t_out, signed) } (CastTy::Float, CastTy::Float) => { let srcsz = ll_t_in.float_width(); let dstsz = ll_t_out.float_width(); if dstsz > srcsz { - bcx.fpext(llval, ll_t_out) + bx.fpext(llval, ll_t_out) } else if srcsz > dstsz { - bcx.fptrunc(llval, ll_t_out) + bx.fptrunc(llval, ll_t_out) } else { llval } @@ -309,68 +309,68 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { (CastTy::Ptr(_), CastTy::Ptr(_)) | (CastTy::FnPtr, CastTy::Ptr(_)) | (CastTy::RPtr(_), CastTy::Ptr(_)) => - bcx.pointercast(llval, ll_t_out), + bx.pointercast(llval, ll_t_out), (CastTy::Ptr(_), CastTy::Int(_)) | (CastTy::FnPtr, CastTy::Int(_)) => - bcx.ptrtoint(llval, ll_t_out), + bx.ptrtoint(llval, ll_t_out), (CastTy::Int(_), CastTy::Ptr(_)) => { - let usize_llval = bcx.intcast(llval, bcx.ccx.isize_ty(), signed); - bcx.inttoptr(usize_llval, ll_t_out) + let usize_llval = bx.intcast(llval, bx.cx.isize_ty, signed); + bx.inttoptr(usize_llval, ll_t_out) } (CastTy::Int(_), CastTy::Float) => - cast_int_to_float(&bcx, signed, llval, ll_t_in, ll_t_out), + cast_int_to_float(&bx, signed, llval, ll_t_in, ll_t_out), (CastTy::Float, CastTy::Int(IntTy::I)) => - cast_float_to_int(&bcx, true, llval, ll_t_in, ll_t_out), + cast_float_to_int(&bx, true, llval, ll_t_in, ll_t_out), (CastTy::Float, CastTy::Int(_)) => - cast_float_to_int(&bcx, false, llval, ll_t_in, ll_t_out), + cast_float_to_int(&bx, false, llval, ll_t_in, ll_t_out), _ => bug!("unsupported cast: {:?} to {:?}", operand.layout.ty, cast.ty) }; OperandValue::Immediate(newval) } }; - (bcx, OperandRef { + (bx, OperandRef { val, layout: cast }) } mir::Rvalue::Ref(_, bk, ref place) => { - let tr_place = self.trans_place(&bcx, place); + let tr_place = self.trans_place(&bx, place); let ty = tr_place.layout.ty; // Note: places are indirect, so storing the `llval` into the // destination effectively creates a reference. - let val = if !bcx.ccx.shared().type_has_metadata(ty) { + let val = if !bx.cx.type_has_metadata(ty) { OperandValue::Immediate(tr_place.llval) } else { OperandValue::Pair(tr_place.llval, tr_place.llextra) }; - (bcx, OperandRef { + (bx, OperandRef { val, - layout: self.ccx.layout_of(self.ccx.tcx().mk_ref( - self.ccx.tcx().types.re_erased, + layout: self.cx.layout_of(self.cx.tcx.mk_ref( + self.cx.tcx.types.re_erased, ty::TypeAndMut { ty, mutbl: bk.to_mutbl_lossy() } )), }) } mir::Rvalue::Len(ref place) => { - let size = self.evaluate_array_len(&bcx, place); + let size = self.evaluate_array_len(&bx, place); let operand = OperandRef { val: OperandValue::Immediate(size), - layout: bcx.ccx.layout_of(bcx.tcx().types.usize), + layout: bx.cx.layout_of(bx.tcx().types.usize), }; - (bcx, operand) + (bx, operand) } mir::Rvalue::BinaryOp(op, ref lhs, ref rhs) => { - let lhs = self.trans_operand(&bcx, lhs); - let rhs = self.trans_operand(&bcx, rhs); + let lhs = self.trans_operand(&bx, lhs); + let rhs = self.trans_operand(&bx, rhs); let llresult = match (lhs.val, rhs.val) { (OperandValue::Pair(lhs_addr, lhs_extra), OperandValue::Pair(rhs_addr, rhs_extra)) => { - self.trans_fat_ptr_binop(&bcx, op, + self.trans_fat_ptr_binop(&bx, op, lhs_addr, lhs_extra, rhs_addr, rhs_extra, lhs.layout.ty) @@ -378,114 +378,114 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { (OperandValue::Immediate(lhs_val), OperandValue::Immediate(rhs_val)) => { - self.trans_scalar_binop(&bcx, op, lhs_val, rhs_val, lhs.layout.ty) + self.trans_scalar_binop(&bx, op, lhs_val, rhs_val, lhs.layout.ty) } _ => bug!() }; let operand = OperandRef { val: OperandValue::Immediate(llresult), - layout: bcx.ccx.layout_of( - op.ty(bcx.tcx(), lhs.layout.ty, rhs.layout.ty)), + layout: bx.cx.layout_of( + op.ty(bx.tcx(), lhs.layout.ty, rhs.layout.ty)), }; - (bcx, operand) + (bx, operand) } mir::Rvalue::CheckedBinaryOp(op, ref lhs, ref rhs) => { - let lhs = self.trans_operand(&bcx, lhs); - let rhs = self.trans_operand(&bcx, rhs); - let result = self.trans_scalar_checked_binop(&bcx, op, + let lhs = self.trans_operand(&bx, lhs); + let rhs = self.trans_operand(&bx, rhs); + let result = self.trans_scalar_checked_binop(&bx, op, lhs.immediate(), rhs.immediate(), lhs.layout.ty); - let val_ty = op.ty(bcx.tcx(), lhs.layout.ty, rhs.layout.ty); - let operand_ty = bcx.tcx().intern_tup(&[val_ty, bcx.tcx().types.bool], false); + let val_ty = op.ty(bx.tcx(), lhs.layout.ty, rhs.layout.ty); + let operand_ty = bx.tcx().intern_tup(&[val_ty, bx.tcx().types.bool], false); let operand = OperandRef { val: result, - layout: bcx.ccx.layout_of(operand_ty) + layout: bx.cx.layout_of(operand_ty) }; - (bcx, operand) + (bx, operand) } mir::Rvalue::UnaryOp(op, ref operand) => { - let operand = self.trans_operand(&bcx, operand); + let operand = self.trans_operand(&bx, operand); let lloperand = operand.immediate(); let is_float = operand.layout.ty.is_fp(); let llval = match op { - mir::UnOp::Not => bcx.not(lloperand), + mir::UnOp::Not => bx.not(lloperand), mir::UnOp::Neg => if is_float { - bcx.fneg(lloperand) + bx.fneg(lloperand) } else { - bcx.neg(lloperand) + bx.neg(lloperand) } }; - (bcx, OperandRef { + (bx, OperandRef { val: OperandValue::Immediate(llval), layout: operand.layout, }) } mir::Rvalue::Discriminant(ref place) => { - let discr_ty = rvalue.ty(&*self.mir, bcx.tcx()); - let discr = self.trans_place(&bcx, place) - .trans_get_discr(&bcx, discr_ty); - (bcx, OperandRef { + let discr_ty = rvalue.ty(&*self.mir, bx.tcx()); + let discr = self.trans_place(&bx, place) + .trans_get_discr(&bx, discr_ty); + (bx, OperandRef { val: OperandValue::Immediate(discr), - layout: self.ccx.layout_of(discr_ty) + layout: self.cx.layout_of(discr_ty) }) } mir::Rvalue::NullaryOp(mir::NullOp::SizeOf, ty) => { - assert!(bcx.ccx.shared().type_is_sized(ty)); - let val = C_usize(bcx.ccx, bcx.ccx.size_of(ty).bytes()); - let tcx = bcx.tcx(); - (bcx, OperandRef { + assert!(bx.cx.type_is_sized(ty)); + let val = C_usize(bx.cx, bx.cx.size_of(ty).bytes()); + let tcx = bx.tcx(); + (bx, OperandRef { val: OperandValue::Immediate(val), - layout: self.ccx.layout_of(tcx.types.usize), + layout: self.cx.layout_of(tcx.types.usize), }) } mir::Rvalue::NullaryOp(mir::NullOp::Box, content_ty) => { let content_ty: Ty<'tcx> = self.monomorphize(&content_ty); - let (size, align) = bcx.ccx.size_and_align_of(content_ty); - let llsize = C_usize(bcx.ccx, size.bytes()); - let llalign = C_usize(bcx.ccx, align.abi()); - let box_layout = bcx.ccx.layout_of(bcx.tcx().mk_box(content_ty)); - let llty_ptr = box_layout.llvm_type(bcx.ccx); + let (size, align) = bx.cx.size_and_align_of(content_ty); + let llsize = C_usize(bx.cx, size.bytes()); + let llalign = C_usize(bx.cx, align.abi()); + let box_layout = bx.cx.layout_of(bx.tcx().mk_box(content_ty)); + let llty_ptr = box_layout.llvm_type(bx.cx); // Allocate space: - let def_id = match bcx.tcx().lang_items().require(ExchangeMallocFnLangItem) { + let def_id = match bx.tcx().lang_items().require(ExchangeMallocFnLangItem) { Ok(id) => id, Err(s) => { - bcx.sess().fatal(&format!("allocation of `{}` {}", box_layout.ty, s)); + bx.sess().fatal(&format!("allocation of `{}` {}", box_layout.ty, s)); } }; - let instance = ty::Instance::mono(bcx.tcx(), def_id); - let r = callee::get_fn(bcx.ccx, instance); - let val = bcx.pointercast(bcx.call(r, &[llsize, llalign], None), llty_ptr); + let instance = ty::Instance::mono(bx.tcx(), def_id); + let r = callee::get_fn(bx.cx, instance); + let val = bx.pointercast(bx.call(r, &[llsize, llalign], None), llty_ptr); let operand = OperandRef { val: OperandValue::Immediate(val), layout: box_layout, }; - (bcx, operand) + (bx, operand) } mir::Rvalue::Use(ref operand) => { - let operand = self.trans_operand(&bcx, operand); - (bcx, operand) + let operand = self.trans_operand(&bx, operand); + (bx, operand) } mir::Rvalue::Repeat(..) | mir::Rvalue::Aggregate(..) => { // According to `rvalue_creates_operand`, only ZST // aggregate rvalues are allowed to be operands. - let ty = rvalue.ty(self.mir, self.ccx.tcx()); - (bcx, OperandRef::new_zst(self.ccx, - self.ccx.layout_of(self.monomorphize(&ty)))) + let ty = rvalue.ty(self.mir, self.cx.tcx); + (bx, OperandRef::new_zst(self.cx, + self.cx.layout_of(self.monomorphize(&ty)))) } } } fn evaluate_array_len(&mut self, - bcx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'tcx>, place: &mir::Place<'tcx>) -> ValueRef { // ZST are passed as operands and require special handling @@ -494,17 +494,17 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { if let LocalRef::Operand(Some(op)) = self.locals[index] { if let ty::TyArray(_, n) = op.layout.ty.sty { let n = n.val.to_const_int().unwrap().to_u64().unwrap(); - return common::C_usize(bcx.ccx, n); + return common::C_usize(bx.cx, n); } } } // use common size calculation for non zero-sized types - let tr_value = self.trans_place(&bcx, place); - return tr_value.len(bcx.ccx); + let tr_value = self.trans_place(&bx, place); + return tr_value.len(bx.cx); } pub fn trans_scalar_binop(&mut self, - bcx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'tcx>, op: mir::BinOp, lhs: ValueRef, rhs: ValueRef, @@ -515,49 +515,49 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { let is_bool = input_ty.is_bool(); match op { mir::BinOp::Add => if is_float { - bcx.fadd(lhs, rhs) + bx.fadd(lhs, rhs) } else { - bcx.add(lhs, rhs) + bx.add(lhs, rhs) }, mir::BinOp::Sub => if is_float { - bcx.fsub(lhs, rhs) + bx.fsub(lhs, rhs) } else { - bcx.sub(lhs, rhs) + bx.sub(lhs, rhs) }, mir::BinOp::Mul => if is_float { - bcx.fmul(lhs, rhs) + bx.fmul(lhs, rhs) } else { - bcx.mul(lhs, rhs) + bx.mul(lhs, rhs) }, mir::BinOp::Div => if is_float { - bcx.fdiv(lhs, rhs) + bx.fdiv(lhs, rhs) } else if is_signed { - bcx.sdiv(lhs, rhs) + bx.sdiv(lhs, rhs) } else { - bcx.udiv(lhs, rhs) + bx.udiv(lhs, rhs) }, mir::BinOp::Rem => if is_float { - bcx.frem(lhs, rhs) + bx.frem(lhs, rhs) } else if is_signed { - bcx.srem(lhs, rhs) + bx.srem(lhs, rhs) } else { - bcx.urem(lhs, rhs) + bx.urem(lhs, rhs) }, - mir::BinOp::BitOr => bcx.or(lhs, rhs), - mir::BinOp::BitAnd => bcx.and(lhs, rhs), - mir::BinOp::BitXor => bcx.xor(lhs, rhs), - mir::BinOp::Offset => bcx.inbounds_gep(lhs, &[rhs]), - mir::BinOp::Shl => common::build_unchecked_lshift(bcx, lhs, rhs), - mir::BinOp::Shr => common::build_unchecked_rshift(bcx, input_ty, lhs, rhs), + mir::BinOp::BitOr => bx.or(lhs, rhs), + mir::BinOp::BitAnd => bx.and(lhs, rhs), + mir::BinOp::BitXor => bx.xor(lhs, rhs), + mir::BinOp::Offset => bx.inbounds_gep(lhs, &[rhs]), + mir::BinOp::Shl => common::build_unchecked_lshift(bx, lhs, rhs), + mir::BinOp::Shr => common::build_unchecked_rshift(bx, input_ty, lhs, rhs), mir::BinOp::Ne | mir::BinOp::Lt | mir::BinOp::Gt | mir::BinOp::Eq | mir::BinOp::Le | mir::BinOp::Ge => if is_nil { - C_bool(bcx.ccx, match op { + C_bool(bx.cx, match op { mir::BinOp::Ne | mir::BinOp::Lt | mir::BinOp::Gt => false, mir::BinOp::Eq | mir::BinOp::Le | mir::BinOp::Ge => true, _ => unreachable!() }) } else if is_float { - bcx.fcmp( + bx.fcmp( base::bin_op_to_fcmp_predicate(op.to_hir_binop()), lhs, rhs ) @@ -565,13 +565,13 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { let (lhs, rhs) = if is_bool { // FIXME(#36856) -- extend the bools into `i8` because // LLVM's i1 comparisons are broken. - (bcx.zext(lhs, Type::i8(bcx.ccx)), - bcx.zext(rhs, Type::i8(bcx.ccx))) + (bx.zext(lhs, Type::i8(bx.cx)), + bx.zext(rhs, Type::i8(bx.cx))) } else { (lhs, rhs) }; - bcx.icmp( + bx.icmp( base::bin_op_to_icmp_predicate(op.to_hir_binop(), is_signed), lhs, rhs ) @@ -580,7 +580,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { } pub fn trans_fat_ptr_binop(&mut self, - bcx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'tcx>, op: mir::BinOp, lhs_addr: ValueRef, lhs_extra: ValueRef, @@ -590,15 +590,15 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { -> ValueRef { match op { mir::BinOp::Eq => { - bcx.and( - bcx.icmp(llvm::IntEQ, lhs_addr, rhs_addr), - bcx.icmp(llvm::IntEQ, lhs_extra, rhs_extra) + bx.and( + bx.icmp(llvm::IntEQ, lhs_addr, rhs_addr), + bx.icmp(llvm::IntEQ, lhs_extra, rhs_extra) ) } mir::BinOp::Ne => { - bcx.or( - bcx.icmp(llvm::IntNE, lhs_addr, rhs_addr), - bcx.icmp(llvm::IntNE, lhs_extra, rhs_extra) + bx.or( + bx.icmp(llvm::IntNE, lhs_addr, rhs_addr), + bx.icmp(llvm::IntNE, lhs_extra, rhs_extra) ) } mir::BinOp::Le | mir::BinOp::Lt | @@ -612,11 +612,11 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { _ => bug!(), }; - bcx.or( - bcx.icmp(strict_op, lhs_addr, rhs_addr), - bcx.and( - bcx.icmp(llvm::IntEQ, lhs_addr, rhs_addr), - bcx.icmp(op, lhs_extra, rhs_extra) + bx.or( + bx.icmp(strict_op, lhs_addr, rhs_addr), + bx.and( + bx.icmp(llvm::IntEQ, lhs_addr, rhs_addr), + bx.icmp(op, lhs_extra, rhs_extra) ) ) } @@ -627,7 +627,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { } pub fn trans_scalar_checked_binop(&mut self, - bcx: &Builder<'a, 'tcx>, + bx: &Builder<'a, 'tcx>, op: mir::BinOp, lhs: ValueRef, rhs: ValueRef, @@ -636,17 +636,17 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { // with #[rustc_inherit_overflow_checks] and inlined from // another crate (mostly core::num generic/#[inline] fns), // while the current crate doesn't use overflow checks. - if !bcx.ccx.check_overflow() { - let val = self.trans_scalar_binop(bcx, op, lhs, rhs, input_ty); - return OperandValue::Pair(val, C_bool(bcx.ccx, false)); + if !bx.cx.check_overflow { + let val = self.trans_scalar_binop(bx, op, lhs, rhs, input_ty); + return OperandValue::Pair(val, C_bool(bx.cx, false)); } // First try performing the operation on constants, which // will only succeed if both operands are constant. // This is necessary to determine when an overflow Assert // will always panic at runtime, and produce a warning. - if let Some((val, of)) = const_scalar_checked_binop(bcx.tcx(), op, lhs, rhs, input_ty) { - return OperandValue::Pair(val, C_bool(bcx.ccx, of)); + if let Some((val, of)) = const_scalar_checked_binop(bx.tcx(), op, lhs, rhs, input_ty) { + return OperandValue::Pair(val, C_bool(bx.cx, of)); } let (val, of) = match op { @@ -658,20 +658,20 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { mir::BinOp::Mul => OverflowOp::Mul, _ => unreachable!() }; - let intrinsic = get_overflow_intrinsic(oop, bcx, input_ty); - let res = bcx.call(intrinsic, &[lhs, rhs], None); + let intrinsic = get_overflow_intrinsic(oop, bx, input_ty); + let res = bx.call(intrinsic, &[lhs, rhs], None); - (bcx.extract_value(res, 0), - bcx.extract_value(res, 1)) + (bx.extract_value(res, 0), + bx.extract_value(res, 1)) } mir::BinOp::Shl | mir::BinOp::Shr => { let lhs_llty = val_ty(lhs); let rhs_llty = val_ty(rhs); - let invert_mask = common::shift_mask_val(&bcx, lhs_llty, rhs_llty, true); - let outer_bits = bcx.and(rhs, invert_mask); + let invert_mask = common::shift_mask_val(&bx, lhs_llty, rhs_llty, true); + let outer_bits = bx.and(rhs, invert_mask); - let of = bcx.icmp(llvm::IntNE, outer_bits, C_null(rhs_llty)); - let val = self.trans_scalar_binop(bcx, op, lhs, rhs, input_ty); + let of = bx.icmp(llvm::IntNE, outer_bits, C_null(rhs_llty)); + let val = self.trans_scalar_binop(bx, op, lhs, rhs, input_ty); (val, of) } @@ -697,9 +697,9 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { true, mir::Rvalue::Repeat(..) | mir::Rvalue::Aggregate(..) => { - let ty = rvalue.ty(self.mir, self.ccx.tcx()); + let ty = rvalue.ty(self.mir, self.cx.tcx); let ty = self.monomorphize(&ty); - self.ccx.layout_of(ty).is_zst() + self.cx.layout_of(ty).is_zst() } } @@ -712,12 +712,12 @@ enum OverflowOp { Add, Sub, Mul } -fn get_overflow_intrinsic(oop: OverflowOp, bcx: &Builder, ty: Ty) -> ValueRef { +fn get_overflow_intrinsic(oop: OverflowOp, bx: &Builder, ty: Ty) -> ValueRef { use syntax::ast::IntTy::*; use syntax::ast::UintTy::*; use rustc::ty::{TyInt, TyUint}; - let tcx = bcx.tcx(); + let tcx = bx.tcx(); let new_sty = match ty.sty { TyInt(Isize) => match &tcx.sess.target.target.target_pointer_width[..] { @@ -784,10 +784,10 @@ fn get_overflow_intrinsic(oop: OverflowOp, bcx: &Builder, ty: Ty) -> ValueRef { }, }; - bcx.ccx.get_intrinsic(&name) + bx.cx.get_intrinsic(&name) } -fn cast_int_to_float(bcx: &Builder, +fn cast_int_to_float(bx: &Builder, signed: bool, x: ValueRef, int_ty: Type, @@ -800,31 +800,31 @@ fn cast_int_to_float(bcx: &Builder, // All inputs greater or equal to (f32::MAX + 0.5 ULP) are rounded to infinity, // and for everything else LLVM's uitofp works just fine. let max = C_uint_big(int_ty, MAX_F32_PLUS_HALF_ULP); - let overflow = bcx.icmp(llvm::IntUGE, x, max); - let infinity_bits = C_u32(bcx.ccx, ieee::Single::INFINITY.to_bits() as u32); + let overflow = bx.icmp(llvm::IntUGE, x, max); + let infinity_bits = C_u32(bx.cx, ieee::Single::INFINITY.to_bits() as u32); let infinity = consts::bitcast(infinity_bits, float_ty); - bcx.select(overflow, infinity, bcx.uitofp(x, float_ty)) + bx.select(overflow, infinity, bx.uitofp(x, float_ty)) } else { if signed { - bcx.sitofp(x, float_ty) + bx.sitofp(x, float_ty) } else { - bcx.uitofp(x, float_ty) + bx.uitofp(x, float_ty) } } } -fn cast_float_to_int(bcx: &Builder, +fn cast_float_to_int(bx: &Builder, signed: bool, x: ValueRef, float_ty: Type, int_ty: Type) -> ValueRef { let fptosui_result = if signed { - bcx.fptosi(x, int_ty) + bx.fptosi(x, int_ty) } else { - bcx.fptoui(x, int_ty) + bx.fptoui(x, int_ty) }; - if !bcx.sess().opts.debugging_opts.saturating_float_casts { + if !bx.sess().opts.debugging_opts.saturating_float_casts { return fptosui_result; } // LLVM's fpto[su]i returns undef when the input x is infinite, NaN, or does not fit into the @@ -870,8 +870,8 @@ fn cast_float_to_int(bcx: &Builder, } let float_bits_to_llval = |bits| { let bits_llval = match float_ty.float_width() { - 32 => C_u32(bcx.ccx, bits as u32), - 64 => C_u64(bcx.ccx, bits as u64), + 32 => C_u32(bx.cx, bits as u32), + 64 => C_u64(bx.cx, bits as u64), n => bug!("unsupported float width {}", n), }; consts::bitcast(bits_llval, float_ty) @@ -924,19 +924,19 @@ fn cast_float_to_int(bcx: &Builder, // negation, and the negation can be merged into the select. Therefore, it not necessarily any // more expensive than a ordered ("normal") comparison. Whether these optimizations will be // performed is ultimately up to the backend, but at least x86 does perform them. - let less_or_nan = bcx.fcmp(llvm::RealULT, x, f_min); - let greater = bcx.fcmp(llvm::RealOGT, x, f_max); + let less_or_nan = bx.fcmp(llvm::RealULT, x, f_min); + let greater = bx.fcmp(llvm::RealOGT, x, f_max); let int_max = C_uint_big(int_ty, int_max(signed, int_ty)); let int_min = C_uint_big(int_ty, int_min(signed, int_ty) as u128); - let s0 = bcx.select(less_or_nan, int_min, fptosui_result); - let s1 = bcx.select(greater, int_max, s0); + let s0 = bx.select(less_or_nan, int_min, fptosui_result); + let s1 = bx.select(greater, int_max, s0); // Step 3: NaN replacement. // For unsigned types, the above step already yielded int_ty::MIN == 0 if x is NaN. // Therefore we only need to execute this step for signed integer types. if signed { // LLVM has no isNaN predicate, so we use (x == x) instead - bcx.select(bcx.fcmp(llvm::RealOEQ, x, x), s1, C_uint(int_ty, 0)) + bx.select(bx.fcmp(llvm::RealOEQ, x, x), s1, C_uint(int_ty, 0)) } else { s1 } diff --git a/src/librustc_trans/mir/statement.rs b/src/librustc_trans/mir/statement.rs index e0ca5dcc9d0..b5b74849401 100644 --- a/src/librustc_trans/mir/statement.rs +++ b/src/librustc_trans/mir/statement.rs @@ -13,28 +13,28 @@ use rustc::mir; use asm; use builder::Builder; -use super::MirContext; +use super::FunctionCx; use super::LocalRef; -impl<'a, 'tcx> MirContext<'a, 'tcx> { +impl<'a, 'tcx> FunctionCx<'a, 'tcx> { pub fn trans_statement(&mut self, - bcx: Builder<'a, 'tcx>, + bx: Builder<'a, 'tcx>, statement: &mir::Statement<'tcx>) -> Builder<'a, 'tcx> { debug!("trans_statement(statement={:?})", statement); - self.set_debug_loc(&bcx, statement.source_info); + self.set_debug_loc(&bx, statement.source_info); match statement.kind { mir::StatementKind::Assign(ref place, ref rvalue) => { if let mir::Place::Local(index) = *place { match self.locals[index] { LocalRef::Place(tr_dest) => { - self.trans_rvalue(bcx, tr_dest, rvalue) + self.trans_rvalue(bx, tr_dest, rvalue) } LocalRef::Operand(None) => { - let (bcx, operand) = self.trans_rvalue_operand(bcx, rvalue); + let (bx, operand) = self.trans_rvalue_operand(bx, rvalue); self.locals[index] = LocalRef::Operand(Some(operand)); - bcx + bx } LocalRef::Operand(Some(op)) => { if !op.layout.is_zst() { @@ -45,46 +45,46 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { // If the type is zero-sized, it's already been set here, // but we still need to make sure we translate the operand - self.trans_rvalue_operand(bcx, rvalue).0 + self.trans_rvalue_operand(bx, rvalue).0 } } } else { - let tr_dest = self.trans_place(&bcx, place); - self.trans_rvalue(bcx, tr_dest, rvalue) + let tr_dest = self.trans_place(&bx, place); + self.trans_rvalue(bx, tr_dest, rvalue) } } mir::StatementKind::SetDiscriminant{ref place, variant_index} => { - self.trans_place(&bcx, place) - .trans_set_discr(&bcx, variant_index); - bcx + self.trans_place(&bx, place) + .trans_set_discr(&bx, variant_index); + bx } mir::StatementKind::StorageLive(local) => { if let LocalRef::Place(tr_place) = self.locals[local] { - tr_place.storage_live(&bcx); + tr_place.storage_live(&bx); } - bcx + bx } mir::StatementKind::StorageDead(local) => { if let LocalRef::Place(tr_place) = self.locals[local] { - tr_place.storage_dead(&bcx); + tr_place.storage_dead(&bx); } - bcx + bx } mir::StatementKind::InlineAsm { ref asm, ref outputs, ref inputs } => { let outputs = outputs.iter().map(|output| { - self.trans_place(&bcx, output) + self.trans_place(&bx, output) }).collect(); let input_vals = inputs.iter().map(|input| { - self.trans_operand(&bcx, input).immediate() + self.trans_operand(&bx, input).immediate() }).collect(); - asm::trans_inline_asm(&bcx, asm, outputs, input_vals); - bcx + asm::trans_inline_asm(&bx, asm, outputs, input_vals); + bx } mir::StatementKind::EndRegion(_) | mir::StatementKind::Validate(..) | - mir::StatementKind::Nop => bcx, + mir::StatementKind::Nop => bx, } } } diff --git a/src/librustc_trans/trans_item.rs b/src/librustc_trans/trans_item.rs index fa6a42e062d..5eb6679fe25 100644 --- a/src/librustc_trans/trans_item.rs +++ b/src/librustc_trans/trans_item.rs @@ -18,18 +18,17 @@ use asm; use attributes; use base; use consts; -use context::CrateContext; +use context::CodegenCx; use declare; use llvm; use monomorphize::Instance; use type_of::LayoutLlvmExt; use rustc::hir; use rustc::mir::mono::{Linkage, Visibility}; -use rustc::ty::{TyCtxt, TypeFoldable}; +use rustc::ty::TypeFoldable; use rustc::ty::layout::LayoutOf; use syntax::ast; use syntax::attr; -use syntax_pos::Span; use std::fmt; pub use rustc::mir::mono::MonoItem; @@ -38,18 +37,18 @@ pub use rustc_mir::monomorphize::item::*; pub use rustc_mir::monomorphize::item::MonoItemExt as BaseMonoItemExt; pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> { - fn define(&self, ccx: &CrateContext<'a, 'tcx>) { + fn define(&self, cx: &CodegenCx<'a, 'tcx>) { debug!("BEGIN IMPLEMENTING '{} ({})' in cgu {}", - self.to_string(ccx.tcx()), + self.to_string(cx.tcx), self.to_raw_string(), - ccx.codegen_unit().name()); + cx.codegen_unit.name()); match *self.as_mono_item() { MonoItem::Static(node_id) => { - let tcx = ccx.tcx(); + let tcx = cx.tcx; let item = tcx.hir.expect_item(node_id); if let hir::ItemStatic(_, m, _) = item.node { - match consts::trans_static(&ccx, m, item.id, &item.attrs) { + match consts::trans_static(&cx, m, item.id, &item.attrs) { Ok(_) => { /* Cool, everything's alright. */ }, Err(err) => { err.report(tcx, item.span, "static"); @@ -60,63 +59,51 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> { } } MonoItem::GlobalAsm(node_id) => { - let item = ccx.tcx().hir.expect_item(node_id); + let item = cx.tcx.hir.expect_item(node_id); if let hir::ItemGlobalAsm(ref ga) = item.node { - asm::trans_global_asm(ccx, ga); + asm::trans_global_asm(cx, ga); } else { span_bug!(item.span, "Mismatch between hir::Item type and TransItem type") } } MonoItem::Fn(instance) => { - base::trans_instance(&ccx, instance); + base::trans_instance(&cx, instance); } } debug!("END IMPLEMENTING '{} ({})' in cgu {}", - self.to_string(ccx.tcx()), + self.to_string(cx.tcx), self.to_raw_string(), - ccx.codegen_unit().name()); + cx.codegen_unit.name()); } fn predefine(&self, - ccx: &CrateContext<'a, 'tcx>, + cx: &CodegenCx<'a, 'tcx>, linkage: Linkage, visibility: Visibility) { debug!("BEGIN PREDEFINING '{} ({})' in cgu {}", - self.to_string(ccx.tcx()), + self.to_string(cx.tcx), self.to_raw_string(), - ccx.codegen_unit().name()); + cx.codegen_unit.name()); - let symbol_name = self.symbol_name(ccx.tcx()); + let symbol_name = self.symbol_name(cx.tcx); debug!("symbol {}", &symbol_name); match *self.as_mono_item() { MonoItem::Static(node_id) => { - predefine_static(ccx, node_id, linkage, visibility, &symbol_name); + predefine_static(cx, node_id, linkage, visibility, &symbol_name); } MonoItem::Fn(instance) => { - predefine_fn(ccx, instance, linkage, visibility, &symbol_name); + predefine_fn(cx, instance, linkage, visibility, &symbol_name); } MonoItem::GlobalAsm(..) => {} } debug!("END PREDEFINING '{} ({})' in cgu {}", - self.to_string(ccx.tcx()), + self.to_string(cx.tcx), self.to_raw_string(), - ccx.codegen_unit().name()); - } - - fn local_span(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option<Span> { - match *self.as_mono_item() { - MonoItem::Fn(Instance { def, .. }) => { - tcx.hir.as_local_node_id(def.def_id()) - } - MonoItem::Static(node_id) | - MonoItem::GlobalAsm(node_id) => { - Some(node_id) - } - }.map(|node_id| tcx.hir.span(node_id)) + cx.codegen_unit.name()); } fn to_raw_string(&self) -> String { @@ -138,18 +125,18 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> { impl<'a, 'tcx> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {} -fn predefine_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, +fn predefine_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, node_id: ast::NodeId, linkage: Linkage, visibility: Visibility, symbol_name: &str) { - let def_id = ccx.tcx().hir.local_def_id(node_id); - let instance = Instance::mono(ccx.tcx(), def_id); - let ty = instance.ty(ccx.tcx()); - let llty = ccx.layout_of(ty).llvm_type(ccx); + let def_id = cx.tcx.hir.local_def_id(node_id); + let instance = Instance::mono(cx.tcx, def_id); + let ty = instance.ty(cx.tcx); + let llty = cx.layout_of(ty).llvm_type(cx); - let g = declare::define_global(ccx, symbol_name, llty).unwrap_or_else(|| { - ccx.sess().span_fatal(ccx.tcx().hir.span(node_id), + let g = declare::define_global(cx, symbol_name, llty).unwrap_or_else(|| { + cx.sess().span_fatal(cx.tcx.hir.span(node_id), &format!("symbol `{}` is already defined", symbol_name)) }); @@ -158,11 +145,11 @@ fn predefine_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, llvm::LLVMRustSetVisibility(g, base::visibility_to_llvm(visibility)); } - ccx.instances().borrow_mut().insert(instance, g); - ccx.statics().borrow_mut().insert(g, def_id); + cx.instances.borrow_mut().insert(instance, g); + cx.statics.borrow_mut().insert(g, def_id); } -fn predefine_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, +fn predefine_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, instance: Instance<'tcx>, linkage: Linkage, visibility: Visibility, @@ -170,14 +157,14 @@ fn predefine_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, assert!(!instance.substs.needs_infer() && !instance.substs.has_param_types()); - let mono_ty = instance.ty(ccx.tcx()); - let attrs = instance.def.attrs(ccx.tcx()); - let lldecl = declare::declare_fn(ccx, symbol_name, mono_ty); + let mono_ty = instance.ty(cx.tcx); + let attrs = instance.def.attrs(cx.tcx); + let lldecl = declare::declare_fn(cx, symbol_name, mono_ty); unsafe { llvm::LLVMRustSetLinkage(lldecl, base::linkage_to_llvm(linkage)) }; - base::set_link_section(ccx, lldecl, &attrs); + base::set_link_section(cx, lldecl, &attrs); if linkage == Linkage::LinkOnceODR || linkage == Linkage::WeakODR { - llvm::SetUniqueComdat(ccx.llmod(), lldecl); + llvm::SetUniqueComdat(cx.llmod, lldecl); } // If we're compiling the compiler-builtins crate, e.g. the equivalent of @@ -185,7 +172,7 @@ fn predefine_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, // visibility as we're going to link this object all over the place but // don't want the symbols to get exported. if linkage != Linkage::Internal && linkage != Linkage::Private && - attr::contains_name(ccx.tcx().hir.krate_attrs(), "compiler_builtins") { + attr::contains_name(cx.tcx.hir.krate_attrs(), "compiler_builtins") { unsafe { llvm::LLVMRustSetVisibility(lldecl, llvm::Visibility::Hidden); } @@ -196,10 +183,10 @@ fn predefine_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, } debug!("predefine_fn: mono_ty = {:?} instance = {:?}", mono_ty, instance); - if instance.def.is_inline(ccx.tcx()) { + if instance.def.is_inline(cx.tcx) { attributes::inline(lldecl, attributes::InlineAttr::Hint); } - attributes::from_fn_attrs(ccx, lldecl, instance.def.def_id()); + attributes::from_fn_attrs(cx, lldecl, instance.def.def_id()); - ccx.instances().borrow_mut().insert(instance, lldecl); + cx.instances.borrow_mut().insert(instance, lldecl); } diff --git a/src/librustc_trans/type_.rs b/src/librustc_trans/type_.rs index 6cbe175d4d8..a77acc4f175 100644 --- a/src/librustc_trans/type_.rs +++ b/src/librustc_trans/type_.rs @@ -14,7 +14,7 @@ use llvm; use llvm::{ContextRef, TypeRef, Bool, False, True, TypeKind}; use llvm::{Float, Double, X86_FP80, PPC_FP128, FP128}; -use context::CrateContext; +use context::CodegenCx; use syntax::ast; use rustc::ty::layout::{self, Align, Size}; @@ -62,115 +62,115 @@ impl Type { unsafe { mem::transmute(slice) } } - pub fn void(ccx: &CrateContext) -> Type { - ty!(llvm::LLVMVoidTypeInContext(ccx.llcx())) + pub fn void(cx: &CodegenCx) -> Type { + ty!(llvm::LLVMVoidTypeInContext(cx.llcx)) } - pub fn metadata(ccx: &CrateContext) -> Type { - ty!(llvm::LLVMRustMetadataTypeInContext(ccx.llcx())) + pub fn metadata(cx: &CodegenCx) -> Type { + ty!(llvm::LLVMRustMetadataTypeInContext(cx.llcx)) } - pub fn i1(ccx: &CrateContext) -> Type { - ty!(llvm::LLVMInt1TypeInContext(ccx.llcx())) + pub fn i1(cx: &CodegenCx) -> Type { + ty!(llvm::LLVMInt1TypeInContext(cx.llcx)) } - pub fn i8(ccx: &CrateContext) -> Type { - ty!(llvm::LLVMInt8TypeInContext(ccx.llcx())) + pub fn i8(cx: &CodegenCx) -> Type { + ty!(llvm::LLVMInt8TypeInContext(cx.llcx)) } pub fn i8_llcx(llcx: ContextRef) -> Type { ty!(llvm::LLVMInt8TypeInContext(llcx)) } - pub fn i16(ccx: &CrateContext) -> Type { - ty!(llvm::LLVMInt16TypeInContext(ccx.llcx())) + pub fn i16(cx: &CodegenCx) -> Type { + ty!(llvm::LLVMInt16TypeInContext(cx.llcx)) } - pub fn i32(ccx: &CrateContext) -> Type { - ty!(llvm::LLVMInt32TypeInContext(ccx.llcx())) + pub fn i32(cx: &CodegenCx) -> Type { + ty!(llvm::LLVMInt32TypeInContext(cx.llcx)) } - pub fn i64(ccx: &CrateContext) -> Type { - ty!(llvm::LLVMInt64TypeInContext(ccx.llcx())) + pub fn i64(cx: &CodegenCx) -> Type { + ty!(llvm::LLVMInt64TypeInContext(cx.llcx)) } - pub fn i128(ccx: &CrateContext) -> Type { - ty!(llvm::LLVMIntTypeInContext(ccx.llcx(), 128)) + pub fn i128(cx: &CodegenCx) -> Type { + ty!(llvm::LLVMIntTypeInContext(cx.llcx, 128)) } // Creates an integer type with the given number of bits, e.g. i24 - pub fn ix(ccx: &CrateContext, num_bits: u64) -> Type { - ty!(llvm::LLVMIntTypeInContext(ccx.llcx(), num_bits as c_uint)) + pub fn ix(cx: &CodegenCx, num_bits: u64) -> Type { + ty!(llvm::LLVMIntTypeInContext(cx.llcx, num_bits as c_uint)) } - pub fn f32(ccx: &CrateContext) -> Type { - ty!(llvm::LLVMFloatTypeInContext(ccx.llcx())) + pub fn f32(cx: &CodegenCx) -> Type { + ty!(llvm::LLVMFloatTypeInContext(cx.llcx)) } - pub fn f64(ccx: &CrateContext) -> Type { - ty!(llvm::LLVMDoubleTypeInContext(ccx.llcx())) + pub fn f64(cx: &CodegenCx) -> Type { + ty!(llvm::LLVMDoubleTypeInContext(cx.llcx)) } - pub fn bool(ccx: &CrateContext) -> Type { - Type::i8(ccx) + pub fn bool(cx: &CodegenCx) -> Type { + Type::i8(cx) } - pub fn char(ccx: &CrateContext) -> Type { - Type::i32(ccx) + pub fn char(cx: &CodegenCx) -> Type { + Type::i32(cx) } - pub fn i8p(ccx: &CrateContext) -> Type { - Type::i8(ccx).ptr_to() + pub fn i8p(cx: &CodegenCx) -> Type { + Type::i8(cx).ptr_to() } pub fn i8p_llcx(llcx: ContextRef) -> Type { Type::i8_llcx(llcx).ptr_to() } - pub fn isize(ccx: &CrateContext) -> Type { - match &ccx.tcx().sess.target.target.target_pointer_width[..] { - "16" => Type::i16(ccx), - "32" => Type::i32(ccx), - "64" => Type::i64(ccx), + pub fn isize(cx: &CodegenCx) -> Type { + match &cx.tcx.sess.target.target.target_pointer_width[..] { + "16" => Type::i16(cx), + "32" => Type::i32(cx), + "64" => Type::i64(cx), tws => bug!("Unsupported target word size for int: {}", tws), } } - pub fn c_int(ccx: &CrateContext) -> Type { - match &ccx.tcx().sess.target.target.target_c_int_width[..] { - "16" => Type::i16(ccx), - "32" => Type::i32(ccx), - "64" => Type::i64(ccx), + pub fn c_int(cx: &CodegenCx) -> Type { + match &cx.tcx.sess.target.target.target_c_int_width[..] { + "16" => Type::i16(cx), + "32" => Type::i32(cx), + "64" => Type::i64(cx), width => bug!("Unsupported target_c_int_width: {}", width), } } - pub fn int_from_ty(ccx: &CrateContext, t: ast::IntTy) -> Type { + pub fn int_from_ty(cx: &CodegenCx, t: ast::IntTy) -> Type { match t { - ast::IntTy::Isize => ccx.isize_ty(), - ast::IntTy::I8 => Type::i8(ccx), - ast::IntTy::I16 => Type::i16(ccx), - ast::IntTy::I32 => Type::i32(ccx), - ast::IntTy::I64 => Type::i64(ccx), - ast::IntTy::I128 => Type::i128(ccx), + ast::IntTy::Isize => cx.isize_ty, + ast::IntTy::I8 => Type::i8(cx), + ast::IntTy::I16 => Type::i16(cx), + ast::IntTy::I32 => Type::i32(cx), + ast::IntTy::I64 => Type::i64(cx), + ast::IntTy::I128 => Type::i128(cx), } } - pub fn uint_from_ty(ccx: &CrateContext, t: ast::UintTy) -> Type { + pub fn uint_from_ty(cx: &CodegenCx, t: ast::UintTy) -> Type { match t { - ast::UintTy::Usize => ccx.isize_ty(), - ast::UintTy::U8 => Type::i8(ccx), - ast::UintTy::U16 => Type::i16(ccx), - ast::UintTy::U32 => Type::i32(ccx), - ast::UintTy::U64 => Type::i64(ccx), - ast::UintTy::U128 => Type::i128(ccx), + ast::UintTy::Usize => cx.isize_ty, + ast::UintTy::U8 => Type::i8(cx), + ast::UintTy::U16 => Type::i16(cx), + ast::UintTy::U32 => Type::i32(cx), + ast::UintTy::U64 => Type::i64(cx), + ast::UintTy::U128 => Type::i128(cx), } } - pub fn float_from_ty(ccx: &CrateContext, t: ast::FloatTy) -> Type { + pub fn float_from_ty(cx: &CodegenCx, t: ast::FloatTy) -> Type { match t { - ast::FloatTy::F32 => Type::f32(ccx), - ast::FloatTy::F64 => Type::f64(ccx), + ast::FloatTy::F32 => Type::f32(cx), + ast::FloatTy::F64 => Type::f64(cx), } } @@ -186,16 +186,16 @@ impl Type { args.len() as c_uint, True)) } - pub fn struct_(ccx: &CrateContext, els: &[Type], packed: bool) -> Type { + pub fn struct_(cx: &CodegenCx, els: &[Type], packed: bool) -> Type { let els: &[TypeRef] = Type::to_ref_slice(els); - ty!(llvm::LLVMStructTypeInContext(ccx.llcx(), els.as_ptr(), + ty!(llvm::LLVMStructTypeInContext(cx.llcx, els.as_ptr(), els.len() as c_uint, packed as Bool)) } - pub fn named_struct(ccx: &CrateContext, name: &str) -> Type { + pub fn named_struct(cx: &CodegenCx, name: &str) -> Type { let name = CString::new(name).unwrap(); - ty!(llvm::LLVMStructCreateNamed(ccx.llcx(), name.as_ptr())) + ty!(llvm::LLVMStructCreateNamed(cx.llcx, name.as_ptr())) } @@ -265,7 +265,7 @@ impl Type { } } - pub fn from_integer(cx: &CrateContext, i: layout::Integer) -> Type { + pub fn from_integer(cx: &CodegenCx, i: layout::Integer) -> Type { use rustc::ty::layout::Integer::*; match i { I8 => Type::i8(cx), @@ -278,23 +278,23 @@ impl Type { /// Return a LLVM type that has at most the required alignment, /// as a conservative approximation for unknown pointee types. - pub fn pointee_for_abi_align(ccx: &CrateContext, align: Align) -> Type { + pub fn pointee_for_abi_align(cx: &CodegenCx, align: Align) -> Type { // FIXME(eddyb) We could find a better approximation if ity.align < align. - let ity = layout::Integer::approximate_abi_align(ccx, align); - Type::from_integer(ccx, ity) + let ity = layout::Integer::approximate_abi_align(cx, align); + Type::from_integer(cx, ity) } /// Return a LLVM type that has at most the required alignment, /// and exactly the required size, as a best-effort padding array. - pub fn padding_filler(ccx: &CrateContext, size: Size, align: Align) -> Type { - let unit = layout::Integer::approximate_abi_align(ccx, align); + pub fn padding_filler(cx: &CodegenCx, size: Size, align: Align) -> Type { + let unit = layout::Integer::approximate_abi_align(cx, align); let size = size.bytes(); let unit_size = unit.size().bytes(); assert_eq!(size % unit_size, 0); - Type::array(&Type::from_integer(ccx, unit), size / unit_size) + Type::array(&Type::from_integer(cx, unit), size / unit_size) } - pub fn x86_mmx(ccx: &CrateContext) -> Type { - ty!(llvm::LLVMX86MMXTypeInContext(ccx.llcx())) + pub fn x86_mmx(cx: &CodegenCx) -> Type { + ty!(llvm::LLVMX86MMXTypeInContext(cx.llcx)) } } diff --git a/src/librustc_trans/type_of.rs b/src/librustc_trans/type_of.rs index 8d9bc07fe56..b1533cfad19 100644 --- a/src/librustc_trans/type_of.rs +++ b/src/librustc_trans/type_of.rs @@ -19,7 +19,7 @@ use type_::Type; use std::fmt::Write; -fn uncached_llvm_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, +fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, layout: TyLayout<'tcx>, defer: &mut Option<(Type, TyLayout<'tcx>)>) -> Type { @@ -34,19 +34,19 @@ fn uncached_llvm_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, // one-element SIMD vectors, so it's assumed this won't clash with // much else. let use_x86_mmx = count == 1 && layout.size.bits() == 64 && - (ccx.sess().target.target.arch == "x86" || - ccx.sess().target.target.arch == "x86_64"); + (cx.sess().target.target.arch == "x86" || + cx.sess().target.target.arch == "x86_64"); if use_x86_mmx { - return Type::x86_mmx(ccx) + return Type::x86_mmx(cx) } else { - let element = layout.scalar_llvm_type_at(ccx, element, Size::from_bytes(0)); + let element = layout.scalar_llvm_type_at(cx, element, Size::from_bytes(0)); return Type::vector(&element, count); } } layout::Abi::ScalarPair(..) => { - return Type::struct_(ccx, &[ - layout.scalar_pair_element_llvm_type(ccx, 0), - layout.scalar_pair_element_llvm_type(ccx, 1), + return Type::struct_(cx, &[ + layout.scalar_pair_element_llvm_type(cx, 0), + layout.scalar_pair_element_llvm_type(cx, 1), ], false); } layout::Abi::Uninhabited | @@ -61,7 +61,7 @@ fn uncached_llvm_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty::TyForeign(..) | ty::TyStr => { let mut name = String::with_capacity(32); - let printer = DefPathBasedNames::new(ccx.tcx(), true, true); + let printer = DefPathBasedNames::new(cx.tcx, true, true); printer.push_type_name(layout.ty, &mut name); match (&layout.ty.sty, &layout.variants) { (&ty::TyAdt(def, _), &layout::Variants::Single { index }) => { @@ -78,30 +78,30 @@ fn uncached_llvm_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, match layout.fields { layout::FieldPlacement::Union(_) => { - let fill = Type::padding_filler(ccx, layout.size, layout.align); + let fill = Type::padding_filler(cx, layout.size, layout.align); let packed = false; match name { None => { - Type::struct_(ccx, &[fill], packed) + Type::struct_(cx, &[fill], packed) } Some(ref name) => { - let mut llty = Type::named_struct(ccx, name); + let mut llty = Type::named_struct(cx, name); llty.set_struct_body(&[fill], packed); llty } } } layout::FieldPlacement::Array { count, .. } => { - Type::array(&layout.field(ccx, 0).llvm_type(ccx), count) + Type::array(&layout.field(cx, 0).llvm_type(cx), count) } layout::FieldPlacement::Arbitrary { .. } => { match name { None => { - let (llfields, packed) = struct_llfields(ccx, layout); - Type::struct_(ccx, &llfields, packed) + let (llfields, packed) = struct_llfields(cx, layout); + Type::struct_(cx, &llfields, packed) } Some(ref name) => { - let llty = Type::named_struct(ccx, name); + let llty = Type::named_struct(cx, name); *defer = Some((llty, layout)); llty } @@ -110,7 +110,7 @@ fn uncached_llvm_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, } } -fn struct_llfields<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, +fn struct_llfields<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, layout: TyLayout<'tcx>) -> (Vec<Type>, bool) { debug!("struct_llfields: {:#?}", layout); @@ -121,7 +121,7 @@ fn struct_llfields<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let mut prev_align = layout.align; let mut result: Vec<Type> = Vec::with_capacity(1 + field_count * 2); for i in layout.fields.index_by_increasing_offset() { - let field = layout.field(ccx, i); + let field = layout.field(cx, i); packed |= layout.align.abi() < field.align.abi(); let target_offset = layout.fields.offset(i as usize); @@ -131,10 +131,10 @@ fn struct_llfields<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let padding = target_offset - offset; let padding_align = layout.align.min(prev_align).min(field.align); assert_eq!(offset.abi_align(padding_align) + padding, target_offset); - result.push(Type::padding_filler(ccx, padding, padding_align)); + result.push(Type::padding_filler(cx, padding, padding_align)); debug!(" padding before: {:?}", padding); - result.push(field.llvm_type(ccx)); + result.push(field.llvm_type(cx)); offset = target_offset + field.size; prev_align = field.align; } @@ -148,7 +148,7 @@ fn struct_llfields<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, assert_eq!(offset.abi_align(padding_align) + padding, layout.size); debug!("struct_llfields: pad_bytes: {:?} offset: {:?} stride: {:?}", padding, offset, layout.size); - result.push(Type::padding_filler(ccx, padding, padding_align)); + result.push(Type::padding_filler(cx, padding, padding_align)); assert!(result.len() == 1 + field_count * 2); } else { debug!("struct_llfields: offset: {:?} stride: {:?}", @@ -158,7 +158,7 @@ fn struct_llfields<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, (result, packed) } -impl<'a, 'tcx> CrateContext<'a, 'tcx> { +impl<'a, 'tcx> CodegenCx<'a, 'tcx> { pub fn align_of(&self, ty: Ty<'tcx>) -> Align { self.layout_of(ty).align } @@ -197,14 +197,14 @@ pub struct PointeeInfo { pub trait LayoutLlvmExt<'tcx> { fn is_llvm_immediate(&self) -> bool; fn is_llvm_scalar_pair<'a>(&self) -> bool; - fn llvm_type<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> Type; - fn immediate_llvm_type<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> Type; - fn scalar_llvm_type_at<'a>(&self, ccx: &CrateContext<'a, 'tcx>, + fn llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> Type; + fn immediate_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> Type; + fn scalar_llvm_type_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, scalar: &layout::Scalar, offset: Size) -> Type; - fn scalar_pair_element_llvm_type<'a>(&self, ccx: &CrateContext<'a, 'tcx>, + fn scalar_pair_element_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>, index: usize) -> Type; fn llvm_field_index(&self, index: usize) -> u64; - fn pointee_info_at<'a>(&self, ccx: &CrateContext<'a, 'tcx>, offset: Size) + fn pointee_info_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, offset: Size) -> Option<PointeeInfo>; } @@ -240,28 +240,28 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> { /// with the inner-most trailing unsized field using the "minimal unit" /// of that field's type - this is useful for taking the address of /// that field and ensuring the struct has the right alignment. - fn llvm_type<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> Type { + fn llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> Type { if let layout::Abi::Scalar(ref scalar) = self.abi { // Use a different cache for scalars because pointers to DSTs // can be either fat or thin (data pointers of fat pointers). - if let Some(&llty) = ccx.scalar_lltypes().borrow().get(&self.ty) { + if let Some(&llty) = cx.scalar_lltypes.borrow().get(&self.ty) { return llty; } let llty = match self.ty.sty { ty::TyRef(_, ty::TypeAndMut { ty, .. }) | ty::TyRawPtr(ty::TypeAndMut { ty, .. }) => { - ccx.layout_of(ty).llvm_type(ccx).ptr_to() + cx.layout_of(ty).llvm_type(cx).ptr_to() } ty::TyAdt(def, _) if def.is_box() => { - ccx.layout_of(self.ty.boxed_ty()).llvm_type(ccx).ptr_to() + cx.layout_of(self.ty.boxed_ty()).llvm_type(cx).ptr_to() } ty::TyFnPtr(sig) => { - let sig = ccx.tcx().erase_late_bound_regions_and_normalize(&sig); - FnType::new(ccx, sig, &[]).llvm_type(ccx).ptr_to() + let sig = cx.tcx.erase_late_bound_regions_and_normalize(&sig); + FnType::new(cx, sig, &[]).llvm_type(cx).ptr_to() } - _ => self.scalar_llvm_type_at(ccx, scalar, Size::from_bytes(0)) + _ => self.scalar_llvm_type_at(cx, scalar, Size::from_bytes(0)) }; - ccx.scalar_lltypes().borrow_mut().insert(self.ty, llty); + cx.scalar_lltypes.borrow_mut().insert(self.ty, llty); return llty; } @@ -271,7 +271,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> { layout::Variants::Single { index } => Some(index), _ => None }; - if let Some(&llty) = ccx.lltypes().borrow().get(&(self.ty, variant_index)) { + if let Some(&llty) = cx.lltypes.borrow().get(&(self.ty, variant_index)) { return llty; } @@ -281,69 +281,69 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> { // Make sure lifetimes are erased, to avoid generating distinct LLVM // types for Rust types that only differ in the choice of lifetimes. - let normal_ty = ccx.tcx().erase_regions(&self.ty); + let normal_ty = cx.tcx.erase_regions(&self.ty); let mut defer = None; let llty = if self.ty != normal_ty { - let mut layout = ccx.layout_of(normal_ty); + let mut layout = cx.layout_of(normal_ty); if let Some(v) = variant_index { - layout = layout.for_variant(ccx, v); + layout = layout.for_variant(cx, v); } - layout.llvm_type(ccx) + layout.llvm_type(cx) } else { - uncached_llvm_type(ccx, *self, &mut defer) + uncached_llvm_type(cx, *self, &mut defer) }; debug!("--> mapped {:#?} to llty={:?}", self, llty); - ccx.lltypes().borrow_mut().insert((self.ty, variant_index), llty); + cx.lltypes.borrow_mut().insert((self.ty, variant_index), llty); if let Some((mut llty, layout)) = defer { - let (llfields, packed) = struct_llfields(ccx, layout); + let (llfields, packed) = struct_llfields(cx, layout); llty.set_struct_body(&llfields, packed) } llty } - fn immediate_llvm_type<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> Type { + fn immediate_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> Type { if let layout::Abi::Scalar(ref scalar) = self.abi { if scalar.is_bool() { - return Type::i1(ccx); + return Type::i1(cx); } } - self.llvm_type(ccx) + self.llvm_type(cx) } - fn scalar_llvm_type_at<'a>(&self, ccx: &CrateContext<'a, 'tcx>, + fn scalar_llvm_type_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, scalar: &layout::Scalar, offset: Size) -> Type { match scalar.value { - layout::Int(i, _) => Type::from_integer(ccx, i), - layout::F32 => Type::f32(ccx), - layout::F64 => Type::f64(ccx), + layout::Int(i, _) => Type::from_integer(cx, i), + layout::F32 => Type::f32(cx), + layout::F64 => Type::f64(cx), layout::Pointer => { // If we know the alignment, pick something better than i8. - let pointee = if let Some(pointee) = self.pointee_info_at(ccx, offset) { - Type::pointee_for_abi_align(ccx, pointee.align) + let pointee = if let Some(pointee) = self.pointee_info_at(cx, offset) { + Type::pointee_for_abi_align(cx, pointee.align) } else { - Type::i8(ccx) + Type::i8(cx) }; pointee.ptr_to() } } } - fn scalar_pair_element_llvm_type<'a>(&self, ccx: &CrateContext<'a, 'tcx>, + fn scalar_pair_element_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>, index: usize) -> Type { // HACK(eddyb) special-case fat pointers until LLVM removes // pointee types, to avoid bitcasting every `OperandRef::deref`. match self.ty.sty { ty::TyRef(..) | ty::TyRawPtr(_) => { - return self.field(ccx, index).llvm_type(ccx); + return self.field(cx, index).llvm_type(cx); } ty::TyAdt(def, _) if def.is_box() => { - let ptr_ty = ccx.tcx().mk_mut_ptr(self.ty.boxed_ty()); - return ccx.layout_of(ptr_ty).scalar_pair_element_llvm_type(ccx, index); + let ptr_ty = cx.tcx.mk_mut_ptr(self.ty.boxed_ty()); + return cx.layout_of(ptr_ty).scalar_pair_element_llvm_type(cx, index); } _ => {} } @@ -362,15 +362,15 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> { // load/store `bool` as `i8` to avoid crippling LLVM optimizations, // `i1` in a LLVM aggregate is valid and mostly equivalent to `i8`. if scalar.is_bool() { - return Type::i1(ccx); + return Type::i1(cx); } let offset = if index == 0 { Size::from_bytes(0) } else { - a.value.size(ccx).abi_align(b.value.align(ccx)) + a.value.size(cx).abi_align(b.value.align(cx)) }; - self.scalar_llvm_type_at(ccx, scalar, offset) + self.scalar_llvm_type_at(cx, scalar, offset) } fn llvm_field_index(&self, index: usize) -> u64 { @@ -396,16 +396,16 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> { } } - fn pointee_info_at<'a>(&self, ccx: &CrateContext<'a, 'tcx>, offset: Size) + fn pointee_info_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, offset: Size) -> Option<PointeeInfo> { - if let Some(&pointee) = ccx.pointee_infos().borrow().get(&(self.ty, offset)) { + if let Some(&pointee) = cx.pointee_infos.borrow().get(&(self.ty, offset)) { return pointee; } let mut result = None; match self.ty.sty { ty::TyRawPtr(mt) if offset.bytes() == 0 => { - let (size, align) = ccx.size_and_align_of(mt.ty); + let (size, align) = cx.size_and_align_of(mt.ty); result = Some(PointeeInfo { size, align, @@ -414,17 +414,17 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> { } ty::TyRef(_, mt) if offset.bytes() == 0 => { - let (size, align) = ccx.size_and_align_of(mt.ty); + let (size, align) = cx.size_and_align_of(mt.ty); let kind = match mt.mutbl { - hir::MutImmutable => if ccx.shared().type_is_freeze(mt.ty) { + hir::MutImmutable => if cx.type_is_freeze(mt.ty) { PointerKind::Frozen } else { PointerKind::Shared }, hir::MutMutable => { - if ccx.shared().tcx().sess.opts.debugging_opts.mutable_noalias || - ccx.shared().tcx().sess.panic_strategy() == PanicStrategy::Abort { + if cx.tcx.sess.opts.debugging_opts.mutable_noalias || + cx.tcx.sess.panic_strategy() == PanicStrategy::Abort { PointerKind::UniqueBorrowed } else { PointerKind::Shared @@ -454,7 +454,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> { // niches than just null (e.g. the first page // of the address space, or unaligned pointers). if self.fields.offset(0) == offset { - Some(self.for_variant(ccx, dataful_variant)) + Some(self.for_variant(cx, dataful_variant)) } else { None } @@ -470,14 +470,14 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> { } if let Some(variant) = data_variant { - let ptr_end = offset + layout::Pointer.size(ccx); + let ptr_end = offset + layout::Pointer.size(cx); for i in 0..variant.fields.count() { let field_start = variant.fields.offset(i); if field_start <= offset { - let field = variant.field(ccx, i); + let field = variant.field(cx, i); if ptr_end <= field_start + field.size { // We found the right field, look inside it. - result = field.pointee_info_at(ccx, offset - field_start); + result = field.pointee_info_at(cx, offset - field_start); break; } } @@ -495,7 +495,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> { } } - ccx.pointee_infos().borrow_mut().insert((self.ty, offset), result); + cx.pointee_infos.borrow_mut().insert((self.ty, offset), result); result } } diff --git a/src/librustc_trans_utils/Cargo.toml b/src/librustc_trans_utils/Cargo.toml index 7b9537ee23e..7a01b6d261a 100644 --- a/src/librustc_trans_utils/Cargo.toml +++ b/src/librustc_trans_utils/Cargo.toml @@ -19,3 +19,5 @@ syntax_pos = { path = "../libsyntax_pos" } rustc = { path = "../librustc" } rustc_back = { path = "../librustc_back" } rustc_data_structures = { path = "../librustc_data_structures" } +rustc_mir = { path = "../librustc_mir" } +rustc_incremental = { path = "../librustc_incremental" } diff --git a/src/librustc_trans_utils/diagnostics.rs b/src/librustc_trans_utils/diagnostics.rs new file mode 100644 index 00000000000..13fa15faf41 --- /dev/null +++ b/src/librustc_trans_utils/diagnostics.rs @@ -0,0 +1,38 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(non_snake_case)] + +register_long_diagnostics! { + +E0558: r##" +The `export_name` attribute was malformed. + +Erroneous code example: + +```ignore (error-emitted-at-codegen-which-cannot-be-handled-by-compile_fail) +#[export_name] // error: export_name attribute has invalid format +pub fn something() {} + +fn main() {} +``` + +The `export_name` attribute expects a string in order to determine the name of +the exported symbol. Example: + +``` +#[export_name = "some_function"] // ok! +pub fn something() {} + +fn main() {} +``` +"##, + +} diff --git a/src/librustc_trans_utils/lib.rs b/src/librustc_trans_utils/lib.rs index 77afc2899c3..9b7ab204492 100644 --- a/src/librustc_trans_utils/lib.rs +++ b/src/librustc_trans_utils/lib.rs @@ -35,18 +35,26 @@ extern crate log; #[macro_use] extern crate rustc; extern crate rustc_back; +extern crate rustc_mir; +extern crate rustc_incremental; +#[macro_use] extern crate syntax; extern crate syntax_pos; extern crate rustc_data_structures; +pub extern crate rustc as __rustc; + use rustc::ty::{TyCtxt, Instance}; use rustc::hir; use rustc::hir::def_id::LOCAL_CRATE; use rustc::hir::map as hir_map; use rustc::util::nodemap::NodeSet; +pub mod diagnostics; pub mod link; pub mod trans_crate; +pub mod symbol_names; +pub mod symbol_names_test; /// check for the #[rustc_error] annotation, which forces an /// error in trans. This is used to write compile-fail tests @@ -110,3 +118,6 @@ pub fn find_exported_symbols<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> NodeSet { } }).collect() } + +#[cfg(not(stage0))] // remove after the next snapshot +__build_diagnostic_array! { librustc_trans_utils, DIAGNOSTICS } diff --git a/src/librustc_trans/back/symbol_names.rs b/src/librustc_trans_utils/symbol_names.rs index 825f306499a..fb299bf7eea 100644 --- a/src/librustc_trans/back/symbol_names.rs +++ b/src/librustc_trans_utils/symbol_names.rs @@ -97,11 +97,9 @@ //! virtually impossible. Thus, symbol hash generation exclusively relies on //! DefPaths which are much more robust in the face of changes to the code base. -use monomorphize::Instance; -use trans_item::{BaseMonoItemExt, InstantiationMode}; - use rustc::middle::weak_lang_items; -use rustc::mir::mono::MonoItem; +use rustc_mir::monomorphize::Instance; +use rustc_mir::monomorphize::item::{MonoItem, MonoItemExt, InstantiationMode}; use rustc::hir::def_id::DefId; use rustc::hir::map as hir_map; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; @@ -257,14 +255,12 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance if let Some(id) = node_id { if tcx.sess.plugin_registrar_fn.get() == Some(id) { - let idx = def_id.index; let disambiguator = tcx.sess.local_crate_disambiguator(); - return tcx.sess.generate_plugin_registrar_symbol(disambiguator, idx); + return tcx.sess.generate_plugin_registrar_symbol(disambiguator); } if tcx.sess.derive_registrar_fn.get() == Some(id) { - let idx = def_id.index; let disambiguator = tcx.sess.local_crate_disambiguator(); - return tcx.sess.generate_derive_registrar_symbol(disambiguator, idx); + return tcx.sess.generate_derive_registrar_symbol(disambiguator); } } diff --git a/src/librustc_trans/symbol_names_test.rs b/src/librustc_trans_utils/symbol_names_test.rs index 15c142cf947..5d7d4f3055b 100644 --- a/src/librustc_trans/symbol_names_test.rs +++ b/src/librustc_trans_utils/symbol_names_test.rs @@ -19,7 +19,7 @@ use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use rustc::ty::TyCtxt; use syntax::ast; -use monomorphize::Instance; +use rustc_mir::monomorphize::Instance; const SYMBOL_NAME: &'static str = "rustc_symbol_name"; const ITEM_PATH: &'static str = "rustc_item_path"; diff --git a/src/librustc_trans_utils/trans_crate.rs b/src/librustc_trans_utils/trans_crate.rs index 47143893e59..49756d754fe 100644 --- a/src/librustc_trans_utils/trans_crate.rs +++ b/src/librustc_trans_utils/trans_crate.rs @@ -26,6 +26,7 @@ use std::io::prelude::*; use std::io::{self, Cursor}; use std::fs::File; use std::path::Path; +use std::rc::Rc; use std::sync::mpsc; use rustc_data_structures::owning_ref::{ErasedBoxRef, OwningRef}; @@ -35,83 +36,81 @@ use flate2::write::DeflateEncoder; use syntax::symbol::Symbol; use rustc::hir::def_id::LOCAL_CRATE; -use rustc::session::Session; -use rustc::session::config::{CrateType, OutputFilenames}; +use rustc::session::{Session, CompileIncomplete}; +use rustc::session::config::{CrateType, OutputFilenames, PrintRequest}; use rustc::ty::TyCtxt; use rustc::ty::maps::Providers; use rustc::middle::cstore::EncodedMetadata; -use rustc::middle::cstore::MetadataLoader as MetadataLoaderTrait; +use rustc::middle::cstore::MetadataLoader; use rustc::dep_graph::DepGraph; use rustc_back::target::Target; +use rustc_mir::monomorphize::collector; use link::{build_link_meta, out_filename}; pub trait TransCrate { - type MetadataLoader: MetadataLoaderTrait; - type OngoingCrateTranslation; - type TranslatedCrate; + fn print(&self, _req: PrintRequest, _sess: &Session) {} + fn target_features(&self, _sess: &Session) -> Vec<Symbol> { vec![] } - fn metadata_loader() -> Box<MetadataLoaderTrait>; - fn provide(_providers: &mut Providers); - fn provide_extern(_providers: &mut Providers); + fn metadata_loader(&self) -> Box<MetadataLoader>; + fn provide(&self, _providers: &mut Providers); + fn provide_extern(&self, _providers: &mut Providers); fn trans_crate<'a, 'tcx>( + &self, tcx: TyCtxt<'a, 'tcx, 'tcx>, rx: mpsc::Receiver<Box<Any + Send>> - ) -> Self::OngoingCrateTranslation; - fn join_trans( - trans: Self::OngoingCrateTranslation, + ) -> Box<Any>; + + /// This is called on the returned `Box<Any>` from `trans_crate` + /// + /// # Panics + /// + /// Panics when the passed `Box<Any>` was not returned by `trans_crate`. + fn join_trans_and_link( + &self, + trans: Box<Any>, sess: &Session, - dep_graph: &DepGraph - ) -> Self::TranslatedCrate; - fn link_binary(sess: &Session, trans: &Self::TranslatedCrate, outputs: &OutputFilenames); - fn dump_incremental_data(trans: &Self::TranslatedCrate); + dep_graph: &DepGraph, + outputs: &OutputFilenames, + ) -> Result<(), CompileIncomplete>; } pub struct DummyTransCrate; impl TransCrate for DummyTransCrate { - type MetadataLoader = DummyMetadataLoader; - type OngoingCrateTranslation = (); - type TranslatedCrate = (); - - fn metadata_loader() -> Box<MetadataLoaderTrait> { + fn metadata_loader(&self) -> Box<MetadataLoader> { box DummyMetadataLoader(()) } - fn provide(_providers: &mut Providers) { + fn provide(&self, _providers: &mut Providers) { bug!("DummyTransCrate::provide"); } - fn provide_extern(_providers: &mut Providers) { + fn provide_extern(&self, _providers: &mut Providers) { bug!("DummyTransCrate::provide_extern"); } fn trans_crate<'a, 'tcx>( + &self, _tcx: TyCtxt<'a, 'tcx, 'tcx>, _rx: mpsc::Receiver<Box<Any + Send>> - ) -> Self::OngoingCrateTranslation { + ) -> Box<Any> { bug!("DummyTransCrate::trans_crate"); } - fn join_trans( - _trans: Self::OngoingCrateTranslation, + fn join_trans_and_link( + &self, + _trans: Box<Any>, _sess: &Session, - _dep_graph: &DepGraph - ) -> Self::TranslatedCrate { - bug!("DummyTransCrate::join_trans"); - } - - fn link_binary(_sess: &Session, _trans: &Self::TranslatedCrate, _outputs: &OutputFilenames) { - bug!("DummyTransCrate::link_binary"); - } - - fn dump_incremental_data(_trans: &Self::TranslatedCrate) { - bug!("DummyTransCrate::dump_incremental_data"); + _dep_graph: &DepGraph, + _outputs: &OutputFilenames, + ) -> Result<(), CompileIncomplete> { + bug!("DummyTransCrate::join_trans_and_link"); } } pub struct DummyMetadataLoader(()); -impl MetadataLoaderTrait for DummyMetadataLoader { +impl MetadataLoader for DummyMetadataLoader { fn get_rlib_metadata( &self, _target: &Target, @@ -131,7 +130,7 @@ impl MetadataLoaderTrait for DummyMetadataLoader { pub struct NoLlvmMetadataLoader; -impl MetadataLoaderTrait for NoLlvmMetadataLoader { +impl MetadataLoader for NoLlvmMetadataLoader { fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result<ErasedBoxRef<[u8]>, String> { let file = File::open(filename) .map_err(|e| format!("metadata file open err: {:?}", e))?; @@ -161,87 +160,132 @@ impl MetadataLoaderTrait for NoLlvmMetadataLoader { } } -pub struct MetadataOnlyTransCrate; +pub struct MetadataOnlyTransCrate(()); pub struct OngoingCrateTranslation { metadata: EncodedMetadata, metadata_version: Vec<u8>, crate_name: Symbol, } -pub struct TranslatedCrate(OngoingCrateTranslation); impl MetadataOnlyTransCrate { - #[allow(dead_code)] - pub fn new() -> Self { - MetadataOnlyTransCrate + pub fn new(sess: &Session) -> Box<TransCrate> { + for cty in sess.opts.crate_types.iter() { + match *cty { + CrateType::CrateTypeRlib | CrateType::CrateTypeDylib | + CrateType::CrateTypeExecutable => {}, + _ => { + sess.parse_sess.span_diagnostic.warn( + &format!("LLVM unsupported, so output type {} is not supported", cty) + ); + }, + } + } + + box MetadataOnlyTransCrate(()) } } impl TransCrate for MetadataOnlyTransCrate { - type MetadataLoader = NoLlvmMetadataLoader; - type OngoingCrateTranslation = OngoingCrateTranslation; - type TranslatedCrate = TranslatedCrate; - - fn metadata_loader() -> Box<MetadataLoaderTrait> { + fn metadata_loader(&self) -> Box<MetadataLoader> { box NoLlvmMetadataLoader } - fn provide(_providers: &mut Providers) {} - fn provide_extern(_providers: &mut Providers) {} + fn provide(&self, providers: &mut Providers) { + ::symbol_names::provide(providers); + providers.target_features_enabled = |_tcx, _id| { + Rc::new(Vec::new()) // Just a dummy + }; + } + fn provide_extern(&self, _providers: &mut Providers) {} fn trans_crate<'a, 'tcx>( + &self, tcx: TyCtxt<'a, 'tcx, 'tcx>, _rx: mpsc::Receiver<Box<Any + Send>> - ) -> Self::OngoingCrateTranslation { + ) -> Box<Any> { + use rustc_mir::monomorphize::item::MonoItem; + ::check_for_rustc_errors_attr(tcx); + ::symbol_names_test::report_symbol_names(tcx); + ::rustc_incremental::assert_dep_graph(tcx); + ::rustc_incremental::assert_module_sources::assert_module_sources(tcx); + ::rustc_mir::monomorphize::assert_symbols_are_distinct(tcx, + collector::collect_crate_mono_items( + tcx, + collector::MonoItemCollectionMode::Eager + ).0.iter() + ); + ::rustc::middle::dependency_format::calculate(tcx); let _ = tcx.link_args(LOCAL_CRATE); let _ = tcx.native_libraries(LOCAL_CRATE); + for trans_item in + collector::collect_crate_mono_items( + tcx, + collector::MonoItemCollectionMode::Eager + ).0 { + match trans_item { + MonoItem::Fn(inst) => { + let def_id = inst.def_id(); + if def_id.is_local() { + let _ = tcx.export_name(def_id); + let _ = tcx.contains_extern_indicator(def_id); + let _ = inst.def.is_inline(tcx); + let attrs = inst.def.attrs(tcx); + let _ = + ::syntax::attr::find_inline_attr(Some(tcx.sess.diagnostic()), &attrs); + } + } + _ => {} + } + } tcx.sess.abort_if_errors(); let link_meta = build_link_meta(tcx.crate_hash(LOCAL_CRATE)); let exported_symbols = ::find_exported_symbols(tcx); let metadata = tcx.encode_metadata(&link_meta, &exported_symbols); - OngoingCrateTranslation { + box OngoingCrateTranslation { metadata: metadata, metadata_version: tcx.metadata_encoding_version().to_vec(), crate_name: tcx.crate_name(LOCAL_CRATE), } } - fn join_trans( - trans: Self::OngoingCrateTranslation, - _sess: &Session, + fn join_trans_and_link( + &self, + trans: Box<Any>, + sess: &Session, _dep_graph: &DepGraph, - ) -> Self::TranslatedCrate { - TranslatedCrate(trans) - } - - fn link_binary(sess: &Session, trans: &Self::TranslatedCrate, outputs: &OutputFilenames) { + outputs: &OutputFilenames, + ) -> Result<(), CompileIncomplete> { + let trans = trans.downcast::<OngoingCrateTranslation>() + .expect("Expected MetadataOnlyTransCrate's OngoingCrateTranslation, found Box<Any>"); for &crate_type in sess.opts.crate_types.iter() { if crate_type != CrateType::CrateTypeRlib && crate_type != CrateType::CrateTypeDylib { continue; } let output_name = - out_filename(sess, crate_type, &outputs, &trans.0.crate_name.as_str()); - let mut compressed = trans.0.metadata_version.clone(); + out_filename(sess, crate_type, &outputs, &trans.crate_name.as_str()); + let mut compressed = trans.metadata_version.clone(); let metadata = if crate_type == CrateType::CrateTypeDylib { DeflateEncoder::new(&mut compressed, Compression::fast()) - .write_all(&trans.0.metadata.raw_data) + .write_all(&trans.metadata.raw_data) .unwrap(); &compressed } else { - &trans.0.metadata.raw_data + &trans.metadata.raw_data }; let mut builder = Builder::new(File::create(&output_name).unwrap()); let header = Header::new("rust.metadata.bin".to_string(), metadata.len() as u64); builder.append(&header, Cursor::new(metadata)).unwrap(); } + sess.abort_if_errors(); if !sess.opts.crate_types.contains(&CrateType::CrateTypeRlib) - && !sess.opts.crate_types.contains(&CrateType::CrateTypeDylib) { + && !sess.opts.crate_types.contains(&CrateType::CrateTypeDylib) + { sess.fatal("Executables are not supported by the metadata-only backend."); } + Ok(()) } - - fn dump_incremental_data(_trans: &Self::TranslatedCrate) {} } diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index df1694a6010..5c5e5f2735b 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -210,15 +210,25 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } } - let mut err = type_error_struct!(self.tcx.sess, call_expr.span, callee_ty, E0618, - "expected function, found `{}`", - if let Some(ref path) = unit_variant { - path.to_string() - } else { - callee_ty.to_string() - }); - if let Some(path) = unit_variant { - err.help(&format!("did you mean to write `{}`?", path)); + + let mut err = type_error_struct!( + self.tcx.sess, + call_expr.span, + callee_ty, + E0618, + "expected function, found {}", + match unit_variant { + Some(ref path) => format!("enum variant `{}`", path), + None => format!("`{}`", callee_ty), + }); + + err.span_label(call_expr.span, "not a function"); + + if let Some(ref path) = unit_variant { + err.span_suggestion(call_expr.span, + &format!("`{}` is a unit variant, you need to write it \ + without the parenthesis", path), + path.to_string()); } if let hir::ExprCall(ref expr, _) = call_expr.node { @@ -235,7 +245,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { _ => self.tcx.hir.span_if_local(def.def_id()) }; if let Some(span) = def_span { - err.span_note(span, "defined here"); + let name = match unit_variant { + Some(path) => path, + None => callee_ty.to_string(), + }; + err.span_label(span, format!("`{}` defined here", name)); } } diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 734287f5f7d..570eecfc267 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -518,7 +518,10 @@ fn compare_self_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, self_descr); err.span_label(impl_m_span, format!("`{}` used in impl", self_descr)); if let Some(span) = tcx.hir.span_if_local(trait_m.def_id) { - err.span_label(span, format!("trait declared without `{}`", self_descr)); + err.span_label(span, format!("trait method declared without `{}`", self_descr)); + } else { + err.note_trait_signature(trait_m.name.to_string(), + trait_m.signature(&tcx)); } err.emit(); return Err(ErrorReported); @@ -533,8 +536,7 @@ fn compare_self_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, not in the impl", trait_m.name, self_descr); - err.span_label(impl_m_span, - format!("expected `{}` in impl", self_descr)); + err.span_label(impl_m_span, format!("expected `{}` in impl", self_descr)); if let Some(span) = tcx.hir.span_if_local(trait_m.def_id) { err.span_label(span, format!("`{}` used in trait", self_descr)); } else { diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 6703bbba86b..b6b863cfea6 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -15,6 +15,7 @@ use rustc::infer::InferOk; use rustc::traits::ObligationCause; use syntax::ast; +use syntax::util::parser::AssocOp; use syntax_pos::{self, Span}; use rustc::hir; use rustc::hir::print; @@ -137,7 +138,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if let Some((msg, suggestion)) = self.check_ref(expr, checked_ty, expected) { err.span_suggestion(expr.span, msg, suggestion); - } else { + } else if !self.check_for_cast(&mut err, expr, expr_ty, expected) { let methods = self.get_conversion_methods(expected, checked_ty); if let Ok(expr_text) = self.tcx.sess.codemap().span_to_snippet(expr.span) { let suggestions = iter::repeat(expr_text).zip(methods.iter()) @@ -287,8 +288,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Maybe remove `&`? hir::ExprAddrOf(_, ref expr) => { if let Ok(code) = self.tcx.sess.codemap().span_to_snippet(expr.span) { - return Some(("consider removing the borrow", - code)); + return Some(("consider removing the borrow", code)); } } @@ -303,7 +303,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { format!("*{}", code))); } } - }, + } } } None @@ -311,4 +311,240 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { _ => None, } } + + fn check_for_cast(&self, + err: &mut DiagnosticBuilder<'tcx>, + expr: &hir::Expr, + checked_ty: Ty<'tcx>, + expected_ty: Ty<'tcx>) + -> bool { + let will_truncate = "will truncate the source value"; + let depending_on_isize = "will truncate or zero-extend depending on the bit width of \ + `isize`"; + let depending_on_usize = "will truncate or zero-extend depending on the bit width of \ + `usize`"; + let will_sign_extend = "will sign-extend the source value"; + let will_zero_extend = "will zero-extend the source value"; + + // If casting this expression to a given numeric type would be appropriate in case of a type + // mismatch. + // + // We want to minimize the amount of casting operations that are suggested, as it can be a + // lossy operation with potentially bad side effects, so we only suggest when encountering + // an expression that indicates that the original type couldn't be directly changed. + // + // For now, don't suggest casting with `as`. + let can_cast = false; + + let needs_paren = expr.precedence().order() < (AssocOp::As.precedence() as i8); + + if let Ok(src) = self.tcx.sess.codemap().span_to_snippet(expr.span) { + let msg = format!("you can cast an `{}` to `{}`", checked_ty, expected_ty); + let cast_suggestion = format!("{}{}{} as {}", + if needs_paren { "(" } else { "" }, + src, + if needs_paren { ")" } else { "" }, + expected_ty); + let into_suggestion = format!("{}{}{}.into()", + if needs_paren { "(" } else { "" }, + src, + if needs_paren { ")" } else { "" }); + + match (&expected_ty.sty, &checked_ty.sty) { + (&ty::TyInt(ref exp), &ty::TyInt(ref found)) => { + match (found.bit_width(), exp.bit_width()) { + (Some(found), Some(exp)) if found > exp => { + if can_cast { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, will_truncate), + cast_suggestion); + } + } + (None, _) | (_, None) => { + if can_cast { + err.span_suggestion(expr.span, + &format!("{}, which {}", + msg, + depending_on_isize), + cast_suggestion); + } + } + _ => { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, will_sign_extend), + into_suggestion); + } + } + true + } + (&ty::TyUint(ref exp), &ty::TyUint(ref found)) => { + match (found.bit_width(), exp.bit_width()) { + (Some(found), Some(exp)) if found > exp => { + if can_cast { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, will_truncate), + cast_suggestion); + } + } + (None, _) | (_, None) => { + if can_cast { + err.span_suggestion(expr.span, + &format!("{}, which {}", + msg, + depending_on_usize), + cast_suggestion); + } + } + _ => { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, will_zero_extend), + into_suggestion); + } + } + true + } + (&ty::TyInt(ref exp), &ty::TyUint(ref found)) => { + if can_cast { + match (found.bit_width(), exp.bit_width()) { + (Some(found), Some(exp)) if found > exp - 1 => { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, will_truncate), + cast_suggestion); + } + (None, None) => { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, will_truncate), + cast_suggestion); + } + (None, _) => { + err.span_suggestion(expr.span, + &format!("{}, which {}", + msg, + depending_on_isize), + cast_suggestion); + } + (_, None) => { + err.span_suggestion(expr.span, + &format!("{}, which {}", + msg, + depending_on_usize), + cast_suggestion); + } + _ => { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, will_zero_extend), + cast_suggestion); + } + } + } + true + } + (&ty::TyUint(ref exp), &ty::TyInt(ref found)) => { + if can_cast { + match (found.bit_width(), exp.bit_width()) { + (Some(found), Some(exp)) if found - 1 > exp => { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, will_truncate), + cast_suggestion); + } + (None, None) => { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, will_sign_extend), + cast_suggestion); + } + (None, _) => { + err.span_suggestion(expr.span, + &format!("{}, which {}", + msg, + depending_on_usize), + cast_suggestion); + } + (_, None) => { + err.span_suggestion(expr.span, + &format!("{}, which {}", + msg, + depending_on_isize), + cast_suggestion); + } + _ => { + err.span_suggestion(expr.span, + &format!("{}, which {}", msg, will_sign_extend), + cast_suggestion); + } + } + } + true + } + (&ty::TyFloat(ref exp), &ty::TyFloat(ref found)) => { + if found.bit_width() < exp.bit_width() { + err.span_suggestion(expr.span, + &format!("{} in a lossless way", + msg), + into_suggestion); + } else if can_cast { + err.span_suggestion(expr.span, + &format!("{}, producing the closest possible value", + msg), + cast_suggestion); + err.warn("casting here will cause undefined behavior if the value is \ + finite but larger or smaller than the largest or smallest \ + finite value representable by `f32` (this is a bug and will be \ + fixed)"); + } + true + } + (&ty::TyUint(_), &ty::TyFloat(_)) | (&ty::TyInt(_), &ty::TyFloat(_)) => { + if can_cast { + err.span_suggestion(expr.span, + &format!("{}, rounding the float towards zero", + msg), + cast_suggestion); + err.warn("casting here will cause undefined behavior if the rounded value \ + cannot be represented by the target integer type, including \ + `Inf` and `NaN` (this is a bug and will be fixed)"); + } + true + } + (&ty::TyFloat(ref exp), &ty::TyUint(ref found)) => { + // if `found` is `None` (meaning found is `usize`), don't suggest `.into()` + if exp.bit_width() > found.bit_width().unwrap_or(256) { + err.span_suggestion(expr.span, + &format!("{}, producing the floating point \ + representation of the integer", + msg), + into_suggestion); + } else if can_cast { + err.span_suggestion(expr.span, + &format!("{}, producing the floating point \ + representation of the integer, rounded if \ + necessary", + msg), + cast_suggestion); + } + true + } + (&ty::TyFloat(ref exp), &ty::TyInt(ref found)) => { + // if `found` is `None` (meaning found is `isize`), don't suggest `.into()` + if exp.bit_width() > found.bit_width().unwrap_or(256) { + err.span_suggestion(expr.span, + &format!("{}, producing the floating point \ + representation of the integer", + msg), + into_suggestion); + } else if can_cast { + err.span_suggestion(expr.span, + &format!("{}, producing the floating point \ + representation of the integer, rounded if \ + necessary", + msg), + cast_suggestion); + } + true + } + _ => false, + } + } else { + false + } + } } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 69236d77ed3..cb8ce8d5ac3 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -101,6 +101,7 @@ use rustc::ty::adjustment::{Adjust, Adjustment, AutoBorrow}; use rustc::ty::fold::TypeFoldable; use rustc::ty::maps::Providers; use rustc::ty::util::{Representability, IntTypeExt}; +use rustc::ty::layout::LayoutOf; use errors::{DiagnosticBuilder, DiagnosticId}; use require_c_abi_if_variadic; use session::{CompileIncomplete, config, Session}; @@ -1104,6 +1105,7 @@ fn check_struct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, check_simd(tcx, span, def_id); } + check_transparent(tcx, span, def_id); check_packed(tcx, span, def_id); } @@ -1517,6 +1519,42 @@ fn check_packed_inner<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, false } +fn check_transparent<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: DefId) { + let adt = tcx.adt_def(def_id); + if !adt.repr.transparent() { + return; + } + + // For each field, figure out if it's known to be a ZST and align(1) + let field_infos: Vec<_> = adt.non_enum_variant().fields.iter().map(|field| { + let ty = field.ty(tcx, Substs::identity_for_item(tcx, field.did)); + let param_env = tcx.param_env(field.did); + let layout = (tcx, param_env).layout_of(ty); + // 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); + (span, zst, align1) + }).collect(); + + let non_zst_fields = field_infos.iter().filter(|(_span, zst, _align1)| !*zst); + let non_zst_count = non_zst_fields.clone().count(); + if non_zst_count != 1 { + let field_spans: Vec<_> = non_zst_fields.map(|(span, _zst, _align1)| *span).collect(); + struct_span_err!(tcx.sess, sp, E0690, + "transparent struct needs exactly one non-zero-sized field, but has {}", + non_zst_count) + .span_note(field_spans, "non-zero-sized field") + .emit(); + } + for &(span, zst, align1) in &field_infos { + if zst && !align1 { + span_err!(tcx.sess, span, E0691, + "zero-sized field in transparent struct has alignment larger than 1"); + } + } +} + #[allow(trivial_numeric_casts)] pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 60d28fb0e08..3668fc46ddc 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -107,16 +107,21 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { // // won't be allowed unless there's an *explicit* implementation of `Send` // for `T` - hir::ItemImpl(_, hir::ImplPolarity::Positive, _, _, - ref trait_ref, ref self_ty, _) => { - self.check_impl(item, self_ty, trait_ref); - } - hir::ItemImpl(_, hir::ImplPolarity::Negative, _, _, Some(_), ..) => { - // FIXME(#27579) what amount of WF checking do we need for neg impls? - - let trait_ref = tcx.impl_trait_ref(tcx.hir.local_def_id(item.id)).unwrap(); - if !tcx.trait_is_auto(trait_ref.def_id) { - error_192(tcx, item.span); + hir::ItemImpl(_, polarity, defaultness, _, ref trait_ref, ref self_ty, _) => { + let is_auto = tcx.impl_trait_ref(tcx.hir.local_def_id(item.id)) + .map_or(false, |trait_ref| tcx.trait_is_auto(trait_ref.def_id)); + if let (hir::Defaultness::Default { .. }, true) = (defaultness, is_auto) { + tcx.sess.span_err(item.span, "impls of auto traits cannot be default"); + } + if polarity == hir::ImplPolarity::Positive { + self.check_impl(item, self_ty, trait_ref); + } else { + // FIXME(#27579) what amount of WF checking do we need for neg impls? + if trait_ref.is_some() && !is_auto { + span_err!(tcx.sess, item.span, E0192, + "negative impls are only allowed for \ + auto traits (e.g., `Send` and `Sync`)") + } } } hir::ItemFn(..) => { @@ -661,12 +666,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } -fn error_192(tcx: TyCtxt, span: Span) { - span_err!(tcx.sess, span, E0192, - "negative impls are only allowed for traits with \ - default impls (e.g., `Send` and `Sync`)") -} - fn error_392<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span: Span, param_name: ast::Name) -> DiagnosticBuilder<'tcx> { let mut err = struct_span_err!(tcx.sess, span, E0392, diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs index 4256a1fe12b..2b81c82bc29 100644 --- a/src/librustc_typeck/coherence/inherent_impls.rs +++ b/src/librustc_typeck/coherence/inherent_impls.rs @@ -93,23 +93,11 @@ struct InherentCollect<'a, 'tcx: 'a> { impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> { fn visit_item(&mut self, item: &hir::Item) { - let (unsafety, ty) = match item.node { - hir::ItemImpl(unsafety, .., None, ref ty, _) => (unsafety, ty), + let ty = match item.node { + hir::ItemImpl(.., None, ref ty, _) => ty, _ => return }; - match unsafety { - hir::Unsafety::Normal => { - // OK - } - hir::Unsafety::Unsafe => { - span_err!(self.tcx.sess, - item.span, - E0197, - "inherent impls cannot be declared as unsafe"); - } - } - let def_id = self.tcx.hir.local_def_id(item.id); let self_ty = self.tcx.type_of(def_id); let lang_items = self.tcx.lang_items(); diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index ab19a862a66..c2dfd798a3c 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -67,16 +67,15 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> { } } - // In addition to the above rules, we restrict impls of defaulted traits + // In addition to the above rules, we restrict impls of auto traits // so that they can only be implemented on nominal types, such as structs, // enums or foreign types. To see why this restriction exists, consider the - // following example (#22978). Imagine that crate A defines a defaulted trait + // following example (#22978). Imagine that crate A defines an auto trait // `Foo` and a fn that operates on pairs of types: // // ``` // // Crate A - // trait Foo { } - // impl Foo for .. { } + // auto trait Foo { } // fn two_foos<A:Foo,B:Foo>(..) { // one_foo::<(A,B)>(..) // } diff --git a/src/librustc_typeck/coherence/unsafety.rs b/src/librustc_typeck/coherence/unsafety.rs index c924a3364eb..4aa876e85b6 100644 --- a/src/librustc_typeck/coherence/unsafety.rs +++ b/src/librustc_typeck/coherence/unsafety.rs @@ -37,14 +37,7 @@ impl<'cx, 'tcx, 'v> UnsafetyChecker<'cx, 'tcx> { let trait_def = self.tcx.trait_def(trait_ref.def_id); let unsafe_attr = impl_generics.and_then(|g| g.carries_unsafe_attr()); match (trait_def.unsafety, unsafe_attr, unsafety, polarity) { - (_, _, Unsafety::Unsafe, hir::ImplPolarity::Negative) => { - span_err!(self.tcx.sess, - item.span, - E0198, - "negative implementations are not unsafe"); - } - - (Unsafety::Normal, None, Unsafety::Unsafe, _) => { + (Unsafety::Normal, None, Unsafety::Unsafe, hir::ImplPolarity::Positive) => { span_err!(self.tcx.sess, item.span, E0199, @@ -69,6 +62,10 @@ impl<'cx, 'tcx, 'v> UnsafetyChecker<'cx, 'tcx> { g.attr_name()); } + (_, _, Unsafety::Unsafe, hir::ImplPolarity::Negative) => { + // Reported in AST validation + self.tcx.sess.delay_span_bug(item.span, "unsafe negative impl"); + } (_, _, Unsafety::Normal, hir::ImplPolarity::Negative) | (Unsafety::Unsafe, _, Unsafety::Unsafe, hir::ImplPolarity::Positive) | (Unsafety::Normal, Some(_), Unsafety::Unsafe, hir::ImplPolarity::Positive) | diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 11b983fd314..4f661a4f5e6 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -1715,7 +1715,7 @@ type Foo = Trait<Bar=i32>; // ok! "##, E0192: r##" -Negative impls are only allowed for traits with default impls. For more +Negative impls are only allowed for auto traits. For more information see the [opt-in builtin traits RFC][RFC 19]. [RFC 19]: https://github.com/rust-lang/rfcs/blob/master/text/0019-opt-in-builtin-traits.md @@ -1821,52 +1821,6 @@ impl Trait for Foo { ``` "##, -E0197: r##" -Inherent implementations (one that do not implement a trait but provide -methods associated with a type) are always safe because they are not -implementing an unsafe trait. Removing the `unsafe` keyword from the inherent -implementation will resolve this error. - -```compile_fail,E0197 -struct Foo; - -// this will cause this error -unsafe impl Foo { } -// converting it to this will fix it -impl Foo { } -``` -"##, - -E0198: r##" -A negative implementation is one that excludes a type from implementing a -particular trait. Not being able to use a trait is always a safe operation, -so negative implementations are always safe and never need to be marked as -unsafe. - -```compile_fail -#![feature(optin_builtin_traits)] - -struct Foo; - -// unsafe is unnecessary -unsafe impl !Clone for Foo { } -``` - -This will compile: - -``` -#![feature(optin_builtin_traits)] - -struct Foo; - -auto trait Enterprise {} - -impl !Enterprise for Foo { } -``` - -Please note that negative impls are only allowed for traits with default impls. -"##, - E0199: r##" Safe traits should not have unsafe implementations, therefore marking an implementation for a safe trait unsafe will cause a compiler error. Removing @@ -4651,6 +4605,99 @@ let _ = x.powi(2); let _ = (2.0 as f32).powi(2); ``` "##, + +E0690: r##" +A struct with the representation hint `repr(transparent)` had zero or more than +on fields that were not guaranteed to be zero-sized. + +Erroneous code example: + +```compile_fail,E0690 +#![feature(repr_transparent)] + +#[repr(transparent)] +struct LengthWithUnit<U> { // error: transparent struct needs exactly one + value: f32, // non-zero-sized field, but has 2 + unit: U, +} +``` + +Because transparent structs are represented exactly like one of their fields at +run time, said field must be uniquely determined. If there is no field, or if +there are multiple fields, it is not clear how the struct should be represented. +Note that fields of zero-typed types (e.g., `PhantomData`) can also exist +alongside the field that contains the actual data, they do not count for this +error. When generic types are involved (as in the above example), an error is +reported because the type parameter could be non-zero-sized. + +To combine `repr(transparent)` with type parameters, `PhantomData` may be +useful: + +``` +#![feature(repr_transparent)] + +use std::marker::PhantomData; + +#[repr(transparent)] +struct LengthWithUnit<U> { + value: f32, + unit: PhantomData<U>, +} +``` +"##, + +E0691: r##" +A struct with the `repr(transparent)` representation hint contains a zero-sized +field that requires non-trivial alignment. + +Erroneous code example: + +```compile_fail,E0691 +#![feature(repr_transparent, repr_align, attr_literals)] + +#[repr(align(32))] +struct ForceAlign32; + +#[repr(transparent)] +struct Wrapper(f32, ForceAlign32); // error: zero-sized field in transparent + // struct has alignment larger than 1 +``` + +A transparent struct is supposed to be represented exactly like the piece of +data it contains. Zero-sized fields with different alignment requirements +potentially conflict with this property. In the example above, `Wrapper` would +have to be aligned to 32 bytes even though `f32` has a smaller alignment +requirement. + +Consider removing the over-aligned zero-sized field: + +``` +#![feature(repr_transparent)] + +#[repr(transparent)] +struct Wrapper(f32); +``` + +Alternatively, `PhantomData<T>` has alignment 1 for all `T`, so you can use it +if you need to keep the field for some reason: + +``` +#![feature(repr_transparent, repr_align, attr_literals)] + +use std::marker::PhantomData; + +#[repr(align(32))] +struct ForceAlign32; + +#[repr(transparent)] +struct Wrapper(f32, PhantomData<ForceAlign32>); +``` + +Note that empty arrays `[T; 0]` have the same alignment requirement as the +element type `T`. Also note that the error is conservatively reported even when +the alignment of the zero-sized type is less than or equal to the data field's +alignment. +"##, } register_diagnostics! { diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 1dc98bc7a00..786a6783440 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -77,6 +77,7 @@ This API is completely unstable and subject to change. #![feature(box_syntax)] #![feature(crate_visibility_modifier)] #![feature(conservative_impl_trait)] +#![feature(copy_closures, clone_closures)] #![feature(from_ref)] #![feature(match_default_bindings)] #![feature(never_type)] diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index 1e574964b12..608adcb43d6 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -12,7 +12,7 @@ doctest = false [dependencies] pulldown-cmark = { version = "0.1.0", default-features = false } -html-diff = "0.0.5" +html-diff = "0.0.6" tempdir = "0.3" [build-dependencies] diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 496389da7f2..b8c34d78d30 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -82,9 +82,9 @@ pub fn try_inline(cx: &DocContext, def: Def, name: ast::Name) ret.extend(build_impls(cx, did)); clean::ForeignTypeItem } - // Never inline enum variants but leave them shown as reexports. + // Never inline enum variants but leave them shown as re-exports. Def::Variant(..) => return None, - // Assume that enum variants and struct types are reexported next to + // Assume that enum variants and struct types are re-exported next to // their constructors. Def::VariantCtor(..) | Def::StructCtor(..) => return Some(Vec::new()), @@ -328,6 +328,9 @@ pub fn build_impl(cx: &DocContext, did: DefId, ret: &mut Vec<clean::Item>) { if trait_.def_id() == tcx.lang_items().deref_trait() { super::build_deref_target_impls(cx, &trait_items, ret); } + if let Some(trait_did) = trait_.def_id() { + record_extern_trait(cx, trait_did); + } let provided = trait_.def_id().map(|did| { tcx.provided_trait_methods(did) @@ -365,7 +368,7 @@ fn build_module(cx: &DocContext, did: DefId) -> clean::Module { }; fn fill_in(cx: &DocContext, did: DefId, items: &mut Vec<clean::Item>) { - // If we're reexporting a reexport it may actually reexport something in + // If we're re-exporting a re-export it may actually re-export something in // two namespaces, so the target may be listed twice. Make sure we only // visit each node at most once. let mut visited = FxHashSet(); @@ -483,3 +486,9 @@ fn separate_supertrait_bounds(mut g: clean::Generics) }); (g, ty_bounds) } + +pub fn record_extern_trait(cx: &DocContext, did: DefId) { + cx.external_traits.borrow_mut().entry(did).or_insert_with(|| { + build_external_trait(cx, did) + }); +} diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 271bc967bc9..cc75664cacb 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -3163,8 +3163,7 @@ fn register_def(cx: &DocContext, def: Def) -> DefId { if did.is_local() { return did } inline::record_extern_fqn(cx, did, kind); if let TypeKind::Trait = kind { - let t = inline::build_external_trait(cx, did); - cx.external_traits.borrow_mut().insert(did, t); + inline::record_extern_trait(cx, did); } did } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index b353c0da865..ef7d5b5ff84 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -19,7 +19,6 @@ use rustc::hir::map as hir_map; use rustc::lint; use rustc::util::nodemap::FxHashMap; use rustc_trans; -use rustc_trans::back::link; use rustc_resolve as resolve; use rustc_metadata::cstore::CStore; @@ -140,22 +139,22 @@ pub fn run_core(search_paths: SearchPaths, false, Some(codemap.clone())); - let cstore = Rc::new(CStore::new(box rustc_trans::LlvmMetadataLoader)); let mut sess = session::build_session_( sessopts, cpath, diagnostic_handler, codemap, ); - rustc_trans::init(&sess); + let trans = rustc_trans::LlvmTransCrate::new(&sess); + let cstore = Rc::new(CStore::new(trans.metadata_loader())); rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); let mut cfg = config::build_configuration(&sess, config::parse_cfgspecs(cfgs)); - target_features::add_configuration(&mut cfg, &sess); + target_features::add_configuration(&mut cfg, &sess, &*trans); sess.parse_sess.config = cfg; let control = &driver::CompileController::basic(); let krate = panictry!(driver::phase_1_parse_input(control, &sess, &input)); - let name = link::find_crate_name(Some(&sess), &krate.attrs, &input); + let name = ::rustc_trans_utils::link::find_crate_name(Some(&sess), &krate.attrs, &input); let driver::ExpansionResult { defs, analysis, resolutions, mut hir_forest, .. } = { let result = driver::phase_2_configure_and_expand(&sess, @@ -177,7 +176,8 @@ pub fn run_core(search_paths: SearchPaths, &[], &sess); - abort_on_err(driver::phase_3_run_analysis_passes(control, + abort_on_err(driver::phase_3_run_analysis_passes(&*trans, + control, &sess, &*cstore, hir_map, diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index 61de5f4bc4c..3a18c6b8a80 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -94,20 +94,22 @@ r##"<!DOCTYPE html> <h2>Keyboard Shortcuts</h2> <dl> - <dt>?</dt> + <dt><kbd>?</kbd></dt> <dd>Show this help dialog</dd> - <dt>S</dt> + <dt><kbd>S</kbd></dt> <dd>Focus the search field</dd> - <dt>↑</dt> + <dt><kbd>↑</kbd></dt> <dd>Move up in search results</dd> - <dt>↓</dt> + <dt><kbd>↓</kbd></dt> <dd>Move down in search results</dd> - <dt>↹</dt> + <dt><kbd>↹</kbd></dt> <dd>Switch tab</dd> - <dt>⏎</dt> + <dt><kbd>⏎</kbd></dt> <dd>Go to active search result</dd> - <dt style="width:31px;">+ / -</dt> - <dd>Collapse/expand all sections</dd> + <dt><kbd>+</kbd></dt> + <dd>Expand all sections</dd> + <dt><kbd>-</kbd></dt> + <dd>Collapse all sections</dd> </dl> </div> diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 6e4980c9e91..cfa09ea30a8 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1286,9 +1286,9 @@ impl DocFolder for Cache { clean::ConstantItem(..) | clean::StaticItem(..) | clean::UnionItem(..) | clean::ForeignTypeItem if !self.stripped_mod => { - // Reexported items mean that the same id can show up twice + // Re-exported items mean that the same id can show up twice // in the rustdoc ast that we're looking at. We know, - // however, that a reexported item doesn't show up in the + // however, that a re-exported item doesn't show up in the // `public_items` map, so we can skip inserting into the // paths map if there was already an entry present and we're // not a public item. @@ -1545,7 +1545,7 @@ impl Context { { // Stripped modules survive the rustdoc passes (i.e. `strip-private`) // if they contain impls for public types. These modules can also - // contain items such as publicly reexported structures. + // contain items such as publicly re-exported structures. // // External crates will provide links to these structures, so // these modules are recursed into, but not rendered normally @@ -2008,7 +2008,7 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context, if cx.shared.sort_modules_alphabetically { indices.sort_by(|&i1, &i2| cmp(&items[i1], &items[i2], i1, i2)); } - // This call is to remove reexport duplicates in cases such as: + // This call is to remove re-export duplicates in cases such as: // // ``` // pub mod foo { @@ -2059,7 +2059,7 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context, curty = myty; let (short, name) = match myty.unwrap() { ItemType::ExternCrate | - ItemType::Import => ("reexports", "Reexports"), + ItemType::Import => ("reexports", "Re-exports"), ItemType::Module => ("modules", "Modules"), ItemType::Struct => ("structs", "Structs"), ItemType::Union => ("unions", "Unions"), @@ -3277,8 +3277,7 @@ fn spotlight_decl(decl: &clean::FnDecl) -> Result<String, fmt::Error> { if let Some(impls) = c.impls.get(&did) { for i in impls { let impl_ = i.inner_impl(); - if impl_.trait_.def_id().and_then(|d| c.traits.get(&d)) - .map_or(false, |t| t.is_spotlight) { + if impl_.trait_.def_id().map_or(false, |d| c.traits[&d].is_spotlight) { if out.is_empty() { out.push_str( &format!("<h3 class=\"important\">Important traits for {}</h3>\ @@ -3444,7 +3443,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi } let traits = &cache().traits; - let trait_ = i.trait_did().and_then(|did| traits.get(&did)); + let trait_ = i.trait_did().map(|did| &traits[&did]); if !show_def_docs { write!(w, "<span class='docblock autohide'>")?; @@ -3959,7 +3958,7 @@ fn sidebar_module(fmt: &mut fmt::Formatter, _it: &clean::Item, it.type_() == ItemType::Import) { sidebar.push_str(&format!("<li><a href=\"#{id}\">{name}</a></li>", id = "reexports", - name = "Reexports")); + name = "Re-exports")); } // ordering taken from item_module, reorder, where it prioritized elements in a certain order @@ -3972,7 +3971,7 @@ fn sidebar_module(fmt: &mut fmt::Formatter, _it: &clean::Item, if items.iter().any(|it| !it.is_stripped() && it.type_() == myty) { let (short, name) = match myty { ItemType::ExternCrate | - ItemType::Import => ("reexports", "Reexports"), + ItemType::Import => ("reexports", "Re-exports"), ItemType::Module => ("modules", "Modules"), ItemType::Struct => ("structs", "Structs"), ItemType::Union => ("unions", "Unions"), diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index b4dbd76d0b4..a9a5bd5de05 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -353,35 +353,33 @@ * This code is an unmodified version of the code written by Marco de Wit * and was found at http://stackoverflow.com/a/18514751/745719 */ - var levenshtein = (function() { - var row2 = []; - return function(s1, s2) { - if (s1 === s2) { - return 0; + var levenshtein_row2 = []; + function levenshtein(s1, s2) { + if (s1 === s2) { + return 0; + } + var s1_len = s1.length, s2_len = s2.length; + if (s1_len && s2_len) { + var i1 = 0, i2 = 0, a, b, c, c2, row = levenshtein_row2; + while (i1 < s1_len) { + row[i1] = ++i1; } - var s1_len = s1.length, s2_len = s2.length; - if (s1_len && s2_len) { - var i1 = 0, i2 = 0, a, b, c, c2, row = row2; - while (i1 < s1_len) { - row[i1] = ++i1; - } - while (i2 < s2_len) { - c2 = s2.charCodeAt(i2); - a = i2; - ++i2; - b = i2; - for (i1 = 0; i1 < s1_len; ++i1) { - c = a + (s1.charCodeAt(i1) !== c2 ? 1 : 0); - a = row[i1]; - b = b < a ? (b < c ? b + 1 : c) : (a < c ? a + 1 : c); - row[i1] = b; - } + while (i2 < s2_len) { + c2 = s2.charCodeAt(i2); + a = i2; + ++i2; + b = i2; + for (i1 = 0; i1 < s1_len; ++i1) { + c = a + (s1.charCodeAt(i1) !== c2 ? 1 : 0); + a = row[i1]; + b = b < a ? (b < c ? b + 1 : c) : (a < c ? a + 1 : c); + row[i1] = b; } - return b; } - return s1_len + s2_len; - }; - })(); + return b; + } + return s1_len + s2_len; + } function initSearch(rawSearchIndex) { var currentResults, index, searchIndex; @@ -400,12 +398,20 @@ /** * Executes the query and builds an index of results * @param {[Object]} query [The user query] - * @param {[type]} max [The maximum results returned] * @param {[type]} searchWords [The list of search words to query * against] * @return {[type]} [A search index of results] */ - function execQuery(query, max, searchWords) { + function execQuery(query, searchWords) { + function itemTypeFromName(typename) { + for (var i = 0; i < itemTypes.length; ++i) { + if (itemTypes[i] === typename) { + return i; + } + } + return -1; + } + var valLower = query.query.toLowerCase(), val = valLower, typeFilter = itemTypeFromName(query.type), @@ -1021,9 +1027,8 @@ return true; } - function getQuery() { - var matches, type, query, raw = - document.getElementsByClassName('search-input')[0].value; + function getQuery(raw) { + var matches, type, query; query = raw; matches = query.match(/^(fn|mod|struct|enum|trait|type|const|macro)\s*:\s*/i); @@ -1227,7 +1232,7 @@ } function showResults(results) { - var output, query = getQuery(); + var output, query = getQuery(document.getElementsByClassName('search-input')[0].value); currentResults = query.id; output = '<h1>Results for ' + escape(query.query) + @@ -1271,7 +1276,7 @@ resultIndex; var params = getQueryStringParams(); - query = getQuery(); + query = getQuery(document.getElementsByClassName('search-input')[0].value); if (e) { e.preventDefault(); } @@ -1293,19 +1298,10 @@ } } - results = execQuery(query, 20000, index); + results = execQuery(query, index); showResults(results); } - function itemTypeFromName(typename) { - for (var i = 0; i < itemTypes.length; ++i) { - if (itemTypes[i] === typename) { - return i; - } - } - return -1; - } - function buildIndex(rawSearchIndex) { searchIndex = []; var searchWords = []; diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index b41874a56b8..34b04de8673 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -585,18 +585,13 @@ body.blur > :not(#help) { flex: 0 0 auto; box-shadow: 0 0 6px rgba(0,0,0,.2); width: 550px; - height: 354px; + height: auto; border: 1px solid; } #help dt { float: left; - border-radius: 4px; - border: 1px solid; - width: 23px; - text-align: center; clear: left; display: block; - margin-top: -1px; } #help dd { margin: 5px 35px; } #help .infos { padding-left: 0; } @@ -1134,3 +1129,14 @@ h3.important { left: -42px; margin-top: 2px; } + +kbd { + display: inline-block; + padding: 3px 5px; + font: 15px "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace; + line-height: 10px; + vertical-align: middle; + border: solid 1px; + border-radius: 3px; + box-shadow: inset 0 -1px 0; +} diff --git a/src/librustdoc/html/static/styles/main.css b/src/librustdoc/html/static/styles/main.css index c79413c0852..bd740562424 100644 --- a/src/librustdoc/html/static/styles/main.css +++ b/src/librustdoc/html/static/styles/main.css @@ -194,11 +194,6 @@ a.test-arrow { border-color: #bfbfbf; } -#help dt { - border-color: #bfbfbf; - background: #fff; -} - .since { color: grey; } @@ -348,3 +343,11 @@ pre.ignore:hover, .information:hover + pre.ignore { border-bottom-color: #e0e0e0; } } + +kbd { + color: #444d56; + background-color: #fafbfc; + border-color: #d1d5da; + border-bottom-color: #c6cbd1; + box-shadow-color: #c6cbd1; +} diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 3b43eafb849..2e2dba7681c 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -34,7 +34,7 @@ extern crate libc; extern crate rustc; extern crate rustc_data_structures; extern crate rustc_const_math; -extern crate rustc_trans; +extern crate rustc_trans_utils; extern crate rustc_driver; extern crate rustc_resolve; extern crate rustc_lint; @@ -63,6 +63,8 @@ use std::path::{Path, PathBuf}; use std::process; use std::sync::mpsc::channel; +use rustc_driver::rustc_trans; + use externalfiles::ExternalHtml; use rustc::session::search_paths::SearchPaths; use rustc::session::config::{ErrorOutputType, RustcOptGroup, nightly_options, @@ -242,8 +244,8 @@ pub fn opts() -> Vec<RustcOptGroup> { or `#![doc(html_playground_url=...)]`", "URL") }), - unstable("enable-commonmark", |o| { - o.optflag("", "enable-commonmark", "to enable commonmark doc rendering/testing") + unstable("disable-commonmark", |o| { + o.optflag("", "disable-commonmark", "to disable commonmark doc rendering/testing") }), unstable("display-warnings", |o| { o.optflag("", "display-warnings", "to print code warnings when testing doc") @@ -347,10 +349,10 @@ pub fn main_args(args: &[String]) -> isize { let css_file_extension = matches.opt_str("e").map(|s| PathBuf::from(&s)); let cfgs = matches.opt_strs("cfg"); - let render_type = if matches.opt_present("enable-commonmark") { - RenderType::Pulldown - } else { + let render_type = if matches.opt_present("disable-commonmark") { RenderType::Hoedown + } else { + RenderType::Pulldown }; if let Some(ref p) = css_file_extension { diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 5432f5cb6e1..10850f88f2d 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -34,7 +34,6 @@ use rustc_driver::driver::phase_2_configure_and_expand; use rustc_metadata::cstore::CStore; use rustc_resolve::MakeGlobMap; use rustc_trans; -use rustc_trans::back::link; use syntax::ast; use syntax::codemap::CodeMap; use syntax::feature_gate::UnstableFeatures; @@ -82,11 +81,11 @@ pub fn run(input_path: &Path, true, false, Some(codemap.clone())); - let cstore = Rc::new(CStore::new(box rustc_trans::LlvmMetadataLoader)); let mut sess = session::build_session_( sessopts, Some(input_path.to_owned()), handler, codemap.clone(), ); - rustc_trans::init(&sess); + let trans = rustc_trans::LlvmTransCrate::new(&sess); + let cstore = Rc::new(CStore::new(trans.metadata_loader())); rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); sess.parse_sess.config = config::build_configuration(&sess, config::parse_cfgspecs(cfgs.clone())); @@ -108,7 +107,7 @@ pub fn run(input_path: &Path, }; let crate_name = crate_name.unwrap_or_else(|| { - link::find_crate_name(None, &hir_forest.krate().attrs, &input) + ::rustc_trans_utils::link::find_crate_name(None, &hir_forest.krate().attrs, &input) }); let opts = scrape_test_config(hir_forest.krate()); let mut collector = Collector::new(crate_name, @@ -247,11 +246,11 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize, // Compile the code let diagnostic_handler = errors::Handler::with_emitter(true, false, box emitter); - let cstore = Rc::new(CStore::new(box rustc_trans::LlvmMetadataLoader)); let mut sess = session::build_session_( sessopts, None, diagnostic_handler, codemap, ); - rustc_trans::init(&sess); + let trans = rustc_trans::LlvmTransCrate::new(&sess); + let cstore = Rc::new(CStore::new(trans.metadata_loader())); rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); let outdir = Mutex::new(TempDir::new("rustdoctest").ok().expect("rustdoc needs a tempdir")); @@ -266,7 +265,17 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize, } let res = panic::catch_unwind(AssertUnwindSafe(|| { - driver::compile_input(&sess, &cstore, &None, &input, &out, &None, None, &control) + driver::compile_input( + trans, + &sess, + &cstore, + &None, + &input, + &out, + &None, + None, + &control + ) })); let compile_result = match res { diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 95531b468f4..1cb52d735bb 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -55,7 +55,7 @@ pub struct RustdocVisitor<'a, 'tcx: 'a> { impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { pub fn new(cstore: &'tcx CrateStore, cx: &'a core::DocContext<'a, 'tcx>) -> RustdocVisitor<'a, 'tcx> { - // If the root is reexported, terminate all recursion. + // If the root is re-exported, terminate all recursion. let mut stack = FxHashSet(); stack.insert(ast::CRATE_NODE_ID); RustdocVisitor { @@ -214,7 +214,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { let imported_from = self.cx.tcx.original_crate_name(def_id.krate); let def = match self.cstore.load_macro_untracked(def_id, self.cx.sess()) { LoadedMacro::MacroDef(macro_def) => macro_def, - // FIXME(jseyfried): document proc macro reexports + // FIXME(jseyfried): document proc macro re-exports LoadedMacro::ProcMacro(..) => continue, }; diff --git a/src/libserialize/leb128.rs b/src/libserialize/leb128.rs index a9638717c66..1786e296082 100644 --- a/src/libserialize/leb128.rs +++ b/src/libserialize/leb128.rs @@ -9,7 +9,7 @@ // except according to those terms. #[inline] -fn write_to_vec(vec: &mut Vec<u8>, position: usize, byte: u8) { +pub fn write_to_vec(vec: &mut Vec<u8>, position: usize, byte: u8) { if position == vec.len() { vec.push(byte); } else { @@ -17,56 +17,86 @@ fn write_to_vec(vec: &mut Vec<u8>, position: usize, byte: u8) { } } -#[inline] -/// encodes an integer using unsigned leb128 encoding and stores -/// the result using a callback function. -/// -/// The callback `write` is called once for each position -/// that is to be written to with the byte to be encoded -/// at that position. -pub fn write_unsigned_leb128_to<W>(mut value: u128, mut write: W) -> usize - where W: FnMut(usize, u8) -{ - let mut position = 0; - loop { - let mut byte = (value & 0x7F) as u8; - value >>= 7; - if value != 0 { - byte |= 0x80; - } - - write(position, byte); - position += 1; +#[cfg(target_pointer_width = "32")] +const USIZE_LEB128_SIZE: usize = 5; +#[cfg(target_pointer_width = "64")] +const USIZE_LEB128_SIZE: usize = 10; + +macro_rules! leb128_size { + (u16) => (3); + (u32) => (5); + (u64) => (10); + (u128) => (19); + (usize) => (USIZE_LEB128_SIZE); +} - if value == 0 { - break; +macro_rules! impl_write_unsigned_leb128 { + ($fn_name:ident, $int_ty:ident) => ( + #[inline] + pub fn $fn_name(out: &mut Vec<u8>, start_position: usize, mut value: $int_ty) -> usize { + let mut position = start_position; + for _ in 0 .. leb128_size!($int_ty) { + let mut byte = (value & 0x7F) as u8; + value >>= 7; + if value != 0 { + byte |= 0x80; + } + + write_to_vec(out, position, byte); + position += 1; + + if value == 0 { + break; + } + } + + position - start_position } - } - - position + ) } -pub fn write_unsigned_leb128(out: &mut Vec<u8>, start_position: usize, value: u128) -> usize { - write_unsigned_leb128_to(value, |i, v| write_to_vec(out, start_position+i, v)) +impl_write_unsigned_leb128!(write_u16_leb128, u16); +impl_write_unsigned_leb128!(write_u32_leb128, u32); +impl_write_unsigned_leb128!(write_u64_leb128, u64); +impl_write_unsigned_leb128!(write_u128_leb128, u128); +impl_write_unsigned_leb128!(write_usize_leb128, usize); + + +macro_rules! impl_read_unsigned_leb128 { + ($fn_name:ident, $int_ty:ident) => ( + #[inline] + pub fn $fn_name(slice: &[u8]) -> ($int_ty, usize) { + let mut result: $int_ty = 0; + let mut shift = 0; + let mut position = 0; + + for _ in 0 .. leb128_size!($int_ty) { + let byte = unsafe { + *slice.get_unchecked(position) + }; + position += 1; + result |= ((byte & 0x7F) as $int_ty) << shift; + if (byte & 0x80) == 0 { + break; + } + shift += 7; + } + + // Do a single bounds check at the end instead of for every byte. + assert!(position <= slice.len()); + + (result, position) + } + ) } -#[inline] -pub fn read_unsigned_leb128(data: &[u8], start_position: usize) -> (u128, usize) { - let mut result = 0; - let mut shift = 0; - let mut position = start_position; - loop { - let byte = data[position]; - position += 1; - result |= ((byte & 0x7F) as u128) << shift; - if (byte & 0x80) == 0 { - break; - } - shift += 7; - } +impl_read_unsigned_leb128!(read_u16_leb128, u16); +impl_read_unsigned_leb128!(read_u32_leb128, u32); +impl_read_unsigned_leb128!(read_u64_leb128, u64); +impl_read_unsigned_leb128!(read_u128_leb128, u128); +impl_read_unsigned_leb128!(read_usize_leb128, usize); + - (result, position - start_position) -} #[inline] /// encodes an integer using signed leb128 encoding and stores @@ -130,26 +160,36 @@ pub fn read_signed_leb128(data: &[u8], start_position: usize) -> (i128, usize) { (result, position - start_position) } -#[test] -fn test_unsigned_leb128() { - let mut stream = Vec::with_capacity(10000); - - for x in 0..62 { - let pos = stream.len(); - let bytes_written = write_unsigned_leb128(&mut stream, pos, 3 << x); - assert_eq!(stream.len(), pos + bytes_written); - } - - let mut position = 0; - for x in 0..62 { - let expected = 3 << x; - let (actual, bytes_read) = read_unsigned_leb128(&stream, position); - assert_eq!(expected, actual); - position += bytes_read; - } - assert_eq!(stream.len(), position); +macro_rules! impl_test_unsigned_leb128 { + ($test_name:ident, $write_fn_name:ident, $read_fn_name:ident, $int_ty:ident) => ( + #[test] + fn $test_name() { + let mut stream = Vec::new(); + + for x in 0..62 { + let pos = stream.len(); + let bytes_written = $write_fn_name(&mut stream, pos, (3u64 << x) as $int_ty); + assert_eq!(stream.len(), pos + bytes_written); + } + + let mut position = 0; + for x in 0..62 { + let expected = (3u64 << x) as $int_ty; + let (actual, bytes_read) = $read_fn_name(&stream[position ..]); + assert_eq!(expected, actual); + position += bytes_read; + } + assert_eq!(stream.len(), position); + } + ) } +impl_test_unsigned_leb128!(test_u16_leb128, write_u16_leb128, read_u16_leb128, u16); +impl_test_unsigned_leb128!(test_u32_leb128, write_u32_leb128, read_u32_leb128, u32); +impl_test_unsigned_leb128!(test_u64_leb128, write_u64_leb128, read_u64_leb128, u64); +impl_test_unsigned_leb128!(test_u128_leb128, write_u128_leb128, read_u128_leb128, u128); +impl_test_unsigned_leb128!(test_usize_leb128, write_usize_leb128, read_usize_leb128, usize); + #[test] fn test_signed_leb128() { let values: Vec<_> = (-500..500).map(|i| i * 0x12345789ABCDEF).collect(); diff --git a/src/libserialize/opaque.rs b/src/libserialize/opaque.rs index 409366102ba..077efadd60a 100644 --- a/src/libserialize/opaque.rs +++ b/src/libserialize/opaque.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use leb128::{read_signed_leb128, read_unsigned_leb128, write_signed_leb128, write_unsigned_leb128}; +use leb128::{self, read_signed_leb128, write_signed_leb128}; use std::borrow::Cow; use std::io::{self, Write}; use serialize; @@ -35,9 +35,9 @@ impl<'a> Encoder<'a> { macro_rules! write_uleb128 { - ($enc:expr, $value:expr) => {{ + ($enc:expr, $value:expr, $fun:ident) => {{ let pos = $enc.cursor.position() as usize; - let bytes_written = write_unsigned_leb128($enc.cursor.get_mut(), pos, $value as u128); + let bytes_written = leb128::$fun($enc.cursor.get_mut(), pos, $value); $enc.cursor.set_position((pos + bytes_written) as u64); Ok(()) }} @@ -55,61 +55,76 @@ macro_rules! write_sleb128 { impl<'a> serialize::Encoder for Encoder<'a> { type Error = io::Error; + #[inline] fn emit_nil(&mut self) -> EncodeResult { Ok(()) } + #[inline] fn emit_usize(&mut self, v: usize) -> EncodeResult { - write_uleb128!(self, v) + write_uleb128!(self, v, write_usize_leb128) } + #[inline] fn emit_u128(&mut self, v: u128) -> EncodeResult { - write_uleb128!(self, v) + write_uleb128!(self, v, write_u128_leb128) } + #[inline] fn emit_u64(&mut self, v: u64) -> EncodeResult { - write_uleb128!(self, v) + write_uleb128!(self, v, write_u64_leb128) } + #[inline] fn emit_u32(&mut self, v: u32) -> EncodeResult { - write_uleb128!(self, v) + write_uleb128!(self, v, write_u32_leb128) } + #[inline] fn emit_u16(&mut self, v: u16) -> EncodeResult { - write_uleb128!(self, v) + write_uleb128!(self, v, write_u16_leb128) } + #[inline] fn emit_u8(&mut self, v: u8) -> EncodeResult { - let _ = self.cursor.write_all(&[v]); + let pos = self.cursor.position() as usize; + leb128::write_to_vec(self.cursor.get_mut(), pos, v); + self.cursor.set_position((pos + 1) as u64); Ok(()) } + #[inline] fn emit_isize(&mut self, v: isize) -> EncodeResult { write_sleb128!(self, v) } + #[inline] fn emit_i128(&mut self, v: i128) -> EncodeResult { write_sleb128!(self, v) } + #[inline] fn emit_i64(&mut self, v: i64) -> EncodeResult { write_sleb128!(self, v) } + #[inline] fn emit_i32(&mut self, v: i32) -> EncodeResult { write_sleb128!(self, v) } + #[inline] fn emit_i16(&mut self, v: i16) -> EncodeResult { write_sleb128!(self, v) } + #[inline] fn emit_i8(&mut self, v: i8) -> EncodeResult { let as_u8: u8 = unsafe { ::std::mem::transmute(v) }; - let _ = self.cursor.write_all(&[as_u8]); - Ok(()) + self.emit_u8(as_u8) } + #[inline] fn emit_bool(&mut self, v: bool) -> EncodeResult { self.emit_u8(if v { 1 @@ -118,20 +133,24 @@ impl<'a> serialize::Encoder for Encoder<'a> { }) } + #[inline] fn emit_f64(&mut self, v: f64) -> EncodeResult { let as_u64: u64 = unsafe { ::std::mem::transmute(v) }; self.emit_u64(as_u64) } + #[inline] fn emit_f32(&mut self, v: f32) -> EncodeResult { let as_u32: u32 = unsafe { ::std::mem::transmute(v) }; self.emit_u32(as_u32) } + #[inline] fn emit_char(&mut self, v: char) -> EncodeResult { self.emit_u32(v as u32) } + #[inline] fn emit_str(&mut self, v: &str) -> EncodeResult { self.emit_usize(v.len())?; let _ = self.cursor.write_all(v.as_bytes()); @@ -140,6 +159,7 @@ impl<'a> serialize::Encoder for Encoder<'a> { } impl<'a> Encoder<'a> { + #[inline] pub fn position(&self) -> usize { self.cursor.position() as usize } @@ -162,14 +182,17 @@ impl<'a> Decoder<'a> { } } + #[inline] pub fn position(&self) -> usize { self.position } + #[inline] pub fn set_position(&mut self, pos: usize) { self.position = pos } + #[inline] pub fn advance(&mut self, bytes: usize) { self.position += bytes; } @@ -187,10 +210,10 @@ impl<'a> Decoder<'a> { } macro_rules! read_uleb128 { - ($dec:expr, $t:ty) => ({ - let (value, bytes_read) = read_unsigned_leb128($dec.data, $dec.position); + ($dec:expr, $t:ty, $fun:ident) => ({ + let (value, bytes_read) = leb128::$fun(&$dec.data[$dec.position ..]); $dec.position += bytes_read; - Ok(value as $t) + Ok(value) }) } @@ -213,22 +236,22 @@ impl<'a> serialize::Decoder for Decoder<'a> { #[inline] fn read_u128(&mut self) -> Result<u128, Self::Error> { - read_uleb128!(self, u128) + read_uleb128!(self, u128, read_u128_leb128) } #[inline] fn read_u64(&mut self) -> Result<u64, Self::Error> { - read_uleb128!(self, u64) + read_uleb128!(self, u64, read_u64_leb128) } #[inline] fn read_u32(&mut self) -> Result<u32, Self::Error> { - read_uleb128!(self, u32) + read_uleb128!(self, u32, read_u32_leb128) } #[inline] fn read_u16(&mut self) -> Result<u16, Self::Error> { - read_uleb128!(self, u16) + read_uleb128!(self, u16, read_u16_leb128) } #[inline] @@ -240,7 +263,7 @@ impl<'a> serialize::Decoder for Decoder<'a> { #[inline] fn read_usize(&mut self) -> Result<usize, Self::Error> { - read_uleb128!(self, usize) + read_uleb128!(self, usize, read_usize_leb128) } #[inline] diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index 96f98efe4aa..73bd5747c10 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -16,7 +16,7 @@ use marker; use mem::{align_of, size_of, needs_drop}; use mem; use ops::{Deref, DerefMut}; -use ptr::{self, Unique, Shared}; +use ptr::{self, Unique, NonNull}; use self::BucketState::*; @@ -873,7 +873,7 @@ impl<K, V> RawTable<K, V> { elems_left, marker: marker::PhantomData, }, - table: Shared::from(self), + table: NonNull::from(self), marker: marker::PhantomData, } } @@ -1020,7 +1020,7 @@ impl<K, V> IntoIter<K, V> { /// Iterator over the entries in a table, clearing the table. pub struct Drain<'a, K: 'a, V: 'a> { - table: Shared<RawTable<K, V>>, + table: NonNull<RawTable<K, V>>, iter: RawBuckets<'static, K, V>, marker: marker::PhantomData<&'a RawTable<K, V>>, } diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs index b8a6a66eaa6..e9a150f34a5 100644 --- a/src/libstd/collections/mod.rs +++ b/src/libstd/collections/mod.rs @@ -64,11 +64,11 @@ //! * You want a map, with no extra functionality. //! //! ### Use a `BTreeMap` when: +//! * You want a map sorted by its keys. +//! * You want to be able to get a range of entries on-demand. //! * You're interested in what the smallest or largest key-value pair is. //! * You want to find the largest or smallest key that is smaller or larger //! than something. -//! * You want to be able to get all of the entries in order on-demand. -//! * You want a map sorted by its keys. //! //! ### Use the `Set` variant of any of these `Map`s when: //! * You just want to remember which keys you've seen. diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs index 6d76c7e722c..5e5695f15ac 100644 --- a/src/libstd/f32.rs +++ b/src/libstd/f32.rs @@ -472,20 +472,19 @@ impl f32 { /// Returns the logarithm of the number with respect to an arbitrary base. /// + /// The result may not be correctly rounded owing to implementation details; + /// `self.log2()` can produce more accurate results for base 2, and + /// `self.log10()` can produce more accurate results for base 10. + /// /// ``` /// use std::f32; /// - /// let ten = 10.0f32; - /// let two = 2.0f32; - /// - /// // log10(10) - 1 == 0 - /// let abs_difference_10 = (ten.log(10.0) - 1.0).abs(); + /// let five = 5.0f32; /// - /// // log2(2) - 1 == 0 - /// let abs_difference_2 = (two.log(2.0) - 1.0).abs(); + /// // log5(5) - 1 == 0 + /// let abs_difference = (five.log(5.0) - 1.0).abs(); /// - /// assert!(abs_difference_10 <= f32::EPSILON); - /// assert!(abs_difference_2 <= f32::EPSILON); + /// assert!(abs_difference <= f32::EPSILON); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs index dee9566f1fc..e4eea745bb7 100644 --- a/src/libstd/f64.rs +++ b/src/libstd/f64.rs @@ -432,18 +432,17 @@ impl f64 { /// Returns the logarithm of the number with respect to an arbitrary base. /// - /// ``` - /// let ten = 10.0_f64; - /// let two = 2.0_f64; + /// The result may not be correctly rounded owing to implementation details; + /// `self.log2()` can produce more accurate results for base 2, and + /// `self.log10()` can produce more accurate results for base 10. /// - /// // log10(10) - 1 == 0 - /// let abs_difference_10 = (ten.log(10.0) - 1.0).abs(); + /// ``` + /// let five = 5.0_f64; /// - /// // log2(2) - 1 == 0 - /// let abs_difference_2 = (two.log(2.0) - 1.0).abs(); + /// // log5(5) - 1 == 0 + /// let abs_difference = (five.log(5.0) - 1.0).abs(); /// - /// assert!(abs_difference_10 < 1e-10); - /// assert!(abs_difference_2 < 1e-10); + /// assert!(abs_difference < 1e-10); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 4e0ff450cab..d1f3ccbd2c6 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -211,12 +211,12 @@ pub struct DirBuilder { recursive: bool, } -/// How large a buffer to pre-allocate before reading the entire file at `path`. -fn initial_buffer_size<P: AsRef<Path>>(path: P) -> usize { +/// How large a buffer to pre-allocate before reading the entire file. +fn initial_buffer_size(file: &File) -> usize { // Allocate one extra byte so the buffer doesn't need to grow before the // final `read` call at the end of the file. Don't worry about `usize` // overflow because reading will fail regardless in that case. - metadata(path).map(|m| m.len() as usize + 1).unwrap_or(0) + file.metadata().map(|m| m.len() as usize + 1).unwrap_or(0) } /// Read the entire contents of a file into a bytes vector. @@ -254,8 +254,9 @@ fn initial_buffer_size<P: AsRef<Path>>(path: P) -> usize { /// ``` #[unstable(feature = "fs_read_write", issue = "46588")] pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> { - let mut bytes = Vec::with_capacity(initial_buffer_size(&path)); - File::open(path)?.read_to_end(&mut bytes)?; + let mut file = File::open(path)?; + let mut bytes = Vec::with_capacity(initial_buffer_size(&file)); + file.read_to_end(&mut bytes)?; Ok(bytes) } @@ -295,8 +296,9 @@ pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> { /// ``` #[unstable(feature = "fs_read_write", issue = "46588")] pub fn read_string<P: AsRef<Path>>(path: P) -> io::Result<String> { - let mut string = String::with_capacity(initial_buffer_size(&path)); - File::open(path)?.read_to_string(&mut string)?; + let mut file = File::open(path)?; + let mut string = String::with_capacity(initial_buffer_size(&file)); + file.read_to_string(&mut string)?; Ok(string) } diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index 16fbf0c6ba6..4e7db5f0826 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -345,8 +345,8 @@ impl<R: Seek> Seek for BufReader<R> { /// /// let mut stream = TcpStream::connect("127.0.0.1:34254").unwrap(); /// -/// for i in 1..10 { -/// stream.write(&[i]).unwrap(); +/// for i in 0..10 { +/// stream.write(&[i+1]).unwrap(); /// } /// ``` /// @@ -361,8 +361,8 @@ impl<R: Seek> Seek for BufReader<R> { /// /// let mut stream = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap()); /// -/// for i in 1..10 { -/// stream.write(&[i]).unwrap(); +/// for i in 0..10 { +/// stream.write(&[i+1]).unwrap(); /// } /// ``` /// diff --git a/src/libstd/io/error.rs b/src/libstd/io/error.rs index bb9383d3d6e..f0b41f30251 100644 --- a/src/libstd/io/error.rs +++ b/src/libstd/io/error.rs @@ -62,12 +62,18 @@ pub type Result<T> = result::Result<T, Error>; /// [`Write`]: ../io/trait.Write.html /// [`Seek`]: ../io/trait.Seek.html /// [`ErrorKind`]: enum.ErrorKind.html -#[derive(Debug)] #[stable(feature = "rust1", since = "1.0.0")] pub struct Error { repr: Repr, } +#[stable(feature = "rust1", since = "1.0.0")] +impl fmt::Debug for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(&self.repr, f) + } +} + enum Repr { Os(i32), Simple(ErrorKind), @@ -511,10 +517,12 @@ impl Error { impl fmt::Debug for Repr { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { match *self { - Repr::Os(ref code) => - fmt.debug_struct("Os").field("code", code) - .field("message", &sys::os::error_string(*code)).finish(), - Repr::Custom(ref c) => fmt.debug_tuple("Custom").field(c).finish(), + Repr::Os(code) => + fmt.debug_struct("Os") + .field("code", &code) + .field("kind", &sys::decode_error_kind(code)) + .field("message", &sys::os::error_string(code)).finish(), + Repr::Custom(ref c) => fmt::Debug::fmt(&c, fmt), Repr::Simple(kind) => fmt.debug_tuple("Kind").field(&kind).finish(), } } @@ -559,17 +567,36 @@ fn _assert_error_is_sync_send() { #[cfg(test)] mod test { - use super::{Error, ErrorKind}; + use super::{Error, ErrorKind, Repr, Custom}; use error; use fmt; use sys::os::error_string; + use sys::decode_error_kind; #[test] fn test_debug_error() { let code = 6; let msg = error_string(code); - let err = Error { repr: super::Repr::Os(code) }; - let expected = format!("Error {{ repr: Os {{ code: {:?}, message: {:?} }} }}", code, msg); + let kind = decode_error_kind(code); + let err = Error { + repr: Repr::Custom(box Custom { + kind: ErrorKind::InvalidInput, + error: box Error { + repr: super::Repr::Os(code) + }, + }) + }; + let expected = format!( + "Custom {{ \ + kind: InvalidInput, \ + error: Os {{ \ + code: {:?}, \ + kind: {:?}, \ + message: {:?} \ + }} \ + }}", + code, kind, msg + ); assert_eq!(format!("{:?}", err), expected); } diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 28040bc20e2..91cc6d25cce 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -293,11 +293,11 @@ #![feature(placement_in_syntax)] #![feature(placement_new_protocol)] #![feature(prelude_import)] +#![feature(ptr_internals)] #![feature(rand)] #![feature(raw)] #![feature(repr_align)] #![feature(rustc_attrs)] -#![feature(shared)] #![feature(sip_hash_13)] #![feature(slice_bytes)] #![feature(slice_concat_ext)] @@ -315,7 +315,6 @@ #![feature(try_from)] #![feature(unboxed_closures)] #![feature(unicode)] -#![feature(unique)] #![feature(untagged_unions)] #![feature(unwind_attributes)] #![feature(vec_push_all)] @@ -351,9 +350,9 @@ use prelude::v1::*; #[cfg(test)] extern crate test; #[cfg(test)] extern crate rand; -// We want to reexport a few macros from core but libcore has already been +// We want to re-export a few macros from core but libcore has already been // imported by the compiler (via our #[no_std] attribute) In this case we just -// add a new crate name so we can attach the reexports to it. +// add a new crate name so we can attach the re-exports to it. #[macro_reexport(assert, assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_ne, unreachable, unimplemented, write, writeln, try)] extern crate core as __core; @@ -390,7 +389,7 @@ mod macros; // The Rust prelude pub mod prelude; -// Public module declarations and reexports +// Public module declarations and re-exports #[stable(feature = "rust1", since = "1.0.0")] pub use core::any; #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index 1ca7e66ed9c..fa430939f05 100644 --- a/src/libstd/net/addr.rs +++ b/src/libstd/net/addr.rs @@ -12,7 +12,9 @@ use fmt; use hash; use io; use mem; -use net::{lookup_host, ntoh, hton, IpAddr, Ipv4Addr, Ipv6Addr}; +use net::{ntoh, hton, IpAddr, Ipv4Addr, Ipv6Addr}; +#[allow(deprecated)] +use net::lookup_host; use option; use sys::net::netc as c; use sys_common::{FromInner, AsInner, IntoInner}; @@ -845,6 +847,7 @@ impl ToSocketAddrs for (Ipv6Addr, u16) { } } +#[allow(deprecated)] fn resolve_socket_addr(s: &str, p: u16) -> io::Result<vec::IntoIter<SocketAddr>> { let ips = lookup_host(s)?; let v: Vec<_> = ips.map(|mut a| { a.set_port(p); a }).collect(); diff --git a/src/libstd/net/mod.rs b/src/libstd/net/mod.rs index 9fcb93e2032..eb0e2e13b4c 100644 --- a/src/libstd/net/mod.rs +++ b/src/libstd/net/mod.rs @@ -134,12 +134,15 @@ fn each_addr<A: ToSocketAddrs, F, T>(addr: A, mut f: F) -> io::Result<T> iterator and returning socket \ addresses", issue = "27705")] +#[rustc_deprecated(since = "1.25", reason = "Use the ToSocketAddrs trait instead")] pub struct LookupHost(net_imp::LookupHost); #[unstable(feature = "lookup_host", reason = "unsure about the returned \ iterator and returning socket \ addresses", issue = "27705")] +#[rustc_deprecated(since = "1.25", reason = "Use the ToSocketAddrs trait instead")] +#[allow(deprecated)] impl Iterator for LookupHost { type Item = SocketAddr; fn next(&mut self) -> Option<SocketAddr> { self.0.next() } @@ -149,6 +152,8 @@ impl Iterator for LookupHost { iterator and returning socket \ addresses", issue = "27705")] +#[rustc_deprecated(since = "1.25", reason = "Use the ToSocketAddrs trait instead")] +#[allow(deprecated)] impl fmt::Debug for LookupHost { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.pad("LookupHost { .. }") @@ -181,6 +186,8 @@ impl fmt::Debug for LookupHost { iterator and returning socket \ addresses", issue = "27705")] +#[rustc_deprecated(since = "1.25", reason = "Use the ToSocketAddrs trait instead")] +#[allow(deprecated)] pub fn lookup_host(host: &str) -> io::Result<LookupHost> { net_imp::lookup_host(host).map(LookupHost) } diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs index 53c2211745c..560876006d3 100644 --- a/src/libstd/panic.rs +++ b/src/libstd/panic.rs @@ -17,7 +17,7 @@ use cell::UnsafeCell; use fmt; use ops::{Deref, DerefMut}; use panicking; -use ptr::{Unique, Shared}; +use ptr::{Unique, NonNull}; use rc::Rc; use sync::{Arc, Mutex, RwLock, atomic}; use thread::Result; @@ -196,10 +196,10 @@ impl<'a, T: RefUnwindSafe + ?Sized> UnwindSafe for &'a T {} impl<T: RefUnwindSafe + ?Sized> UnwindSafe for *const T {} #[stable(feature = "catch_unwind", since = "1.9.0")] impl<T: RefUnwindSafe + ?Sized> UnwindSafe for *mut T {} -#[unstable(feature = "unique", issue = "27730")] +#[unstable(feature = "ptr_internals", issue = "0")] impl<T: UnwindSafe + ?Sized> UnwindSafe for Unique<T> {} -#[unstable(feature = "shared", issue = "27730")] -impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Shared<T> {} +#[stable(feature = "nonnull", since = "1.24.0")] +impl<T: RefUnwindSafe + ?Sized> UnwindSafe for NonNull<T> {} #[stable(feature = "catch_unwind", since = "1.9.0")] impl<T: ?Sized> UnwindSafe for Mutex<T> {} #[stable(feature = "catch_unwind", since = "1.9.0")] diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 7631a9a44bb..ed102c2949e 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -1869,7 +1869,11 @@ impl Path { /// /// let path = Path::new("/test/haha/foo.txt"); /// + /// assert_eq!(path.strip_prefix("/"), Ok(Path::new("test/haha/foo.txt"))); /// assert_eq!(path.strip_prefix("/test"), Ok(Path::new("haha/foo.txt"))); + /// assert_eq!(path.strip_prefix("/test/"), Ok(Path::new("haha/foo.txt"))); + /// assert_eq!(path.strip_prefix("/test/haha/foo.txt"), Ok(Path::new(""))); + /// assert_eq!(path.strip_prefix("/test/haha/foo.txt/"), Ok(Path::new(""))); /// assert_eq!(path.strip_prefix("test").is_ok(), false); /// assert_eq!(path.strip_prefix("/haha").is_ok(), false); /// ``` @@ -1900,6 +1904,9 @@ impl Path { /// let path = Path::new("/etc/passwd"); /// /// assert!(path.starts_with("/etc")); + /// assert!(path.starts_with("/etc/")); + /// assert!(path.starts_with("/etc/passwd")); + /// assert!(path.starts_with("/etc/passwd/")); /// /// assert!(!path.starts_with("/e")); /// ``` diff --git a/src/libstd/prelude/mod.rs b/src/libstd/prelude/mod.rs index 538753d8692..919e033f2b4 100644 --- a/src/libstd/prelude/mod.rs +++ b/src/libstd/prelude/mod.rs @@ -52,7 +52,7 @@ //! # Prelude contents //! //! The current version of the prelude (version 1) lives in -//! [`std::prelude::v1`], and reexports the following. +//! [`std::prelude::v1`], and re-exports the following. //! //! * [`std::marker`]::{[`Copy`], [`Send`], [`Sized`], [`Sync`]}. The marker //! traits indicate fundamental properties of types. diff --git a/src/libstd/prelude/v1.rs b/src/libstd/prelude/v1.rs index 9ca5b445c86..feedd4e1abe 100644 --- a/src/libstd/prelude/v1.rs +++ b/src/libstd/prelude/v1.rs @@ -14,17 +14,17 @@ #![stable(feature = "rust1", since = "1.0.0")] -// Reexported core operators +// Re-exported core operators #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] pub use marker::{Copy, Send, Sized, Sync}; #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] pub use ops::{Drop, Fn, FnMut, FnOnce}; -// Reexported functions +// Re-exported functions #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] pub use mem::drop; -// Reexported types and traits +// Re-exported types and traits #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] pub use boxed::Box; #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libstd/rand/reader.rs b/src/libstd/rand/reader.rs deleted file mode 100644 index 08bc809ed4d..00000000000 --- a/src/libstd/rand/reader.rs +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! A wrapper around any Read to treat it as an RNG. - -#![allow(dead_code)] - -use io::prelude::*; -use rand::Rng; - -/// An RNG that reads random bytes straight from a `Read`. This will -/// work best with an infinite reader, but this is not required. -/// -/// # Panics -/// -/// It will panic if it there is insufficient data to fulfill a request. -pub struct ReaderRng<R> { - reader: R -} - -impl<R: Read> ReaderRng<R> { - /// Create a new `ReaderRng` from a `Read`. - pub fn new(r: R) -> ReaderRng<R> { - ReaderRng { - reader: r - } - } -} - -impl<R: Read> Rng for ReaderRng<R> { - fn next_u32(&mut self) -> u32 { - // This is designed for speed: reading a LE integer on a LE - // platform just involves blitting the bytes into the memory - // of the u32, similarly for BE on BE; avoiding byteswapping. - let mut bytes = [0; 4]; - self.fill_bytes(&mut bytes); - unsafe { *(bytes.as_ptr() as *const u32) } - } - fn next_u64(&mut self) -> u64 { - // see above for explanation. - let mut bytes = [0; 8]; - self.fill_bytes(&mut bytes); - unsafe { *(bytes.as_ptr() as *const u64) } - } - fn fill_bytes(&mut self, mut v: &mut [u8]) { - while !v.is_empty() { - let t = v; - match self.reader.read(t) { - Ok(0) => panic!("ReaderRng.fill_bytes: EOF reached"), - Ok(n) => v = t.split_at_mut(n).1, - Err(e) => panic!("ReaderRng.fill_bytes: {}", e), - } - } - } -} - -#[cfg(test)] -mod tests { - use super::ReaderRng; - use rand::Rng; - - #[test] - fn test_reader_rng_u64() { - // transmute from the target to avoid endianness concerns. - let v = &[0, 0, 0, 0, 0, 0, 0, 1, - 0, 0, 0, 0, 0, 0, 0, 2, - 0, 0, 0, 0, 0, 0, 0, 3][..]; - let mut rng = ReaderRng::new(v); - - assert_eq!(rng.next_u64(), 1u64.to_be()); - assert_eq!(rng.next_u64(), 2u64.to_be()); - assert_eq!(rng.next_u64(), 3u64.to_be()); - } - #[test] - fn test_reader_rng_u32() { - let v = &[0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3][..]; - let mut rng = ReaderRng::new(v); - - assert_eq!(rng.next_u32(), 1u32.to_be()); - assert_eq!(rng.next_u32(), 2u32.to_be()); - assert_eq!(rng.next_u32(), 3u32.to_be()); - } - #[test] - fn test_reader_rng_fill_bytes() { - let v = [1, 2, 3, 4, 5, 6, 7, 8]; - let mut w = [0; 8]; - - let mut rng = ReaderRng::new(&v[..]); - rng.fill_bytes(&mut w); - - assert!(v == w); - } - - #[test] - #[should_panic] - fn test_reader_rng_insufficient_bytes() { - let mut rng = ReaderRng::new(&[][..]); - let mut v = [0; 3]; - rng.fill_bytes(&mut v); - } -} diff --git a/src/libstd/rt.rs b/src/libstd/rt.rs index af414d25b5f..9dbaf784f89 100644 --- a/src/libstd/rt.rs +++ b/src/libstd/rt.rs @@ -23,7 +23,7 @@ #![doc(hidden)] -// Reexport some of our utilities which are expected by other crates. +// Re-export some of our utilities which are expected by other crates. pub use panicking::{begin_panic, begin_panic_fmt, update_panic_count}; // To reduce the generated code of the new `lang_start`, this function is doing diff --git a/src/libstd/sys/unix/l4re.rs b/src/libstd/sys/unix/l4re.rs index c3e8d0b7d95..21218489679 100644 --- a/src/libstd/sys/unix/l4re.rs +++ b/src/libstd/sys/unix/l4re.rs @@ -437,9 +437,5 @@ pub mod net { pub fn lookup_host(_: &str) -> io::Result<LookupHost> { unimpl!(); } - - pub fn res_init_if_glibc_before_2_26() -> io::Result<()> { - unimpl!(); - } } diff --git a/src/libstd/sys/unix/net.rs b/src/libstd/sys/unix/net.rs index e775f857f2b..3f65975e608 100644 --- a/src/libstd/sys/unix/net.rs +++ b/src/libstd/sys/unix/net.rs @@ -51,6 +51,10 @@ pub fn cvt_gai(err: c_int) -> io::Result<()> { if err == 0 { return Ok(()) } + + // We may need to trigger a glibc workaround. See on_resolver_failure() for details. + on_resolver_failure(); + if err == EAI_SYSTEM { return Err(io::Error::last_os_error()) } @@ -377,21 +381,22 @@ impl IntoInner<c_int> for Socket { // res_init unconditionally, we call it only when we detect we're linking // against glibc version < 2.26. (That is, when we both know its needed and // believe it's thread-safe). -pub fn res_init_if_glibc_before_2_26() -> io::Result<()> { +#[cfg(target_env = "gnu")] +fn on_resolver_failure() { // If the version fails to parse, we treat it the same as "not glibc". if let Some(Ok(version_str)) = glibc_version_cstr().map(CStr::to_str) { if let Some(version) = parse_glibc_version(version_str) { if version < (2, 26) { - let ret = unsafe { libc::res_init() }; - if ret != 0 { - return Err(io::Error::last_os_error()); - } + unsafe { libc::res_init() }; } } } - Ok(()) } +#[cfg(not(target_env = "gnu"))] +fn on_resolver_failure() {} + +#[cfg(target_env = "gnu")] fn glibc_version_cstr() -> Option<&'static CStr> { weak! { fn gnu_get_libc_version() -> *const libc::c_char @@ -405,6 +410,7 @@ fn glibc_version_cstr() -> Option<&'static CStr> { // Returns Some((major, minor)) if the string is a valid "x.y" version, // ignoring any extra dot-separated parts. Otherwise return None. +#[cfg(target_env = "gnu")] fn parse_glibc_version(version: &str) -> Option<(usize, usize)> { let mut parsed_ints = version.split(".").map(str::parse::<usize>).fuse(); match (parsed_ints.next(), parsed_ints.next()) { @@ -413,7 +419,7 @@ fn parse_glibc_version(version: &str) -> Option<(usize, usize)> { } } -#[cfg(test)] +#[cfg(all(test, taget_env = "gnu"))] mod test { use super::*; diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index cb249af4254..525882c1e1e 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -311,8 +311,8 @@ pub mod guard { #[cfg(target_os = "macos")] pub unsafe fn current() -> Option<usize> { - Some((libc::pthread_get_stackaddr_np(libc::pthread_self()) as usize - - libc::pthread_get_stacksize_np(libc::pthread_self()))) + Some(libc::pthread_get_stackaddr_np(libc::pthread_self()) as usize - + libc::pthread_get_stacksize_np(libc::pthread_self())) } #[cfg(any(target_os = "openbsd", target_os = "bitrig"))] diff --git a/src/libstd/sys_common/net.rs b/src/libstd/sys_common/net.rs index c70b39995eb..b841afe1a51 100644 --- a/src/libstd/sys_common/net.rs +++ b/src/libstd/sys_common/net.rs @@ -166,27 +166,9 @@ pub fn lookup_host(host: &str) -> io::Result<LookupHost> { hints.ai_socktype = c::SOCK_STREAM; let mut res = ptr::null_mut(); unsafe { - match cvt_gai(c::getaddrinfo(c_host.as_ptr(), ptr::null(), &hints, &mut res)) { - Ok(_) => { - Ok(LookupHost { original: res, cur: res }) - }, - #[cfg(unix)] - Err(e) => { - // If we're running glibc prior to version 2.26, the lookup - // failure could be caused by caching a stale /etc/resolv.conf. - // We need to call libc::res_init() to clear the cache. But we - // shouldn't call it in on any other platform, because other - // res_init implementations aren't thread-safe. See - // https://github.com/rust-lang/rust/issues/41570 and - // https://github.com/rust-lang/rust/issues/43592. - use sys::net::res_init_if_glibc_before_2_26; - let _ = res_init_if_glibc_before_2_26(); - Err(e) - }, - // the cfg is needed here to avoid an "unreachable pattern" warning - #[cfg(not(unix))] - Err(e) => Err(e), - } + cvt_gai(c::getaddrinfo(c_host.as_ptr(), ptr::null(), &hints, &mut res)).map(|_| { + LookupHost { original: res, cur: res } + }) } } diff --git a/src/libstd_unicode/char.rs b/src/libstd_unicode/char.rs index c1daf643986..b4be4a96911 100644 --- a/src/libstd_unicode/char.rs +++ b/src/libstd_unicode/char.rs @@ -33,7 +33,7 @@ use core::iter::FusedIterator; use core::fmt::{self, Write}; use tables::{conversions, derived_property, general_category, property}; -// stable reexports +// stable re-exports #[stable(feature = "rust1", since = "1.0.0")] pub use core::char::{MAX, from_digit, from_u32, from_u32_unchecked}; #[stable(feature = "rust1", since = "1.0.0")] @@ -41,7 +41,7 @@ pub use core::char::{EscapeDebug, EscapeDefault, EscapeUnicode}; #[stable(feature = "char_from_str", since = "1.20.0")] pub use core::char::ParseCharError; -// unstable reexports +// unstable re-exports #[unstable(feature = "try_from", issue = "33417")] pub use core::char::CharTryFromError; #[unstable(feature = "decode_utf8", issue = "33906")] diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 9c0622e7bef..a64f1e9e400 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -15,6 +15,7 @@ pub use self::UnsafeSource::*; pub use self::PathParameters::*; pub use symbol::{Ident, Symbol as Name}; pub use util::ThinVec; +pub use util::parser::ExprPrecedence; use syntax_pos::{Span, DUMMY_SP}; use codemap::{respan, Spanned}; @@ -730,6 +731,7 @@ impl BinOpKind { _ => false } } + pub fn is_comparison(&self) -> bool { use self::BinOpKind::*; match *self { @@ -740,6 +742,7 @@ impl BinOpKind { false, } } + /// Returns `true` if the binary operator takes its arguments by value pub fn is_by_value(&self) -> bool { !self.is_comparison() @@ -966,6 +969,49 @@ impl Expr { Some(P(Ty { node, id: self.id, span: self.span })) } + + pub fn precedence(&self) -> ExprPrecedence { + match self.node { + ExprKind::Box(_) => ExprPrecedence::Box, + ExprKind::InPlace(..) => ExprPrecedence::InPlace, + ExprKind::Array(_) => ExprPrecedence::Array, + ExprKind::Call(..) => ExprPrecedence::Call, + ExprKind::MethodCall(..) => ExprPrecedence::MethodCall, + ExprKind::Tup(_) => ExprPrecedence::Tup, + ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node), + ExprKind::Unary(..) => ExprPrecedence::Unary, + ExprKind::Lit(_) => ExprPrecedence::Lit, + ExprKind::Type(..) | ExprKind::Cast(..) => ExprPrecedence::Cast, + ExprKind::If(..) => ExprPrecedence::If, + ExprKind::IfLet(..) => ExprPrecedence::IfLet, + ExprKind::While(..) => ExprPrecedence::While, + ExprKind::WhileLet(..) => ExprPrecedence::WhileLet, + ExprKind::ForLoop(..) => ExprPrecedence::ForLoop, + ExprKind::Loop(..) => ExprPrecedence::Loop, + ExprKind::Match(..) => ExprPrecedence::Match, + ExprKind::Closure(..) => ExprPrecedence::Closure, + ExprKind::Block(..) => ExprPrecedence::Block, + ExprKind::Catch(..) => ExprPrecedence::Catch, + ExprKind::Assign(..) => ExprPrecedence::Assign, + ExprKind::AssignOp(..) => ExprPrecedence::AssignOp, + ExprKind::Field(..) => ExprPrecedence::Field, + ExprKind::TupField(..) => ExprPrecedence::TupField, + ExprKind::Index(..) => ExprPrecedence::Index, + ExprKind::Range(..) => ExprPrecedence::Range, + ExprKind::Path(..) => ExprPrecedence::Path, + ExprKind::AddrOf(..) => ExprPrecedence::AddrOf, + ExprKind::Break(..) => ExprPrecedence::Break, + ExprKind::Continue(..) => ExprPrecedence::Continue, + ExprKind::Ret(..) => ExprPrecedence::Ret, + ExprKind::InlineAsm(..) => ExprPrecedence::InlineAsm, + ExprKind::Mac(..) => ExprPrecedence::Mac, + ExprKind::Struct(..) => ExprPrecedence::Struct, + ExprKind::Repeat(..) => ExprPrecedence::Repeat, + ExprKind::Paren(..) => ExprPrecedence::Paren, + ExprKind::Try(..) => ExprPrecedence::Try, + ExprKind::Yield(..) => ExprPrecedence::Yield, + } + } } impl fmt::Debug for Expr { diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 4291f811f3f..d18d6f5e6bd 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -992,7 +992,8 @@ pub fn find_deprecation(diagnostic: &Handler, attrs: &[Attribute], /// Valid repr contents: any of the primitive integral type names (see /// `int_type_of_word`, below) to specify enum discriminant type; `C`, to use /// the same discriminant size that the corresponding C enum would or C -/// structure layout, and `packed` to remove padding. +/// structure layout, `packed` to remove padding, and `transparent` to elegate representation +/// concerns to the only non-ZST field. pub fn find_repr_attrs(diagnostic: &Handler, attr: &Attribute) -> Vec<ReprAttr> { let mut acc = Vec::new(); if attr.path == "repr" { @@ -1011,6 +1012,7 @@ pub fn find_repr_attrs(diagnostic: &Handler, attr: &Attribute) -> Vec<ReprAttr> "C" => Some(ReprC), "packed" => Some(ReprPacked), "simd" => Some(ReprSimd), + "transparent" => Some(ReprTransparent), _ => match int_type_of_word(word) { Some(ity) => Some(ReprInt(ity)), None => { @@ -1082,6 +1084,7 @@ pub enum ReprAttr { ReprC, ReprPacked, ReprSimd, + ReprTransparent, ReprAlign(u32), } diff --git a/src/libsyntax/diagnostic_list.rs b/src/libsyntax/diagnostic_list.rs index c3cf4747835..d841281e485 100644 --- a/src/libsyntax/diagnostic_list.rs +++ b/src/libsyntax/diagnostic_list.rs @@ -317,6 +317,31 @@ fn main() { ``` "##, +E0658: r##" +An unstable feature was used. + +Erroneous code example: + +```compile_fail,E658 +let x = ::std::u128::MAX; // error: use of unstable library feature 'i128' +``` + +If you're using a stable or a beta version of rustc, you won't be able to use +any unstable features. In order to do so, please switch to a nightly version of +rustc (by using rustup). + +If you're using a nightly version of rustc, just add the corresponding feature +to be able to use it: + +``` +#![feature(i128)] + +fn main() { + let x = ::std::u128::MAX; // ok! +} +``` +"##, + } register_diagnostics! { diff --git a/src/libsyntax/diagnostics/macros.rs b/src/libsyntax/diagnostics/macros.rs index c01836b6194..61f3e7046f1 100644 --- a/src/libsyntax/diagnostics/macros.rs +++ b/src/libsyntax/diagnostics/macros.rs @@ -106,6 +106,14 @@ macro_rules! struct_span_err { } #[macro_export] +macro_rules! stringify_error_code { + ($code:ident) => ({ + __diagnostic_used!($code); + $crate::errors::DiagnosticId::Error(stringify!($code).to_owned()) + }) +} + +#[macro_export] macro_rules! type_error_struct { ($session:expr, $span:expr, $typ:expr, $code:ident, $($message:tt)*) => ({ if $typ.references_error() { diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 0d3be28ffef..612d8501fb2 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -13,7 +13,7 @@ pub use self::SyntaxExtension::*; use ast::{self, Attribute, Name, PatKind, MetaItem}; use attr::HasAttrs; use codemap::{self, CodeMap, Spanned, respan}; -use syntax_pos::{Span, DUMMY_SP}; +use syntax_pos::{Span, MultiSpan, DUMMY_SP}; use errors::DiagnosticBuilder; use ext::expand::{self, Expansion, Invocation}; use ext::hygiene::{Mark, SyntaxContext}; @@ -754,22 +754,22 @@ impl<'a> ExtCtxt<'a> { last_macro } - pub fn struct_span_warn(&self, - sp: Span, - msg: &str) - -> DiagnosticBuilder<'a> { + pub fn struct_span_warn<S: Into<MultiSpan>>(&self, + sp: S, + msg: &str) + -> DiagnosticBuilder<'a> { self.parse_sess.span_diagnostic.struct_span_warn(sp, msg) } - pub fn struct_span_err(&self, - sp: Span, - msg: &str) - -> DiagnosticBuilder<'a> { + pub fn struct_span_err<S: Into<MultiSpan>>(&self, + sp: S, + msg: &str) + -> DiagnosticBuilder<'a> { self.parse_sess.span_diagnostic.struct_span_err(sp, msg) } - pub fn struct_span_fatal(&self, - sp: Span, - msg: &str) - -> DiagnosticBuilder<'a> { + pub fn struct_span_fatal<S: Into<MultiSpan>>(&self, + sp: S, + msg: &str) + -> DiagnosticBuilder<'a> { self.parse_sess.span_diagnostic.struct_span_fatal(sp, msg) } @@ -785,7 +785,7 @@ impl<'a> ExtCtxt<'a> { /// in most cases one can construct a dummy expression/item to /// substitute; we never hit resolve/type-checking so the dummy /// value doesn't have to match anything) - pub fn span_fatal(&self, sp: Span, msg: &str) -> ! { + pub fn span_fatal<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> ! { panic!(self.parse_sess.span_diagnostic.span_fatal(sp, msg)); } @@ -794,20 +794,20 @@ impl<'a> ExtCtxt<'a> { /// /// Compilation will be stopped in the near future (at the end of /// the macro expansion phase). - pub fn span_err(&self, sp: Span, msg: &str) { + pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, msg: &str) { self.parse_sess.span_diagnostic.span_err(sp, msg); } - pub fn mut_span_err(&self, sp: Span, msg: &str) + pub fn mut_span_err<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> DiagnosticBuilder<'a> { self.parse_sess.span_diagnostic.mut_span_err(sp, msg) } - pub fn span_warn(&self, sp: Span, msg: &str) { + pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: &str) { self.parse_sess.span_diagnostic.span_warn(sp, msg); } - pub fn span_unimpl(&self, sp: Span, msg: &str) -> ! { + pub fn span_unimpl<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> ! { self.parse_sess.span_diagnostic.span_unimpl(sp, msg); } - pub fn span_bug(&self, sp: Span, msg: &str) -> ! { + pub fn span_bug<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> ! { self.parse_sess.span_diagnostic.span_bug(sp, msg); } pub fn trace_macros_diag(&mut self) { diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index be0bfd6677b..7f7ff56fd7f 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -17,7 +17,7 @@ use ext::base::ExtCtxt; use ptr::P; use symbol::{Symbol, keywords}; -// Transitional reexports so qquote can find the paths it is looking for +// Transitional re-exports so qquote can find the paths it is looking for mod syntax { pub use ext; pub use parse; diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index c3bf5dbff5c..ac5a10ec703 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -155,7 +155,7 @@ declare_features! ( // OIBIT specific features (active, optin_builtin_traits, "1.0.0", Some(13231)), - // macro reexport needs more discussion and stabilization + // macro re-export needs more discussion and stabilization (active, macro_reexport, "1.0.0", Some(29638)), // Allows use of #[staged_api] @@ -452,6 +452,9 @@ declare_features! ( // `extern` in paths (active, extern_in_paths, "1.23.0", Some(44660)), + + // Allows `#[repr(transparent)]` attribute on newtype structs + (active, repr_transparent, "1.25.0", Some(43036)), ); declare_features! ( @@ -1179,7 +1182,9 @@ fn leveled_feature_err<'a>(sess: &'a ParseSess, feature: &str, span: Span, issue }; let mut err = match level { - GateStrength::Hard => diag.struct_span_err(span, &explanation), + GateStrength::Hard => { + diag.struct_span_err_with_code(span, &explanation, stringify_error_code!(E0658)) + } GateStrength::Soft => diag.struct_span_warn(span, &explanation), }; @@ -1477,7 +1482,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { ast::ItemKind::ExternCrate(_) => { if let Some(attr) = attr::find_by_name(&i.attrs[..], "macro_reexport") { gate_feature_post!(&self, macro_reexport, attr.span, - "macros reexports are experimental \ + "macros re-exports are experimental \ and possibly buggy"); } } @@ -1522,6 +1527,11 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { "the struct `#[repr(align(u16))]` attribute \ is experimental"); } + if item.check_name("transparent") { + gate_feature_post!(&self, repr_transparent, attr.span, + "the `#[repr(transparent)]` attribute \ + is experimental"); + } } } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index ad9c802ac85..3d58104260f 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -42,7 +42,7 @@ use ast::{BinOpKind, UnOp}; use ast::{RangeEnd, RangeSyntax}; use {ast, attr}; use codemap::{self, CodeMap, Spanned, respan}; -use syntax_pos::{self, Span, BytePos, FileName, DUMMY_SP}; +use syntax_pos::{self, Span, MultiSpan, BytePos, FileName, DUMMY_SP}; use errors::{self, DiagnosticBuilder}; use parse::{self, classify, token}; use parse::common::SeqSep; @@ -71,7 +71,7 @@ bitflags! { } } -type ItemInfo = (Ident, ItemKind, Option<Vec<Attribute> >); +type ItemInfo = (Ident, ItemKind, Option<Vec<Attribute>>); /// How to parse a path. #[derive(Copy, Clone, PartialEq)] @@ -151,10 +151,9 @@ macro_rules! maybe_whole { }; } -fn maybe_append(mut lhs: Vec<Attribute>, rhs: Option<Vec<Attribute>>) - -> Vec<Attribute> { - if let Some(ref attrs) = rhs { - lhs.extend(attrs.iter().cloned()) +fn maybe_append(mut lhs: Vec<Attribute>, mut rhs: Option<Vec<Attribute>>) -> Vec<Attribute> { + if let Some(ref mut rhs) = rhs { + lhs.append(rhs); } lhs } @@ -448,7 +447,9 @@ pub enum Error { } impl Error { - pub fn span_err(self, sp: Span, handler: &errors::Handler) -> DiagnosticBuilder { + pub fn span_err<S: Into<MultiSpan>>(self, + sp: S, + handler: &errors::Handler) -> DiagnosticBuilder { match self { Error::FileNotFoundForModule { ref mod_name, ref default_path, @@ -1267,13 +1268,16 @@ impl<'a> Parser<'a> { pub fn fatal(&self, m: &str) -> DiagnosticBuilder<'a> { self.sess.span_diagnostic.struct_span_fatal(self.span, m) } - pub fn span_fatal(&self, sp: Span, m: &str) -> DiagnosticBuilder<'a> { + pub fn span_fatal<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> DiagnosticBuilder<'a> { self.sess.span_diagnostic.struct_span_fatal(sp, m) } - pub fn span_fatal_err(&self, sp: Span, err: Error) -> DiagnosticBuilder<'a> { + pub fn span_fatal_err<S: Into<MultiSpan>>(&self, sp: S, err: Error) -> DiagnosticBuilder<'a> { err.span_err(sp, self.diagnostic()) } - pub fn span_fatal_help(&self, sp: Span, m: &str, help: &str) -> DiagnosticBuilder<'a> { + pub fn span_fatal_help<S: Into<MultiSpan>>(&self, + sp: S, + m: &str, + help: &str) -> DiagnosticBuilder<'a> { let mut err = self.sess.span_diagnostic.struct_span_fatal(sp, m); err.help(help); err @@ -1284,21 +1288,21 @@ impl<'a> Parser<'a> { pub fn warn(&self, m: &str) { self.sess.span_diagnostic.span_warn(self.span, m) } - pub fn span_warn(&self, sp: Span, m: &str) { + pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, m: &str) { self.sess.span_diagnostic.span_warn(sp, m) } - pub fn span_err(&self, sp: Span, m: &str) { + pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, m: &str) { self.sess.span_diagnostic.span_err(sp, m) } - pub fn struct_span_err(&self, sp: Span, m: &str) -> DiagnosticBuilder<'a> { + pub fn struct_span_err<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> DiagnosticBuilder<'a> { self.sess.span_diagnostic.struct_span_err(sp, m) } - pub fn span_err_help(&self, sp: Span, m: &str, h: &str) { + pub fn span_err_help<S: Into<MultiSpan>>(&self, sp: S, m: &str, h: &str) { let mut err = self.sess.span_diagnostic.mut_span_err(sp, m); err.help(h); err.emit(); } - pub fn span_bug(&self, sp: Span, m: &str) -> ! { + pub fn span_bug<S: Into<MultiSpan>>(&self, sp: S, m: &str) -> ! { self.sess.span_diagnostic.span_bug(sp, m) } pub fn abort_if_errors(&self) { @@ -1347,7 +1351,7 @@ impl<'a> Parser<'a> { Function Style */ - let unsafety = self.parse_unsafety()?; + let unsafety = self.parse_unsafety(); let abi = if self.eat_keyword(keywords::Extern) { self.parse_opt_abi()?.unwrap_or(Abi::C) } else { @@ -1370,11 +1374,12 @@ impl<'a> Parser<'a> { }))) } - pub fn parse_unsafety(&mut self) -> PResult<'a, Unsafety> { + /// Parse unsafety: `unsafe` or nothing. + fn parse_unsafety(&mut self) -> Unsafety { if self.eat_keyword(keywords::Unsafe) { - return Ok(Unsafety::Unsafe); + Unsafety::Unsafe } else { - return Ok(Unsafety::Normal); + Unsafety::Normal } } @@ -4094,28 +4099,6 @@ impl<'a> Parser<'a> { self.look_ahead(2, |t| t.is_keyword(keywords::Trait))) } - fn is_defaultness(&self) -> bool { - // `pub` is included for better error messages - self.token.is_keyword(keywords::Default) && - self.look_ahead(1, |t| t.is_keyword(keywords::Impl) || - t.is_keyword(keywords::Const) || - t.is_keyword(keywords::Fn) || - t.is_keyword(keywords::Unsafe) || - t.is_keyword(keywords::Extern) || - t.is_keyword(keywords::Type) || - t.is_keyword(keywords::Pub)) - } - - fn eat_defaultness(&mut self) -> bool { - let is_defaultness = self.is_defaultness(); - if is_defaultness { - self.bump() - } else { - self.expected_tokens.push(TokenType::Keyword(keywords::Default)); - } - is_defaultness - } - fn eat_macro_def(&mut self, attrs: &[Attribute], vis: &Visibility, lo: Span) -> PResult<'a, Option<P<Item>>> { let token_lo = self.span; @@ -4794,21 +4777,13 @@ impl<'a> Parser<'a> { } let lo = self.prev_span; - // This is a temporary future proofing. - // // We are considering adding generics to the `where` keyword as an alternative higher-rank // parameter syntax (as in `where<'a>` or `where<T>`. To avoid that being a breaking - // change, for now we refuse to parse `where < (ident | lifetime) (> | , | :)`. - if token::Lt == self.token { - let ident_or_lifetime = self.look_ahead(1, |t| t.is_ident() || t.is_lifetime()); - if ident_or_lifetime { - let gt_comma_or_colon = self.look_ahead(2, |t| { - *t == token::Gt || *t == token::Comma || *t == token::Colon - }); - if gt_comma_or_colon { - self.span_err(self.span, "syntax `where<T>` is reserved for future use"); - } - } + // change we parse those generics now, but report an error. + if self.choose_generics_over_qpath() { + let generics = self.parse_generics()?; + self.span_err(generics.span, + "generic parameters on `where` clauses are reserved for future use"); } loop { @@ -5126,7 +5101,7 @@ impl<'a> Parser<'a> { fn parse_item_fn(&mut self, unsafety: Unsafety, constness: Spanned<Constness>, - abi: abi::Abi) + abi: Abi) -> PResult<'a, ItemInfo> { let (ident, mut generics) = self.parse_fn_header()?; let decl = self.parse_fn_decl(false)?; @@ -5150,13 +5125,10 @@ impl<'a> Parser<'a> { /// - `const unsafe fn` /// - `extern fn` /// - etc - pub fn parse_fn_front_matter(&mut self) - -> PResult<'a, (Spanned<ast::Constness>, - ast::Unsafety, - abi::Abi)> { + pub fn parse_fn_front_matter(&mut self) -> PResult<'a, (Spanned<Constness>, Unsafety, Abi)> { let is_const_fn = self.eat_keyword(keywords::Const); let const_span = self.prev_span; - let unsafety = self.parse_unsafety()?; + let unsafety = self.parse_unsafety(); let (constness, unsafety, abi) = if is_const_fn { (respan(const_span, Constness::Const), unsafety, Abi::Rust) } else { @@ -5191,7 +5163,7 @@ impl<'a> Parser<'a> { mut attrs: Vec<Attribute>) -> PResult<'a, ImplItem> { let lo = self.span; let vis = self.parse_visibility(false)?; - let defaultness = self.parse_defaultness()?; + let defaultness = self.parse_defaultness(); let (name, node, generics) = if self.eat_keyword(keywords::Type) { // This parses the grammar: // ImplItemAssocTy = Ident ["<"...">"] ["where" ...] "=" Ty ";" @@ -5284,7 +5256,7 @@ impl<'a> Parser<'a> { /// Parse a method or a macro invocation in a trait impl. fn parse_impl_method(&mut self, vis: &Visibility, at_end: &mut bool) - -> PResult<'a, (Ident, Vec<ast::Attribute>, ast::Generics, + -> PResult<'a, (Ident, Vec<Attribute>, ast::Generics, ast::ImplItemKind)> { // code copied from parse_macro_use_or_failure... abstraction! if self.token.is_path_start() && !self.is_extern_non_path() { @@ -5373,83 +5345,123 @@ impl<'a> Parser<'a> { } } - /// Parses items implementations variants - /// impl<T> Foo { ... } - /// impl<T> ToString for &'static T { ... } - fn parse_item_impl(&mut self, - unsafety: ast::Unsafety, - defaultness: Defaultness) -> PResult<'a, ItemInfo> { + fn choose_generics_over_qpath(&self) -> bool { + // There's an ambiguity between generic parameters and qualified paths in impls. + // If we see `<` it may start both, so we have to inspect some following tokens. + // The following combinations can only start generics, + // but not qualified paths (with one exception): + // `<` `>` - empty generic parameters + // `<` `#` - generic parameters with attributes + // `<` (LIFETIME|IDENT) `>` - single generic parameter + // `<` (LIFETIME|IDENT) `,` - first generic parameter in a list + // `<` (LIFETIME|IDENT) `:` - generic parameter with bounds + // `<` (LIFETIME|IDENT) `=` - generic parameter with a default + // The only truly ambiguous case is + // `<` IDENT `>` `::` IDENT ... + // we disambiguate it in favor of generics (`impl<T> ::absolute::Path<T> { ... }`) + // because this is what almost always expected in practice, qualified paths in impls + // (`impl <Type>::AssocTy { ... }`) aren't even allowed by type checker at the moment. + self.token == token::Lt && + (self.look_ahead(1, |t| t == &token::Pound || t == &token::Gt) || + self.look_ahead(1, |t| t.is_lifetime() || t.is_ident()) && + self.look_ahead(2, |t| t == &token::Gt || t == &token::Comma || + t == &token::Colon || t == &token::Eq)) + } + + fn parse_impl_body(&mut self) -> PResult<'a, (Vec<ImplItem>, Vec<Attribute>)> { + self.expect(&token::OpenDelim(token::Brace))?; + let attrs = self.parse_inner_attributes()?; - // First, parse type parameters if necessary. - let mut generics = self.parse_generics()?; + let mut impl_items = Vec::new(); + while !self.eat(&token::CloseDelim(token::Brace)) { + let mut at_end = false; + match self.parse_impl_item(&mut at_end) { + Ok(impl_item) => impl_items.push(impl_item), + Err(mut err) => { + err.emit(); + if !at_end { + self.recover_stmt_(SemiColonMode::Break, BlockMode::Break); + } + } + } + } + Ok((impl_items, attrs)) + } - // Special case: if the next identifier that follows is '(', don't - // allow this to be parsed as a trait. - let could_be_trait = self.token != token::OpenDelim(token::Paren); + /// Parses an implementation item, `impl` keyword is already parsed. + /// impl<'a, T> TYPE { /* impl items */ } + /// impl<'a, T> TRAIT for TYPE { /* impl items */ } + /// impl<'a, T> !TRAIT for TYPE { /* impl items */ } + /// We actually parse slightly more relaxed grammar for better error reporting and recovery. + /// `impl` GENERICS `!`? TYPE `for`? (TYPE | `..`) (`where` PREDICATES)? `{` BODY `}` + /// `impl` GENERICS `!`? TYPE (`where` PREDICATES)? `{` BODY `}` + fn parse_item_impl(&mut self, unsafety: Unsafety, defaultness: Defaultness) + -> PResult<'a, ItemInfo> { + // First, parse generic parameters if necessary. + let mut generics = if self.choose_generics_over_qpath() { + self.parse_generics()? + } else { + ast::Generics::default() + }; - let neg_span = self.span; - let polarity = if self.eat(&token::Not) { + // Disambiguate `impl !Trait for Type { ... }` and `impl ! { ... }` for the never type. + let polarity = if self.check(&token::Not) && self.look_ahead(1, |t| t.can_begin_type()) { + self.bump(); // `!` ast::ImplPolarity::Negative } else { ast::ImplPolarity::Positive }; - // Parse the trait. - let mut ty = self.parse_ty()?; - - // Parse traits, if necessary. - let opt_trait = if could_be_trait && self.eat_keyword(keywords::For) { - // New-style trait. Reinterpret the type as a trait. - match ty.node { - TyKind::Path(None, ref path) => { - Some(TraitRef { - path: (*path).clone(), - ref_id: ty.id, - }) - } - _ => { - self.span_err(ty.span, "not a trait"); - None - } - } + // Parse both types and traits as a type, then reinterpret if necessary. + let ty_first = self.parse_ty()?; + + // If `for` is missing we try to recover. + let has_for = self.eat_keyword(keywords::For); + let missing_for_span = self.prev_span.between(self.span); + + let ty_second = if self.token == token::DotDot { + // We need to report this error after `cfg` expansion for compatibility reasons + self.bump(); // `..`, do not add it to expected tokens + Some(P(Ty { node: TyKind::Err, span: self.prev_span, id: ast::DUMMY_NODE_ID })) + } else if has_for || self.token.can_begin_type() { + Some(self.parse_ty()?) } else { - if polarity == ast::ImplPolarity::Negative { - // This is a negated type implementation - // `impl !MyType {}`, which is not allowed. - self.span_err(neg_span, "inherent implementation can't be negated"); - } None }; - if opt_trait.is_some() { - ty = if self.eat(&token::DotDot) { - P(Ty { node: TyKind::Err, span: self.prev_span, id: ast::DUMMY_NODE_ID }) - } else { - self.parse_ty()? - } - } generics.where_clause = self.parse_where_clause()?; - self.expect(&token::OpenDelim(token::Brace))?; - let attrs = self.parse_inner_attributes()?; + let (impl_items, attrs) = self.parse_impl_body()?; - let mut impl_items = vec![]; - while !self.eat(&token::CloseDelim(token::Brace)) { - let mut at_end = false; - match self.parse_impl_item(&mut at_end) { - Ok(item) => impl_items.push(item), - Err(mut e) => { - e.emit(); - if !at_end { - self.recover_stmt_(SemiColonMode::Break, BlockMode::Break); - } + let item_kind = match ty_second { + Some(ty_second) => { + // impl Trait for Type + if !has_for { + self.span_err(missing_for_span, "missing `for` in a trait impl"); } + + let ty_first = ty_first.into_inner(); + let path = match ty_first.node { + // This notably includes paths passed through `ty` macro fragments (#46438). + TyKind::Path(None, path) => path, + _ => { + self.span_err(ty_first.span, "expected a trait, found type"); + ast::Path::from_ident(ty_first.span, keywords::Invalid.ident()) + } + }; + let trait_ref = TraitRef { path, ref_id: ty_first.id }; + + ItemKind::Impl(unsafety, polarity, defaultness, + generics, Some(trait_ref), ty_second, impl_items) } - } + None => { + // impl Type + ItemKind::Impl(unsafety, polarity, defaultness, + generics, None, ty_first, impl_items) + } + }; - Ok((keywords::Invalid.ident(), - ItemKind::Impl(unsafety, polarity, defaultness, generics, opt_trait, ty, impl_items), - Some(attrs))) + Ok((keywords::Invalid.ident(), item_kind, Some(attrs))) } fn parse_late_bound_lifetime_defs(&mut self) -> PResult<'a, Vec<GenericParam>> { @@ -5722,12 +5734,21 @@ impl<'a> Parser<'a> { Ok(Visibility::Public) } - /// Parse defaultness: DEFAULT or nothing - fn parse_defaultness(&mut self) -> PResult<'a, Defaultness> { - if self.eat_defaultness() { - Ok(Defaultness::Default) + /// Parse defaultness: `default` or nothing. + fn parse_defaultness(&mut self) -> Defaultness { + // `pub` is included for better error messages + if self.check_keyword(keywords::Default) && + self.look_ahead(1, |t| t.is_keyword(keywords::Impl) || + t.is_keyword(keywords::Const) || + t.is_keyword(keywords::Fn) || + t.is_keyword(keywords::Unsafe) || + t.is_keyword(keywords::Extern) || + t.is_keyword(keywords::Type) || + t.is_keyword(keywords::Pub)) { + self.bump(); // `default` + Defaultness::Default } else { - Ok(Defaultness::Final) + Defaultness::Final } } @@ -5797,7 +5818,7 @@ impl<'a> Parser<'a> { let (module, mut attrs) = self.eval_src_mod(path, directory_ownership, id.to_string(), id_span)?; if warn { - let attr = ast::Attribute { + let attr = Attribute { id: attr::mk_attr_id(), style: ast::AttrStyle::Outer, path: ast::Path::from_ident(syntax_pos::DUMMY_SP, @@ -5837,7 +5858,7 @@ impl<'a> Parser<'a> { } } - pub fn submod_path_from_attr(attrs: &[ast::Attribute], dir_path: &Path) -> Option<PathBuf> { + pub fn submod_path_from_attr(attrs: &[Attribute], dir_path: &Path) -> Option<PathBuf> { attr::first_attr_value_str_by_name(attrs, "path").map(|d| dir_path.join(&d.as_str())) } @@ -5906,7 +5927,7 @@ impl<'a> Parser<'a> { fn submod_path(&mut self, id: ast::Ident, - outer_attrs: &[ast::Attribute], + outer_attrs: &[Attribute], id_sp: Span) -> PResult<'a, ModulePathSuccess> { if let Some(path) = Parser::submod_path_from_attr(outer_attrs, &self.directory.path) { @@ -5999,7 +6020,7 @@ impl<'a> Parser<'a> { directory_ownership: DirectoryOwnership, name: String, id_sp: Span) - -> PResult<'a, (ast::ItemKind, Vec<ast::Attribute> )> { + -> PResult<'a, (ast::ItemKind, Vec<Attribute> )> { let mut included_mod_stack = self.sess.included_mod_stack.borrow_mut(); if let Some(i) = included_mod_stack.iter().position(|p| *p == path) { let mut err = String::from("circular modules: "); @@ -6122,7 +6143,7 @@ impl<'a> Parser<'a> { /// extern {} fn parse_item_foreign_mod(&mut self, lo: Span, - opt_abi: Option<abi::Abi>, + opt_abi: Option<Abi>, visibility: Visibility, mut attrs: Vec<Attribute>) -> PResult<'a, P<Item>> { @@ -6225,7 +6246,7 @@ impl<'a> Parser<'a> { /// Parses a string as an ABI spec on an extern type or module. Consumes /// the `extern` keyword, if one is found. - fn parse_opt_abi(&mut self) -> PResult<'a, Option<abi::Abi>> { + fn parse_opt_abi(&mut self) -> PResult<'a, Option<Abi>> { match self.token { token::Literal(token::Str_(s), suf) | token::Literal(token::StrRaw(s, _), suf) => { let sp = self.span; @@ -6330,11 +6351,7 @@ impl<'a> Parser<'a> { || (self.check_keyword(keywords::Unsafe) && self.look_ahead(1, |t| t.is_keyword(keywords::Fn))) { // CONST FUNCTION ITEM - let unsafety = if self.eat_keyword(keywords::Unsafe) { - Unsafety::Unsafe - } else { - Unsafety::Normal - }; + let unsafety = self.parse_unsafety(); self.bump(); let (ident, item_, extra_attrs) = self.parse_item_fn(unsafety, @@ -6370,7 +6387,7 @@ impl<'a> Parser<'a> { self.look_ahead(1, |t| t.is_keyword(keywords::Auto))) { // UNSAFE TRAIT ITEM - self.expect_keyword(keywords::Unsafe)?; + self.bump(); // `unsafe` let is_auto = if self.eat_keyword(keywords::Trait) { IsAuto::No } else { @@ -6379,7 +6396,7 @@ impl<'a> Parser<'a> { IsAuto::Yes }; let (ident, item_, extra_attrs) = - self.parse_item_trait(is_auto, ast::Unsafety::Unsafe)?; + self.parse_item_trait(is_auto, Unsafety::Unsafe)?; let prev_span = self.prev_span; let item = self.mk_item(lo.to(prev_span), ident, @@ -6388,26 +6405,21 @@ impl<'a> Parser<'a> { maybe_append(attrs, extra_attrs)); return Ok(Some(item)); } - if (self.check_keyword(keywords::Unsafe) && - self.look_ahead(1, |t| t.is_keyword(keywords::Impl))) || - (self.check_keyword(keywords::Default) && - self.look_ahead(1, |t| t.is_keyword(keywords::Unsafe)) && - self.look_ahead(2, |t| t.is_keyword(keywords::Impl))) - { + if self.check_keyword(keywords::Impl) || + self.check_keyword(keywords::Unsafe) && + self.look_ahead(1, |t| t.is_keyword(keywords::Impl)) || + self.check_keyword(keywords::Default) && + self.look_ahead(1, |t| t.is_keyword(keywords::Impl)) || + self.check_keyword(keywords::Default) && + self.look_ahead(1, |t| t.is_keyword(keywords::Unsafe)) { // IMPL ITEM - let defaultness = self.parse_defaultness()?; - self.expect_keyword(keywords::Unsafe)?; + let defaultness = self.parse_defaultness(); + let unsafety = self.parse_unsafety(); self.expect_keyword(keywords::Impl)?; - let (ident, - item_, - extra_attrs) = self.parse_item_impl(ast::Unsafety::Unsafe, defaultness)?; - let prev_span = self.prev_span; - let item = self.mk_item(lo.to(prev_span), - ident, - item_, - visibility, - maybe_append(attrs, extra_attrs)); - return Ok(Some(item)); + let (ident, item, extra_attrs) = self.parse_item_impl(unsafety, defaultness)?; + let span = lo.to(self.prev_span); + return Ok(Some(self.mk_item(span, ident, item, visibility, + maybe_append(attrs, extra_attrs)))); } if self.check_keyword(keywords::Fn) { // FUNCTION ITEM @@ -6428,7 +6440,7 @@ impl<'a> Parser<'a> { if self.check_keyword(keywords::Unsafe) && self.look_ahead(1, |t| *t != token::OpenDelim(token::Brace)) { // UNSAFE FUNCTION ITEM - self.bump(); + self.bump(); // `unsafe` let abi = if self.eat_keyword(keywords::Extern) { self.parse_opt_abi()?.unwrap_or(Abi::C) } else { @@ -6495,25 +6507,7 @@ impl<'a> Parser<'a> { }; // TRAIT ITEM let (ident, item_, extra_attrs) = - self.parse_item_trait(is_auto, ast::Unsafety::Normal)?; - let prev_span = self.prev_span; - let item = self.mk_item(lo.to(prev_span), - ident, - item_, - visibility, - maybe_append(attrs, extra_attrs)); - return Ok(Some(item)); - } - if (self.check_keyword(keywords::Impl)) || - (self.check_keyword(keywords::Default) && - self.look_ahead(1, |t| t.is_keyword(keywords::Impl))) - { - // IMPL ITEM - let defaultness = self.parse_defaultness()?; - self.expect_keyword(keywords::Impl)?; - let (ident, - item_, - extra_attrs) = self.parse_item_impl(ast::Unsafety::Normal, defaultness)?; + self.parse_item_trait(is_auto, Unsafety::Normal)?; let prev_span = self.prev_span; let item = self.mk_item(lo.to(prev_span), ident, diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 5374bf180f4..ff065b57b8d 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1839,7 +1839,7 @@ impl<'a> State<'a> { } pub fn print_expr_maybe_paren(&mut self, expr: &ast::Expr, prec: i8) -> io::Result<()> { - let needs_par = parser::expr_precedence(expr) < prec; + let needs_par = expr.precedence().order() < prec; if needs_par { self.popen()?; } diff --git a/src/libsyntax/util/parser.rs b/src/libsyntax/util/parser.rs index 6014ec5aa92..86963c4000b 100644 --- a/src/libsyntax/util/parser.rs +++ b/src/libsyntax/util/parser.rs @@ -9,7 +9,9 @@ // except according to those terms. use parse::token::{Token, BinOpToken}; use symbol::keywords; -use ast::{self, BinOpKind, ExprKind}; +use ast::{self, BinOpKind}; + +use std::cmp::Ordering; /// Associative operator with precedence. /// @@ -228,66 +230,130 @@ pub const PREC_POSTFIX: i8 = 60; pub const PREC_PAREN: i8 = 99; pub const PREC_FORCE_PAREN: i8 = 100; -pub fn expr_precedence(expr: &ast::Expr) -> i8 { - match expr.node { - ExprKind::Closure(..) => PREC_CLOSURE, - - ExprKind::Break(..) | - ExprKind::Continue(..) | - ExprKind::Ret(..) | - ExprKind::Yield(..) => PREC_JUMP, - - // `Range` claims to have higher precedence than `Assign`, but `x .. x = x` fails to parse, - // instead of parsing as `(x .. x) = x`. Giving `Range` a lower precedence ensures that - // `pprust` will add parentheses in the right places to get the desired parse. - ExprKind::Range(..) => PREC_RANGE, - - // Binop-like expr kinds, handled by `AssocOp`. - ExprKind::Binary(op, _, _) => - AssocOp::from_ast_binop(op.node).precedence() as i8, - - ExprKind::InPlace(..) => AssocOp::Inplace.precedence() as i8, - ExprKind::Cast(..) => AssocOp::As.precedence() as i8, - ExprKind::Type(..) => AssocOp::Colon.precedence() as i8, - - ExprKind::Assign(..) | - ExprKind::AssignOp(..) => AssocOp::Assign.precedence() as i8, - - // Unary, prefix - ExprKind::Box(..) | - ExprKind::AddrOf(..) | - ExprKind::Unary(..) => PREC_PREFIX, - - // Unary, postfix - ExprKind::Call(..) | - ExprKind::MethodCall(..) | - ExprKind::Field(..) | - ExprKind::TupField(..) | - ExprKind::Index(..) | - ExprKind::Try(..) | - ExprKind::InlineAsm(..) | - ExprKind::Mac(..) => PREC_POSTFIX, - - // Never need parens - ExprKind::Array(..) | - ExprKind::Repeat(..) | - ExprKind::Tup(..) | - ExprKind::Lit(..) | - ExprKind::Path(..) | - ExprKind::Paren(..) | - ExprKind::If(..) | - ExprKind::IfLet(..) | - ExprKind::While(..) | - ExprKind::WhileLet(..) | - ExprKind::ForLoop(..) | - ExprKind::Loop(..) | - ExprKind::Match(..) | - ExprKind::Block(..) | - ExprKind::Catch(..) | - ExprKind::Struct(..) => PREC_PAREN, +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum ExprPrecedence { + Closure, + Break, + Continue, + Ret, + Yield, + + Range, + + Binary(BinOpKind), + + InPlace, + Cast, + Type, + + Assign, + AssignOp, + + Box, + AddrOf, + Unary, + + Call, + MethodCall, + Field, + TupField, + Index, + Try, + InlineAsm, + Mac, + + Array, + Repeat, + Tup, + Lit, + Path, + Paren, + If, + IfLet, + While, + WhileLet, + ForLoop, + Loop, + Match, + Block, + Catch, + Struct, +} + +impl PartialOrd for ExprPrecedence { + fn partial_cmp(&self, other: &Self) -> Option<Ordering> { + Some(self.order().cmp(&other.order())) + } +} + +impl Ord for ExprPrecedence { + fn cmp(&self, other: &Self) -> Ordering { + self.order().cmp(&other.order()) } } +impl ExprPrecedence { + pub fn order(self) -> i8 { + match self { + ExprPrecedence::Closure => PREC_CLOSURE, + + ExprPrecedence::Break | + ExprPrecedence::Continue | + ExprPrecedence::Ret | + ExprPrecedence::Yield => PREC_JUMP, + + // `Range` claims to have higher precedence than `Assign`, but `x .. x = x` fails to + // parse, instead of parsing as `(x .. x) = x`. Giving `Range` a lower precedence + // ensures that `pprust` will add parentheses in the right places to get the desired + // parse. + ExprPrecedence::Range => PREC_RANGE, + + // Binop-like expr kinds, handled by `AssocOp`. + ExprPrecedence::Binary(op) => AssocOp::from_ast_binop(op).precedence() as i8, + ExprPrecedence::InPlace => AssocOp::Inplace.precedence() as i8, + ExprPrecedence::Cast => AssocOp::As.precedence() as i8, + ExprPrecedence::Type => AssocOp::Colon.precedence() as i8, + + ExprPrecedence::Assign | + ExprPrecedence::AssignOp => AssocOp::Assign.precedence() as i8, + + // Unary, prefix + ExprPrecedence::Box | + ExprPrecedence::AddrOf | + ExprPrecedence::Unary => PREC_PREFIX, + + // Unary, postfix + ExprPrecedence::Call | + ExprPrecedence::MethodCall | + ExprPrecedence::Field | + ExprPrecedence::TupField | + ExprPrecedence::Index | + ExprPrecedence::Try | + ExprPrecedence::InlineAsm | + ExprPrecedence::Mac => PREC_POSTFIX, + + // Never need parens + ExprPrecedence::Array | + ExprPrecedence::Repeat | + ExprPrecedence::Tup | + ExprPrecedence::Lit | + ExprPrecedence::Path | + ExprPrecedence::Paren | + ExprPrecedence::If | + ExprPrecedence::IfLet | + ExprPrecedence::While | + ExprPrecedence::WhileLet | + ExprPrecedence::ForLoop | + ExprPrecedence::Loop | + ExprPrecedence::Match | + ExprPrecedence::Block | + ExprPrecedence::Catch | + ExprPrecedence::Struct => PREC_PAREN, + } + } +} + + /// Expressions that syntactically contain an "exterior" struct literal i.e. not surrounded by any /// parens or other delimiters, e.g. `X { y: 1 }`, `X { y: 1 }.method()`, `foo == X { y: 1 }` and /// `X { y: 1 } == foo` all do, but `(X { y: 1 }) == foo` does not. diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index 08a7f85d14b..3660d2fe46a 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -830,7 +830,9 @@ fn find_repr_type_name(diagnostic: &Handler, type_attrs: &[ast::Attribute]) -> & for a in type_attrs { for r in &attr::find_repr_attrs(diagnostic, a) { repr_type_name = match *r { - attr::ReprPacked | attr::ReprSimd | attr::ReprAlign(_) => continue, + attr::ReprPacked | attr::ReprSimd | attr::ReprAlign(_) | attr::ReprTransparent => + continue, + attr::ReprC => "i32", attr::ReprInt(attr::SignedInt(ast::IntTy::Isize)) => "isize", diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs index ad5bd39a453..a7822414c69 100644 --- a/src/libsyntax_ext/format.rs +++ b/src/libsyntax_ext/format.rs @@ -814,15 +814,11 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, let (sp, msg) = errs.into_iter().next().unwrap(); cx.ecx.struct_span_err(sp, msg) } else { - let mut diag = cx.ecx.struct_span_err(cx.fmtsp, - "multiple unused formatting arguments"); - - // Ignoring message, as it gets repetitive - // Then use MultiSpan to not clutter up errors - for (sp, _) in errs { - diag.span_label(sp, "unused"); - } - + let mut diag = cx.ecx.struct_span_err( + errs.iter().map(|&(sp, _)| sp).collect::<Vec<Span>>(), + "multiple unused formatting arguments" + ); + diag.span_label(cx.fmtsp, "multiple unused arguments in this statement"); diag } }; diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 4e326c9e199..54a73a04bfa 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -746,10 +746,6 @@ LLVMRustSetDataLayoutFromTargetMachine(LLVMModuleRef Module, unwrap(Module)->setDataLayout(Target->createDataLayout()); } -extern "C" LLVMTargetDataRef LLVMRustGetModuleDataLayout(LLVMModuleRef M) { - return wrap(&unwrap(M)->getDataLayout()); -} - extern "C" void LLVMRustSetModulePIELevel(LLVMModuleRef M) { unwrap(M)->setPIELevel(PIELevel::Level::Large); } diff --git a/src/test/codegen/issue-47278.rs b/src/test/codegen/issue-47278.rs new file mode 100644 index 00000000000..21858b434bf --- /dev/null +++ b/src/test/codegen/issue-47278.rs @@ -0,0 +1,19 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// -C no-prepopulate-passes +#![crate_type="staticlib"] + +#[repr(C)] +pub struct Foo(u64); + +// CHECK: define {{.*}} @foo( +#[no_mangle] +pub extern fn foo(_: Foo) -> Foo { loop {} } diff --git a/src/test/codegen/issue-47442.rs b/src/test/codegen/issue-47442.rs new file mode 100644 index 00000000000..d0c9932e4e2 --- /dev/null +++ b/src/test/codegen/issue-47442.rs @@ -0,0 +1,32 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// check that we don't emit unneeded `resume` cleanup blocks for every +// destructor. + +// CHECK-NOT: Unwind + +#![feature(test)] +#![crate_type="rlib"] + +extern crate test; + +struct Foo {} + +impl Drop for Foo { + fn drop(&mut self) { + test::black_box(()); + } +} + +#[no_mangle] +pub fn foo() { + let _foo = Foo {}; +} diff --git a/src/test/codegen/repr-transparent-aggregates-1.rs b/src/test/codegen/repr-transparent-aggregates-1.rs new file mode 100644 index 00000000000..2eeed2b788c --- /dev/null +++ b/src/test/codegen/repr-transparent-aggregates-1.rs @@ -0,0 +1,53 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -C no-prepopulate-passes + +// ignore-arm +// ignore-mips +// ignore-mips64 +// ignore-powerpc +// ignore-powerpc64 +// See repr-transparent.rs + +#![crate_type="lib"] +#![feature(repr_transparent)] + + +#[repr(C)] +pub struct Big([u32; 16]); + +#[repr(transparent)] +pub struct BigW(Big); + +// CHECK: define void @test_Big(%Big* [[BIG_RET_ATTRS:.*]], %Big* [[BIG_ARG_ATTRS:.*]]) +#[no_mangle] +pub extern fn test_Big(_: Big) -> Big { loop {} } + +// CHECK: define void @test_BigW(%BigW* [[BIG_RET_ATTRS]], %BigW* [[BIG_ARG_ATTRS]]) +#[no_mangle] +pub extern fn test_BigW(_: BigW) -> BigW { loop {} } + + +#[repr(C)] +pub union BigU { + foo: [u32; 16], +} + +#[repr(transparent)] +pub struct BigUw(BigU); + +// CHECK: define void @test_BigU(%BigU* [[BIGU_RET_ATTRS:.*]], %BigU* [[BIGU_ARG_ATTRS:.*]]) +#[no_mangle] +pub extern fn test_BigU(_: BigU) -> BigU { loop {} } + +// CHECK: define void @test_BigUw(%BigUw* [[BIGU_RET_ATTRS]], %BigUw* [[BIGU_ARG_ATTRS]]) +#[no_mangle] +pub extern fn test_BigUw(_: BigUw) -> BigUw { loop {} } diff --git a/src/test/codegen/repr-transparent-aggregates-2.rs b/src/test/codegen/repr-transparent-aggregates-2.rs new file mode 100644 index 00000000000..e6374928a5c --- /dev/null +++ b/src/test/codegen/repr-transparent-aggregates-2.rs @@ -0,0 +1,54 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -C no-prepopulate-passes + +// ignore-aarch64 +// ignore-asmjs +// ignore-s390x +// ignore-wasm +// ignore-x86 +// ignore-x86_64 +// See repr-transparent.rs + +#![crate_type="lib"] +#![feature(repr_transparent)] + + +#[repr(C)] +pub struct Big([u32; 16]); + +#[repr(transparent)] +pub struct BigW(Big); + +// CHECK: define void @test_Big(%Big* [[BIG_RET_ATTRS:.*]], [16 x i32] +#[no_mangle] +pub extern fn test_Big(_: Big) -> Big { loop {} } + +// CHECK: define void @test_BigW(%BigW* [[BIG_RET_ATTRS]], [16 x i32] +#[no_mangle] +pub extern fn test_BigW(_: BigW) -> BigW { loop {} } + + +#[repr(C)] +pub union BigU { + foo: [u32; 16], +} + +#[repr(transparent)] +pub struct BigUw(BigU); + +// CHECK: define void @test_BigU(%BigU* [[BIGU_RET_ATTRS:.*]], [16 x i32] +#[no_mangle] +pub extern fn test_BigU(_: BigU) -> BigU { loop {} } + +// CHECK: define void @test_BigUw(%BigUw* [[BIGU_RET_ATTRS]], [16 x i32] +#[no_mangle] +pub extern fn test_BigUw(_: BigUw) -> BigUw { loop {} } diff --git a/src/test/codegen/repr-transparent.rs b/src/test/codegen/repr-transparent.rs new file mode 100644 index 00000000000..31020d8b94f --- /dev/null +++ b/src/test/codegen/repr-transparent.rs @@ -0,0 +1,177 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -C no-prepopulate-passes + +#![crate_type="lib"] +#![feature(repr_transparent, repr_simd)] + +use std::marker::PhantomData; + +pub struct Zst1; +pub struct Zst2(()); + +#[repr(transparent)] +pub struct F32(f32); + +// CHECK: define float @test_F32(float %arg0) +#[no_mangle] +pub extern fn test_F32(_: F32) -> F32 { loop {} } + +#[repr(transparent)] +pub struct Ptr(*mut u8); + +// CHECK: define i8* @test_Ptr(i8* %arg0) +#[no_mangle] +pub extern fn test_Ptr(_: Ptr) -> Ptr { loop {} } + +#[repr(transparent)] +pub struct WithZst(u64, Zst1); + +// CHECK: define i64 @test_WithZst(i64 %arg0) +#[no_mangle] +pub extern fn test_WithZst(_: WithZst) -> WithZst { loop {} } + +#[repr(transparent)] +pub struct WithZeroSizedArray(*const f32, [i8; 0]); + +// Apparently we use i32* when newtype-unwrapping f32 pointers. Whatever. +// CHECK: define i32* @test_WithZeroSizedArray(i32* %arg0) +#[no_mangle] +pub extern fn test_WithZeroSizedArray(_: WithZeroSizedArray) -> WithZeroSizedArray { loop {} } + +#[repr(transparent)] +pub struct Generic<T>(T); + +// CHECK: define double @test_Generic(double %arg0) +#[no_mangle] +pub extern fn test_Generic(_: Generic<f64>) -> Generic<f64> { loop {} } + +#[repr(transparent)] +pub struct GenericPlusZst<T>(T, Zst2); + +#[repr(u8)] +pub enum Bool { True, False, FileNotFound } + +// CHECK: define{{( zeroext)?}} i8 @test_Gpz(i8{{( zeroext)?}} %arg0) +#[no_mangle] +pub extern fn test_Gpz(_: GenericPlusZst<Bool>) -> GenericPlusZst<Bool> { loop {} } + +#[repr(transparent)] +pub struct LifetimePhantom<'a, T: 'a>(*const T, PhantomData<&'a T>); + +// CHECK: define i16* @test_LifetimePhantom(i16* %arg0) +#[no_mangle] +pub extern fn test_LifetimePhantom(_: LifetimePhantom<i16>) -> LifetimePhantom<i16> { loop {} } + +// This works despite current alignment resrictions because PhantomData is always align(1) +#[repr(transparent)] +pub struct UnitPhantom<T, U> { val: T, unit: PhantomData<U> } + +pub struct Px; + +// CHECK: define float @test_UnitPhantom(float %arg0) +#[no_mangle] +pub extern fn test_UnitPhantom(_: UnitPhantom<f32, Px>) -> UnitPhantom<f32, Px> { loop {} } + +#[repr(transparent)] +pub struct TwoZsts(Zst1, i8, Zst2); + +// CHECK: define{{( signext)?}} i8 @test_TwoZsts(i8{{( signext)?}} %arg0) +#[no_mangle] +pub extern fn test_TwoZsts(_: TwoZsts) -> TwoZsts { loop {} } + +#[repr(transparent)] +pub struct Nested1(Zst2, Generic<f64>); + +// CHECK: define double @test_Nested1(double %arg0) +#[no_mangle] +pub extern fn test_Nested1(_: Nested1) -> Nested1 { loop {} } + +#[repr(transparent)] +pub struct Nested2(Nested1, Zst1); + +// CHECK: define double @test_Nested2(double %arg0) +#[no_mangle] +pub extern fn test_Nested2(_: Nested2) -> Nested2 { loop {} } + +#[repr(simd)] +struct f32x4(f32, f32, f32, f32); + +#[repr(transparent)] +pub struct Vector(f32x4); + +// CHECK: define <4 x float> @test_Vector(<4 x float> %arg0) +#[no_mangle] +pub extern fn test_Vector(_: Vector) -> Vector { loop {} } + +trait Mirror { type It: ?Sized; } +impl<T: ?Sized> Mirror for T { type It = Self; } + +#[repr(transparent)] +pub struct StructWithProjection(<f32 as Mirror>::It); + +// CHECK: define float @test_Projection(float %arg0) +#[no_mangle] +pub extern fn test_Projection(_: StructWithProjection) -> StructWithProjection { loop {} } + + +// The rest of this file tests newtypes around small aggregates on an ABI where small aggregates are +// packed into one register. This is ABI-dependent, so instead we focus on one ABI and supply a +// dummy definition for other ABIs to keep FileCheck happy. +// +// Bigger aggregates are tested in separate files called repr-transparent-aggregate-*.rs because +// there, the expected LLVM IR function signatures vary so much that it's not reasonably possible to +// cover all of them with a single CHECK line. Instead we group ABIs by the general "shape" of the +// signature and have a separate test file for each bin. +// +// PS: You may be wondering why we don't just compare the return types and argument types for +// equality with FileCheck regex captures. Well, rustc doesn't perform newtype unwrapping on +// newtypes containing aggregates. This is OK on all ABIs we support, but because LLVM has not +// gotten rid of pointee types yet, the IR function signature will be syntactically different (%Foo* +// vs %FooWrapper*). + +#[repr(C)] +pub struct Rgb8 { r: u8, g: u8, b: u8 } + +#[repr(transparent)] +pub struct Rgb8Wrap(Rgb8); + +// NB: closing parenthesis is missing because sometimes the argument has a name and sometimes not +// CHECK: define i32 @test_Rgb8Wrap(i32 +#[no_mangle] +#[cfg(all(target_arch="x86_64", target_os="linux"))] +pub extern fn test_Rgb8Wrap(_: Rgb8Wrap) -> Rgb8Wrap { loop {} } + +#[cfg(not(all(target_arch="x86_64", target_os="linux")))] +#[no_mangle] +pub extern fn test_Rgb8Wrap(_: u32) -> u32 { loop {} } + +// Same as with the small struct above: ABI-dependent, we only test the interesting case +// (ABIs that pack the aggregate into a scalar) and stub it out on other ABIs + +#[repr(C)] +pub union FloatBits { + float: f32, + bits: u32, +} + +#[repr(transparent)] +pub struct SmallUnion(FloatBits); + +// NB: closing parenthesis is missing because sometimes the argument has a name and sometimes not +// CHECK: define i32 @test_SmallUnion(i32 +#[no_mangle] +#[cfg(all(target_arch="x86_64", target_os="linux"))] +pub extern fn test_SmallUnion(_: SmallUnion) -> SmallUnion { loop {} } + +#[cfg(not(all(target_arch="x86_64", target_os="linux")))] +#[no_mangle] +pub extern fn test_SmallUnion(_: u32) -> u32 { loop {} } diff --git a/src/test/compile-fail-fulldeps/gated-macro-reexports.rs b/src/test/compile-fail-fulldeps/gated-macro-reexports.rs index 2a20c28cfb8..8b448e401bd 100644 --- a/src/test/compile-fail-fulldeps/gated-macro-reexports.rs +++ b/src/test/compile-fail-fulldeps/gated-macro-reexports.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// Test that macro reexports item are gated by `macro_reexport` feature gate. +// Test that macro re-exports item are gated by `macro_reexport` feature gate. // aux-build:macro_reexport_1.rs // gate-test-macro_reexport @@ -16,6 +16,6 @@ #![crate_type = "dylib"] #[macro_reexport(reexported)] -//~^ ERROR macros reexports are experimental and possibly buggy +//~^ ERROR macros re-exports are experimental and possibly buggy #[macro_use] #[no_link] extern crate macro_reexport_1; diff --git a/src/test/compile-fail/E0185.rs b/src/test/compile-fail/E0185.rs index be54c3754ea..0cd3d00a735 100644 --- a/src/test/compile-fail/E0185.rs +++ b/src/test/compile-fail/E0185.rs @@ -9,14 +9,16 @@ // except according to those terms. trait Foo { - fn foo(); //~ trait declared without `&self` + fn foo(); + //~^ NOTE trait method declared without `&self` } struct Bar; impl Foo for Bar { - fn foo(&self) {} //~ ERROR E0185 - //~^ `&self` used in impl + fn foo(&self) {} + //~^ ERROR E0185 + //~| NOTE `&self` used in impl } fn main() { diff --git a/src/test/compile-fail/E0198.rs b/src/test/compile-fail/E0198.rs index 892989cc6a0..1a779a41e66 100644 --- a/src/test/compile-fail/E0198.rs +++ b/src/test/compile-fail/E0198.rs @@ -12,7 +12,7 @@ struct Foo; -unsafe impl !Clone for Foo { } //~ ERROR negative implementations are not unsafe [E0198] +unsafe impl !Send for Foo { } //~ ERROR E0198 fn main() { } diff --git a/src/test/compile-fail/E0365.rs b/src/test/compile-fail/E0365.rs index a1efcde42b0..18a72b0ff9a 100644 --- a/src/test/compile-fail/E0365.rs +++ b/src/test/compile-fail/E0365.rs @@ -13,6 +13,6 @@ mod foo { } pub use foo as foo2; -//~^ ERROR `foo` is private, and cannot be reexported [E0365] +//~^ ERROR `foo` is private, and cannot be re-exported [E0365] fn main() {} diff --git a/src/test/compile-fail/E0618.rs b/src/test/compile-fail/E0618.rs index f28ac200dea..f46bdb99801 100644 --- a/src/test/compile-fail/E0618.rs +++ b/src/test/compile-fail/E0618.rs @@ -13,7 +13,9 @@ enum X { } fn main() { - X::Entry(); //~ ERROR expected function, found `X::Entry` [E0618] + X::Entry(); + //~^ ERROR expected function, found enum variant `X::Entry` [E0618] let x = 0i32; - x(); //~ ERROR expected function, found `i32` [E0618] + x(); + //~^ ERROR expected function, found `i32` [E0618] } diff --git a/src/test/compile-fail/E0658.rs b/src/test/compile-fail/E0658.rs new file mode 100644 index 00000000000..d30068eb1fe --- /dev/null +++ b/src/test/compile-fail/E0658.rs @@ -0,0 +1,13 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + let _ = ::std::u128::MAX; //~ ERROR E0658 +} diff --git a/src/test/compile-fail/E0659.rs b/src/test/compile-fail/E0659.rs new file mode 100644 index 00000000000..4bd452b0aac --- /dev/null +++ b/src/test/compile-fail/E0659.rs @@ -0,0 +1,26 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +mod moon { + pub fn foo() {} +} + +mod earth { + pub fn foo() {} +} + +mod collider { + pub use moon::*; + pub use earth::*; +} + +fn main() { + collider::foo(); //~ ERROR E0659 +} diff --git a/src/test/compile-fail/auxiliary/static_priv_by_default.rs b/src/test/compile-fail/auxiliary/static_priv_by_default.rs index 859f38e809f..73597e51f08 100644 --- a/src/test/compile-fail/auxiliary/static_priv_by_default.rs +++ b/src/test/compile-fail/auxiliary/static_priv_by_default.rs @@ -32,7 +32,7 @@ mod foo { fn foo() {} } - // these are public so the parent can reexport them. + // these are public so the parent can re-export them. pub static reexported_a: isize = 0; pub fn reexported_b() {} pub struct reexported_c; diff --git a/src/test/compile-fail/closure-bounds-static-cant-capture-borrowed.rs b/src/test/compile-fail/closure-bounds-static-cant-capture-borrowed.rs index 513a17e2ef2..1ffba68263a 100644 --- a/src/test/compile-fail/closure-bounds-static-cant-capture-borrowed.rs +++ b/src/test/compile-fail/closure-bounds-static-cant-capture-borrowed.rs @@ -13,7 +13,7 @@ fn bar<F>(blk: F) where F: FnOnce() + 'static { fn foo(x: &()) { bar(|| { - //~^ ERROR does not fulfill + //~^ ERROR explicit lifetime required in the type of `x` [E0621] let _ = x; }) } diff --git a/src/test/compile-fail/coherence-negative-impls-safe.rs b/src/test/compile-fail/coherence-negative-impls-safe.rs index 3b335d586f3..1ae07b64685 100644 --- a/src/test/compile-fail/coherence-negative-impls-safe.rs +++ b/src/test/compile-fail/coherence-negative-impls-safe.rs @@ -15,6 +15,6 @@ use std::marker::Send; struct TestType; unsafe impl !Send for TestType {} -//~^ ERROR negative implementations are not unsafe +//~^ ERROR negative impls cannot be unsafe fn main() {} diff --git a/src/test/compile-fail/impl-trait/must_outlive_least_region_or_bound.rs b/src/test/compile-fail/impl-trait/must_outlive_least_region_or_bound.rs index 837160bc2fc..0eb99ca0fc3 100644 --- a/src/test/compile-fail/impl-trait/must_outlive_least_region_or_bound.rs +++ b/src/test/compile-fail/impl-trait/must_outlive_least_region_or_bound.rs @@ -13,7 +13,7 @@ use std::fmt::Debug; fn elided(x: &i32) -> impl Copy { x } -//~^ ERROR cannot infer an appropriate lifetime +//~^ ERROR explicit lifetime required in the type of `x` [E0621] fn explicit<'a>(x: &'a i32) -> impl Copy { x } //~^ ERROR cannot infer an appropriate lifetime diff --git a/src/test/compile-fail/imports/reexports.rs b/src/test/compile-fail/imports/reexports.rs index 65e6e8d01b0..f50b5b0e849 100644 --- a/src/test/compile-fail/imports/reexports.rs +++ b/src/test/compile-fail/imports/reexports.rs @@ -13,7 +13,7 @@ mod a { mod foo {} mod a { - pub use super::foo; //~ ERROR cannot be reexported + pub use super::foo; //~ ERROR cannot be re-exported pub use super::*; //~ ERROR must import something with the glob's visibility } } @@ -24,17 +24,17 @@ mod b { pub mod a { pub use super::foo; // This is OK since the value `foo` is visible enough. - fn f(_: foo::S) {} // `foo` is imported in the type namespace (but not `pub` reexported). + fn f(_: foo::S) {} // `foo` is imported in the type namespace (but not `pub` re-exported). } pub mod b { pub use super::*; // This is also OK since the value `foo` is visible enough. - fn f(_: foo::S) {} // Again, the module `foo` is imported (but not `pub` reexported). + fn f(_: foo::S) {} // Again, the module `foo` is imported (but not `pub` re-exported). } } mod c { - // Test that `foo` is not reexported. + // Test that `foo` is not re-exported. use b::a::foo::S; //~ ERROR `foo` use b::b::foo::S as T; //~ ERROR `foo` } diff --git a/src/test/compile-fail/issue-16922.rs b/src/test/compile-fail/issue-16922.rs index b525d5f64fc..1768c834cb3 100644 --- a/src/test/compile-fail/issue-16922.rs +++ b/src/test/compile-fail/issue-16922.rs @@ -12,7 +12,7 @@ use std::any::Any; fn foo<T: Any>(value: &T) -> Box<Any> { Box::new(value) as Box<Any> - //~^ ERROR: cannot infer an appropriate lifetime + //~^ ERROR explicit lifetime required in the type of `value` [E0621] } fn main() { diff --git a/src/test/compile-fail/issue-43925.rs b/src/test/compile-fail/issue-43925.rs new file mode 100644 index 00000000000..8ad57647290 --- /dev/null +++ b/src/test/compile-fail/issue-43925.rs @@ -0,0 +1,16 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(attr_literals)] + +#[link(name="foo", cfg("rlib"))] //~ ERROR invalid argument for `cfg(..)` +extern {} + +fn main() {} diff --git a/src/test/compile-fail/issue-43926.rs b/src/test/compile-fail/issue-43926.rs new file mode 100644 index 00000000000..5d510b643a3 --- /dev/null +++ b/src/test/compile-fail/issue-43926.rs @@ -0,0 +1,14 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[link(name="foo", cfg())] //~ ERROR `cfg()` must have an argument +extern {} + +fn main() {} diff --git a/src/test/compile-fail/issue-46209-private-enum-variant-reexport.rs b/src/test/compile-fail/issue-46209-private-enum-variant-reexport.rs index 5b23e5e8150..f5a20dd96dc 100644 --- a/src/test/compile-fail/issue-46209-private-enum-variant-reexport.rs +++ b/src/test/compile-fail/issue-46209-private-enum-variant-reexport.rs @@ -12,14 +12,14 @@ mod rank { pub use self::Professor::*; - //~^ ERROR enum is private and its variants cannot be reexported + //~^ ERROR enum is private and its variants cannot be re-exported pub use self::Lieutenant::{JuniorGrade, Full}; - //~^ ERROR variant `JuniorGrade` is private and cannot be reexported - //~| ERROR variant `Full` is private and cannot be reexported + //~^ ERROR variant `JuniorGrade` is private and cannot be re-exported + //~| ERROR variant `Full` is private and cannot be re-exported pub use self::PettyOfficer::*; - //~^ ERROR enum is private and its variants cannot be reexported + //~^ ERROR enum is private and its variants cannot be re-exported pub use self::Crewman::*; - //~^ ERROR enum is private and its variants cannot be reexported + //~^ ERROR enum is private and its variants cannot be re-exported enum Professor { Adjunct, diff --git a/src/test/compile-fail/issue-46438.rs b/src/test/compile-fail/issue-46438.rs new file mode 100644 index 00000000000..d84b5813385 --- /dev/null +++ b/src/test/compile-fail/issue-46438.rs @@ -0,0 +1,23 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +macro_rules! m { + ($my_type: ty) => { + impl $my_type for u8 {} + } +} + +trait Trait {} + +m!(Tr); + +m!(&'static u8); //~ ERROR expected a trait, found type + +fn main() {} diff --git a/src/test/compile-fail/lint-ctypes.rs b/src/test/compile-fail/lint-ctypes.rs index fd825563eba..c22239dee0a 100644 --- a/src/test/compile-fail/lint-ctypes.rs +++ b/src/test/compile-fail/lint-ctypes.rs @@ -9,10 +9,12 @@ // except according to those terms. #![deny(improper_ctypes)] -#![feature(libc, i128_type)] +#![feature(libc, i128_type, repr_transparent)] extern crate libc; +use std::marker::PhantomData; + trait Mirror { type It: ?Sized; } impl<T: ?Sized> Mirror for T { type It = Self; } #[repr(C)] @@ -28,6 +30,22 @@ pub type RustFn = fn(); pub type RustBadRet = extern fn() -> Box<u32>; pub type CVoidRet = (); pub struct Foo; +#[repr(transparent)] +pub struct TransparentI128(i128); +#[repr(transparent)] +pub struct TransparentStr(&'static str); +#[repr(transparent)] +pub struct TransparentBadFn(RustBadRet); +#[repr(transparent)] +pub struct TransparentInt(u32); +#[repr(transparent)] +pub struct TransparentRef<'a>(&'a TransparentInt); +#[repr(transparent)] +pub struct TransparentLifetime<'a>(*const u8, PhantomData<&'a ()>); +#[repr(transparent)] +pub struct TransparentUnit<U>(f32, PhantomData<U>); +#[repr(transparent)] +pub struct TransparentCustomZst(i32, ZeroSize); #[repr(C)] pub struct ZeroSizeWithPhantomData(::std::marker::PhantomData<i32>); @@ -51,6 +69,9 @@ extern { pub fn fn_type(p: RustFn); //~ ERROR found function pointer with Rust pub fn fn_type2(p: fn()); //~ ERROR found function pointer with Rust pub fn fn_contained(p: RustBadRet); //~ ERROR: found struct without + pub fn transparent_i128(p: TransparentI128); //~ ERROR: found Rust type `i128` + pub fn transparent_str(p: TransparentStr); //~ ERROR: found Rust type `str` + pub fn transparent_fn(p: TransparentBadFn); //~ ERROR: found struct without pub fn good3(fptr: Option<extern fn()>); pub fn good4(aptr: &[u8; 4 as usize]); @@ -62,6 +83,11 @@ extern { pub fn good10() -> CVoidRet; pub fn good11(size: isize); pub fn good12(size: usize); + pub fn good13(n: TransparentInt); + pub fn good14(p: TransparentRef); + pub fn good15(p: TransparentLifetime); + pub fn good16(p: TransparentUnit<ZeroSize>); + pub fn good17(p: TransparentCustomZst); } #[cfg(not(target_arch = "wasm32"))] diff --git a/src/test/compile-fail/lint-unnecessary-parens.rs b/src/test/compile-fail/lint-unnecessary-parens.rs index b5eac73a55d..7cd0a6bbf0f 100644 --- a/src/test/compile-fail/lint-unnecessary-parens.rs +++ b/src/test/compile-fail/lint-unnecessary-parens.rs @@ -13,19 +13,19 @@ #[derive(Eq, PartialEq)] struct X { y: bool } impl X { - fn foo(&self) -> bool { self.y } + fn foo(&self, conjunct: bool) -> bool { self.y && conjunct } } fn foo() -> isize { return (1); //~ ERROR unnecessary parentheses around `return` value } -fn bar() -> X { - return (X { y: true }); //~ ERROR unnecessary parentheses around `return` value +fn bar(y: bool) -> X { + return (X { y }); //~ ERROR unnecessary parentheses around `return` value } fn main() { foo(); - bar(); + bar((true)); //~ ERROR unnecessary parentheses around function argument if (true) {} //~ ERROR unnecessary parentheses around `if` condition while (true) {} //~ ERROR unnecessary parentheses around `while` condition @@ -40,13 +40,15 @@ fn main() { if (X { y: true } == v) {} if (X { y: false }.y) {} - while (X { y: false }.foo()) {} + while (X { y: false }.foo(true)) {} while (true | X { y: false }.y) {} match (X { y: false }) { _ => {} } + X { y: false }.foo((true)); //~ ERROR unnecessary parentheses around method argument + let mut _a = (0); //~ ERROR unnecessary parentheses around assigned value _a = (0); //~ ERROR unnecessary parentheses around assigned value _a += (1); //~ ERROR unnecessary parentheses around assigned value diff --git a/src/test/compile-fail/lint-unused-extern-crate.rs b/src/test/compile-fail/lint-unused-extern-crate.rs index a3cfa134983..8f0b53fd599 100644 --- a/src/test/compile-fail/lint-unused-extern-crate.rs +++ b/src/test/compile-fail/lint-unused-extern-crate.rs @@ -20,7 +20,7 @@ extern crate lint_unused_extern_crate5; //~ ERROR: unused extern crate -pub extern crate lint_unused_extern_crate4; // no error, it is reexported +pub extern crate lint_unused_extern_crate4; // no error, it is re-exported extern crate lint_unused_extern_crate3; // no error, it is used diff --git a/src/test/compile-fail/macro-reexport-malformed-1.rs b/src/test/compile-fail/macro-reexport-malformed-1.rs index a2778a83130..36a6fce00a1 100644 --- a/src/test/compile-fail/macro-reexport-malformed-1.rs +++ b/src/test/compile-fail/macro-reexport-malformed-1.rs @@ -12,5 +12,5 @@ #![feature(macro_reexport)] #[allow(unused_extern_crates)] -#[macro_reexport] //~ ERROR bad macro reexport +#[macro_reexport] //~ ERROR bad macro re-export extern crate std; diff --git a/src/test/compile-fail/macro-reexport-malformed-2.rs b/src/test/compile-fail/macro-reexport-malformed-2.rs index c5af9e3799d..5f741d010de 100644 --- a/src/test/compile-fail/macro-reexport-malformed-2.rs +++ b/src/test/compile-fail/macro-reexport-malformed-2.rs @@ -12,5 +12,5 @@ #![feature(macro_reexport)] #[allow(unused_extern_crates)] -#[macro_reexport="foo"] //~ ERROR bad macro reexport +#[macro_reexport="foo"] //~ ERROR bad macro re-export extern crate std; diff --git a/src/test/compile-fail/macro-reexport-malformed-3.rs b/src/test/compile-fail/macro-reexport-malformed-3.rs index d72d1ee004e..1a7e3b918cd 100644 --- a/src/test/compile-fail/macro-reexport-malformed-3.rs +++ b/src/test/compile-fail/macro-reexport-malformed-3.rs @@ -12,5 +12,5 @@ #![feature(macro_reexport)] #[allow(unused_extern_crates)] -#[macro_reexport(foo="bar")] //~ ERROR bad macro reexport +#[macro_reexport(foo="bar")] //~ ERROR bad macro re-export extern crate std; diff --git a/src/test/compile-fail/macro-reexport-undef.rs b/src/test/compile-fail/macro-reexport-undef.rs index 5bb0b8759f4..50ac89e49e0 100644 --- a/src/test/compile-fail/macro-reexport-undef.rs +++ b/src/test/compile-fail/macro-reexport-undef.rs @@ -13,7 +13,7 @@ #![feature(macro_reexport)] #[macro_use(macro_two)] -#[macro_reexport(no_way)] //~ ERROR reexported macro not found +#[macro_reexport(no_way)] //~ ERROR re-exported macro not found extern crate two_macros; pub fn main() { diff --git a/src/test/compile-fail/object-lifetime-default-from-box-error.rs b/src/test/compile-fail/object-lifetime-default-from-box-error.rs index c50f425b2c0..b253612bc32 100644 --- a/src/test/compile-fail/object-lifetime-default-from-box-error.rs +++ b/src/test/compile-fail/object-lifetime-default-from-box-error.rs @@ -25,7 +25,7 @@ fn load(ss: &mut SomeStruct) -> Box<SomeTrait> { // `Box<SomeTrait>` defaults to a `'static` bound, so this return // is illegal. - ss.r //~ ERROR cannot infer an appropriate lifetime + ss.r //~ ERROR explicit lifetime required in the type of `ss` [E0621] } fn store(ss: &mut SomeStruct, b: Box<SomeTrait>) { diff --git a/src/test/compile-fail/phantom-oibit.rs b/src/test/compile-fail/phantom-oibit.rs index 52bc0126612..e36c4835ca1 100644 --- a/src/test/compile-fail/phantom-oibit.rs +++ b/src/test/compile-fail/phantom-oibit.rs @@ -9,8 +9,7 @@ // except according to those terms. // Ensure that OIBIT checks `T` when it encounters a `PhantomData<T>` field, instead of checking -// the `PhantomData<T>` type itself (which almost always implements a "default" trait -// (`impl Trait for ..`)) +// the `PhantomData<T>` type itself (which almost always implements an auto trait) #![feature(optin_builtin_traits)] diff --git a/src/test/compile-fail/privacy/legacy-ctor-visibility.rs b/src/test/compile-fail/privacy/legacy-ctor-visibility.rs index fb65af230ac..95144916fd7 100644 --- a/src/test/compile-fail/privacy/legacy-ctor-visibility.rs +++ b/src/test/compile-fail/privacy/legacy-ctor-visibility.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// ignore-tidy-linelength + #![allow(unused)] use m::S; @@ -19,7 +21,7 @@ mod m { use S; fn f() { S(10); - //~^ ERROR private struct constructors are not usable through reexports in outer modules + //~^ ERROR private struct constructors are not usable through re-exports in outer modules //~| WARN this was previously accepted } } diff --git a/src/test/compile-fail/privacy/restricted/test.rs b/src/test/compile-fail/privacy/restricted/test.rs index 7f076ebf287..8c1d609e244 100644 --- a/src/test/compile-fail/privacy/restricted/test.rs +++ b/src/test/compile-fail/privacy/restricted/test.rs @@ -28,7 +28,7 @@ mod foo { fn f() { use foo::bar::S; pub(self) use foo::bar::f; // ok - pub(super) use foo::bar::f as g; //~ ERROR cannot be reexported + pub(super) use foo::bar::f as g; //~ ERROR cannot be re-exported S::default().x; // ok S::default().f(); // ok S::g(); // ok diff --git a/src/test/compile-fail/private-in-public-ill-formed.rs b/src/test/compile-fail/private-in-public-ill-formed.rs index 4e10614bf62..480406054ad 100644 --- a/src/test/compile-fail/private-in-public-ill-formed.rs +++ b/src/test/compile-fail/private-in-public-ill-formed.rs @@ -21,7 +21,7 @@ mod aliases_pub { type AssocAlias = m::Pub3; } - impl (<Priv as PrivTr>::AssocAlias) { //~ ERROR no base type found for inherent implementation + impl <Priv as PrivTr>::AssocAlias { //~ ERROR no base type found for inherent implementation pub fn f(arg: Priv) {} // private type `aliases_pub::Priv` in public interface } } @@ -37,7 +37,7 @@ mod aliases_priv { type AssocAlias = Priv3; } - impl (<Priv as PrivTr>::AssocAlias) { //~ ERROR no base type found for inherent implementation + impl <Priv as PrivTr>::AssocAlias { //~ ERROR no base type found for inherent implementation pub fn f(arg: Priv) {} // OK } } diff --git a/src/test/compile-fail/private-variant-reexport.rs b/src/test/compile-fail/private-variant-reexport.rs index 1280aba3076..5d770f88155 100644 --- a/src/test/compile-fail/private-variant-reexport.rs +++ b/src/test/compile-fail/private-variant-reexport.rs @@ -9,19 +9,19 @@ // except according to those terms. mod m1 { - pub use ::E::V; //~ ERROR variant `V` is private and cannot be reexported + pub use ::E::V; //~ ERROR variant `V` is private and cannot be re-exported } mod m2 { - pub use ::E::{V}; //~ ERROR variant `V` is private and cannot be reexported + pub use ::E::{V}; //~ ERROR variant `V` is private and cannot be re-exported } mod m3 { - pub use ::E::V::{self}; //~ ERROR variant `V` is private and cannot be reexported + pub use ::E::V::{self}; //~ ERROR variant `V` is private and cannot be re-exported } mod m4 { - pub use ::E::*; //~ ERROR enum is private and its variants cannot be reexported + pub use ::E::*; //~ ERROR enum is private and its variants cannot be re-exported } enum E { V } diff --git a/src/test/compile-fail/pub-reexport-priv-extern-crate.rs b/src/test/compile-fail/pub-reexport-priv-extern-crate.rs index 5479be54533..2e71e007e9e 100644 --- a/src/test/compile-fail/pub-reexport-priv-extern-crate.rs +++ b/src/test/compile-fail/pub-reexport-priv-extern-crate.rs @@ -11,7 +11,7 @@ #![allow(unused)] extern crate core; -pub use core as reexported_core; //~ ERROR `core` is private, and cannot be reexported +pub use core as reexported_core; //~ ERROR `core` is private, and cannot be re-exported //~^ WARN this was previously accepted mod foo1 { @@ -19,7 +19,7 @@ mod foo1 { } mod foo2 { - use foo1::core; //~ ERROR `core` is private, and cannot be reexported + use foo1::core; //~ ERROR `core` is private, and cannot be re-exported //~^ WARN this was previously accepted pub mod bar { extern crate core; @@ -27,7 +27,7 @@ mod foo2 { } mod baz { - pub use foo2::bar::core; //~ ERROR `core` is private, and cannot be reexported + pub use foo2::bar::core; //~ ERROR `core` is private, and cannot be re-exported //~^ WARN this was previously accepted } diff --git a/src/test/compile-fail/region-object-lifetime-in-coercion.rs b/src/test/compile-fail/region-object-lifetime-in-coercion.rs index 687b2c344a3..5bf397ab383 100644 --- a/src/test/compile-fail/region-object-lifetime-in-coercion.rs +++ b/src/test/compile-fail/region-object-lifetime-in-coercion.rs @@ -16,20 +16,20 @@ impl<'a> Foo for &'a [u8] {} fn a(v: &[u8]) -> Box<Foo + 'static> { let x: Box<Foo + 'static> = Box::new(v); - //~^ ERROR cannot infer an appropriate lifetime due to conflicting + //~^ ERROR explicit lifetime required in the type of `v` [E0621] x } fn b(v: &[u8]) -> Box<Foo + 'static> { Box::new(v) - //~^ ERROR cannot infer an appropriate lifetime due to conflicting + //~^ ERROR explicit lifetime required in the type of `v` [E0621] } fn c(v: &[u8]) -> Box<Foo> { // same as previous case due to RFC 599 Box::new(v) - //~^ ERROR cannot infer an appropriate lifetime due to conflicting + //~^ ERROR explicit lifetime required in the type of `v` [E0621] } fn d<'a,'b>(v: &'a [u8]) -> Box<Foo+'b> { diff --git a/src/test/compile-fail/regions-proc-bound-capture.rs b/src/test/compile-fail/regions-proc-bound-capture.rs index 17fd55b031b..dd7b2bf9635 100644 --- a/src/test/compile-fail/regions-proc-bound-capture.rs +++ b/src/test/compile-fail/regions-proc-bound-capture.rs @@ -16,7 +16,7 @@ fn borrowed_proc<'a>(x: &'a isize) -> Box<FnMut()->(isize) + 'a> { fn static_proc(x: &isize) -> Box<FnMut()->(isize) + 'static> { // This is illegal, because the region bound on `proc` is 'static. - Box::new(move|| { *x }) //~ ERROR cannot infer an appropriate lifetime + Box::new(move|| { *x }) //~ ERROR explicit lifetime required in the type of `x` [E0621] } fn main() { } diff --git a/src/test/compile-fail/regions-static-bound.rs b/src/test/compile-fail/regions-static-bound.rs index a217cc9ebfa..13f93090fbb 100644 --- a/src/test/compile-fail/regions-static-bound.rs +++ b/src/test/compile-fail/regions-static-bound.rs @@ -22,12 +22,12 @@ fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a { } fn error(u: &(), v: &()) { - static_id(&u); //[ll]~ ERROR cannot infer an appropriate lifetime + static_id(&u); //[ll]~ ERROR explicit lifetime required in the type of `u` [E0621] //[nll]~^ WARNING not reporting region error due to -Znll - //[nll]~| ERROR free region `` does not outlive free region `'static` - static_id_indirect(&v); //[ll]~ ERROR cannot infer an appropriate lifetime + //[nll]~| ERROR explicit lifetime required in the type of `u` [E0621] + static_id_indirect(&v); //[ll]~ ERROR explicit lifetime required in the type of `v` [E0621] //[nll]~^ WARNING not reporting region error due to -Znll - //[nll]~| ERROR free region `` does not outlive free region `'static` + //[nll]~| ERROR explicit lifetime required in the type of `v` [E0621] } fn main() {} diff --git a/src/test/compile-fail/repr-transparent-other-items.rs b/src/test/compile-fail/repr-transparent-other-items.rs new file mode 100644 index 00000000000..cf0870866c7 --- /dev/null +++ b/src/test/compile-fail/repr-transparent-other-items.rs @@ -0,0 +1,40 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(repr_transparent)] + +// See also repr-transparent.rs + +#[repr(transparent)] //~ ERROR unsupported representation for zero-variant enum +enum Void {} //~| ERROR should be applied to struct + +#[repr(transparent)] //~ ERROR should be applied to struct +enum FieldlessEnum { + Foo, + Bar, +} + +#[repr(transparent)] //~ ERROR should be applied to struct +enum Enum { + Foo(String), + Bar(u32), +} + +#[repr(transparent)] //~ ERROR should be applied to struct +union Foo { + u: u32, + s: i32 +} + +#[repr(transparent)] //~ ERROR should be applied to struct +fn cant_repr_this() {} + +#[repr(transparent)] //~ ERROR should be applied to struct +static CANT_REPR_THIS: u32 = 0; diff --git a/src/test/compile-fail/repr-transparent-other-reprs.rs b/src/test/compile-fail/repr-transparent-other-reprs.rs new file mode 100644 index 00000000000..7b91a6f68e3 --- /dev/null +++ b/src/test/compile-fail/repr-transparent-other-reprs.rs @@ -0,0 +1,28 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(repr_transparent, repr_align, attr_literals)] + +// See also repr-transparent.rs + +#[repr(transparent, C)] //~ ERROR cannot have other repr +struct TransparentPlusC { + ptr: *const u8 +} + +#[repr(transparent, packed)] //~ ERROR cannot have other repr +struct TransparentPlusPacked(*const u8); + +#[repr(transparent, align(2))] //~ ERROR cannot have other repr +struct TransparentPlusAlign(u8); + +#[repr(transparent)] //~ ERROR cannot have other repr +#[repr(C)] +struct SeparateAttributes(*mut u8); diff --git a/src/test/compile-fail/repr-transparent.rs b/src/test/compile-fail/repr-transparent.rs new file mode 100644 index 00000000000..b5e6a0fa0b1 --- /dev/null +++ b/src/test/compile-fail/repr-transparent.rs @@ -0,0 +1,51 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// This file tests repr(transparent)-related errors reported during typeck. Other errors +// that are reported earlier and therefore preempt these are tested in: +// - repr-transparent-other-reprs.rs +// - repr-transparent-other-items.rs + +#![feature(repr_align, attr_literals)] +#![feature(repr_transparent)] + +use std::marker::PhantomData; + +#[repr(transparent)] +struct NoFields; //~ ERROR needs exactly one non-zero-sized field + +#[repr(transparent)] +struct ContainsOnlyZst(()); //~ ERROR needs exactly one non-zero-sized field + +#[repr(transparent)] +struct ContainsOnlyZstArray([bool; 0]); //~ ERROR needs exactly one non-zero-sized field + +#[repr(transparent)] +struct ContainsMultipleZst(PhantomData<*const i32>, NoFields); +//~^ ERROR needs exactly one non-zero-sized field + +#[repr(transparent)] +struct MultipleNonZst(u8, u8); //~ ERROR needs exactly one non-zero-sized field + +trait Mirror { type It: ?Sized; } +impl<T: ?Sized> Mirror for T { type It = Self; } + +#[repr(transparent)] +pub struct StructWithProjection(f32, <f32 as Mirror>::It); +//~^ ERROR needs exactly one non-zero-sized field + +#[repr(transparent)] +struct NontrivialAlignZst(u32, [u16; 0]); //~ ERROR alignment larger than 1 + +#[repr(align(32))] +struct ZstAlign32<T>(PhantomData<T>); + +#[repr(transparent)] +struct GenericAlign<T>(ZstAlign32<T>, u32); //~ ERROR alignment larger than 1 diff --git a/src/test/compile-fail/specialization/defaultimpl/validation.rs b/src/test/compile-fail/specialization/defaultimpl/validation.rs new file mode 100644 index 00000000000..26b8b737f34 --- /dev/null +++ b/src/test/compile-fail/specialization/defaultimpl/validation.rs @@ -0,0 +1,23 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(optin_builtin_traits)] +#![feature(specialization)] + +struct S; +struct Z; + +default impl S {} //~ ERROR inherent impls cannot be default + +default unsafe impl Send for S {} //~ ERROR impls of auto traits cannot be default +default impl !Send for Z {} //~ ERROR impls of auto traits cannot be default + +trait Tr {} +default impl !Tr for S {} //~ ERROR negative impls are only allowed for auto traits diff --git a/src/test/compile-fail/syntax-trait-polarity-feature-gate.rs b/src/test/compile-fail/syntax-trait-polarity-feature-gate.rs index a7ca5e3bf09..8d5e89cc66f 100644 --- a/src/test/compile-fail/syntax-trait-polarity-feature-gate.rs +++ b/src/test/compile-fail/syntax-trait-polarity-feature-gate.rs @@ -14,7 +14,7 @@ struct TestType; trait TestTrait {} -unsafe impl !Send for TestType {} +impl !Send for TestType {} //~^ ERROR negative trait bounds fn main() {} diff --git a/src/test/parse-fail/syntax-trait-polarity.rs b/src/test/compile-fail/syntax-trait-polarity.rs index 1971ffeaf26..1a5d058cb9a 100644 --- a/src/test/parse-fail/syntax-trait-polarity.rs +++ b/src/test/compile-fail/syntax-trait-polarity.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: -Z parse-only -Z continue-parse-after-error - #![feature(optin_builtin_traits)] use std::marker::Send; @@ -17,19 +15,23 @@ use std::marker::Send; struct TestType; impl !TestType {} -//~^ ERROR inherent implementation can't be negated +//~^ ERROR inherent impls cannot be negative trait TestTrait {} unsafe impl !Send for TestType {} +//~^ ERROR negative impls cannot be unsafe impl !TestTrait for TestType {} +//~^ ERROR negative impls are only allowed for auto traits -struct TestType2<T>; +struct TestType2<T>(T); impl<T> !TestType2<T> {} -//~^ ERROR inherent implementation can't be negated +//~^ ERROR inherent impls cannot be negative unsafe impl<T> !Send for TestType2<T> {} +//~^ ERROR negative impls cannot be unsafe impl<T> !TestTrait for TestType2<T> {} +//~^ ERROR negative impls are only allowed for auto traits fn main() {} diff --git a/src/test/compile-fail/trait-safety-inherent-impl.rs b/src/test/compile-fail/trait-safety-inherent-impl.rs index 285d4c1ba8d..059fdc100c9 100644 --- a/src/test/compile-fail/trait-safety-inherent-impl.rs +++ b/src/test/compile-fail/trait-safety-inherent-impl.rs @@ -12,7 +12,7 @@ struct SomeStruct; -unsafe impl SomeStruct { //~ ERROR inherent impls cannot be declared as unsafe +unsafe impl SomeStruct { //~ ERROR inherent impls cannot be unsafe fn foo(self) { } } diff --git a/src/test/compile-fail/typeck-negative-impls-builtin.rs b/src/test/compile-fail/typeck-negative-impls-builtin.rs index 57a394dc7f1..d6d8fb6235d 100644 --- a/src/test/compile-fail/typeck-negative-impls-builtin.rs +++ b/src/test/compile-fail/typeck-negative-impls-builtin.rs @@ -17,6 +17,6 @@ trait TestTrait { } impl !TestTrait for TestType {} -//~^ ERROR negative impls are only allowed for traits with default impls (e.g., `Send` and `Sync`) +//~^ ERROR negative impls are only allowed for auto traits (e.g., `Send` and `Sync`) fn main() {} diff --git a/src/test/incremental-fulldeps/auxiliary/incremental_proc_macro_aux.rs b/src/test/incremental-fulldeps/auxiliary/incremental_proc_macro_aux.rs new file mode 100644 index 00000000000..e9f9ba86f23 --- /dev/null +++ b/src/test/incremental-fulldeps/auxiliary/incremental_proc_macro_aux.rs @@ -0,0 +1,31 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +// Add a function to shift DefIndex of registrar function +#[cfg(cfail2)] +fn foo() {} + +#[proc_macro_derive(IncrementalMacro)] +pub fn derive(input: TokenStream) -> TokenStream { + #[cfg(cfail2)] + { + foo(); + } + + "".parse().unwrap() +} diff --git a/src/test/incremental-fulldeps/incremental_proc_macro.rs b/src/test/incremental-fulldeps/incremental_proc_macro.rs new file mode 100644 index 00000000000..e4345070853 --- /dev/null +++ b/src/test/incremental-fulldeps/incremental_proc_macro.rs @@ -0,0 +1,27 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:incremental_proc_macro_aux.rs +// ignore-stage1 +// revisions: cfail1 cfail2 +// must-compile-successfully + +// This test makes sure that we still find the proc-macro registrar function +// when we compile proc-macros incrementally (see #47292). + +#![crate_type = "rlib"] + +#[macro_use] +extern crate incremental_proc_macro_aux; + +#[derive(IncrementalMacro)] +pub struct Foo { + x: u32 +} diff --git a/src/test/parse-fail/impl-qpath.rs b/src/test/parse-fail/impl-qpath.rs new file mode 100644 index 00000000000..48dd888b2e5 --- /dev/null +++ b/src/test/parse-fail/impl-qpath.rs @@ -0,0 +1,18 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -Z parse-only + +impl <*const u8>::AssocTy {} // OK +impl <Type as Trait>::AssocTy {} // OK +impl <'a + Trait>::AssocTy {} // OK +impl <<Type>::AssocTy>::AssocTy {} // OK + +FAIL //~ ERROR diff --git a/src/test/parse-fail/trait-bounds-not-on-impl.rs b/src/test/parse-fail/trait-bounds-not-on-impl.rs index b7dcc8a8b3b..7cd2774fe39 100644 --- a/src/test/parse-fail/trait-bounds-not-on-impl.rs +++ b/src/test/parse-fail/trait-bounds-not-on-impl.rs @@ -15,9 +15,7 @@ trait Foo { struct Bar; -impl Foo + Owned for Bar { -//~^ ERROR not a trait -//~^^ ERROR expected one of `where` or `{`, found `Bar` +impl Foo + Owned for Bar { //~ ERROR expected a trait, found type } fn main() { } diff --git a/src/test/parse-fail/where_with_bound.rs b/src/test/parse-fail/where_with_bound.rs index cb57500df79..2948619ccd0 100644 --- a/src/test/parse-fail/where_with_bound.rs +++ b/src/test/parse-fail/where_with_bound.rs @@ -11,6 +11,6 @@ // compile-flags: -Z parse-only fn foo<T>() where <T>::Item: ToString, T: Iterator { } - //~^ syntax `where<T>` is reserved for future use +//~^ ERROR generic parameters on `where` clauses are reserved for future use fn main() {} diff --git a/src/test/run-make/hotplug_codegen_backend/Makefile b/src/test/run-make/hotplug_codegen_backend/Makefile new file mode 100644 index 00000000000..9a216d1d81f --- /dev/null +++ b/src/test/run-make/hotplug_codegen_backend/Makefile @@ -0,0 +1,9 @@ +include ../tools.mk + +all: + /bin/echo || exit 0 # This test requires /bin/echo to exist + $(RUSTC) the_backend.rs --crate-name the_backend --crate-type dylib \ + -o $(TMPDIR)/the_backend.dylib + $(RUSTC) some_crate.rs --crate-name some_crate --crate-type bin -o $(TMPDIR)/some_crate \ + -Z codegen-backend=$(TMPDIR)/the_backend.dylib -Z unstable-options + grep -x "This has been \"compiled\" succesfully." $(TMPDIR)/some_crate diff --git a/src/test/run-make/hotplug_codegen_backend/some_crate.rs b/src/test/run-make/hotplug_codegen_backend/some_crate.rs new file mode 100644 index 00000000000..26ffce01b2e --- /dev/null +++ b/src/test/run-make/hotplug_codegen_backend/some_crate.rs @@ -0,0 +1,13 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + ::std::process::exit(1); +} diff --git a/src/test/run-make/hotplug_codegen_backend/the_backend.rs b/src/test/run-make/hotplug_codegen_backend/the_backend.rs new file mode 100644 index 00000000000..0de404ed249 --- /dev/null +++ b/src/test/run-make/hotplug_codegen_backend/the_backend.rs @@ -0,0 +1,82 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(rustc_private)] + +extern crate syntax; +extern crate rustc; +extern crate rustc_trans_utils; + +use std::any::Any; +use std::sync::mpsc; +use syntax::symbol::Symbol; +use rustc::session::{Session, CompileIncomplete}; +use rustc::session::config::OutputFilenames; +use rustc::ty::TyCtxt; +use rustc::ty::maps::Providers; +use rustc::middle::cstore::MetadataLoader; +use rustc::dep_graph::DepGraph; +use rustc_trans_utils::trans_crate::{TransCrate, MetadataOnlyTransCrate}; + +struct TheBackend(Box<TransCrate>); + +impl TransCrate for TheBackend { + fn metadata_loader(&self) -> Box<MetadataLoader> { + self.0.metadata_loader() + } + + fn provide(&self, providers: &mut Providers) { + self.0.provide(providers); + } + + fn provide_extern(&self, providers: &mut Providers) { + self.0.provide_extern(providers); + } + + fn trans_crate<'a, 'tcx>( + &self, + tcx: TyCtxt<'a, 'tcx, 'tcx>, + _rx: mpsc::Receiver<Box<Any + Send>> + ) -> Box<Any> { + use rustc::hir::def_id::LOCAL_CRATE; + + Box::new(tcx.crate_name(LOCAL_CRATE) as Symbol) + } + + fn join_trans_and_link( + &self, + trans: Box<Any>, + sess: &Session, + _dep_graph: &DepGraph, + outputs: &OutputFilenames, + ) -> Result<(), CompileIncomplete> { + use std::io::Write; + use rustc::session::config::CrateType; + use rustc_trans_utils::link::out_filename; + let crate_name = trans.downcast::<Symbol>() + .expect("in join_trans_and_link: trans is not a Symbol"); + for &crate_type in sess.opts.crate_types.iter() { + if crate_type != CrateType::CrateTypeExecutable { + sess.fatal(&format!("Crate type is {:?}", crate_type)); + } + let output_name = + out_filename(sess, crate_type, &outputs, &*crate_name.as_str()); + let mut out_file = ::std::fs::File::create(output_name).unwrap(); + write!(out_file, "This has been \"compiled\" succesfully.").unwrap(); + } + Ok(()) + } +} + +/// This is the entrypoint for a hot plugged rustc_trans +#[no_mangle] +pub fn __rustc_codegen_backend(sess: &Session) -> Box<TransCrate> { + Box::new(TheBackend(MetadataOnlyTransCrate::new(sess))) +} diff --git a/src/test/run-make/issue-19371/foo.rs b/src/test/run-make/issue-19371/foo.rs index f0ab1d5dc0f..c360dde618e 100644 --- a/src/test/run-make/issue-19371/foo.rs +++ b/src/test/run-make/issue-19371/foo.rs @@ -16,6 +16,7 @@ extern crate rustc_lint; extern crate rustc_metadata; extern crate rustc_errors; extern crate rustc_trans; +extern crate rustc_trans_utils; extern crate syntax; use rustc::session::{build_session, Session}; @@ -25,6 +26,7 @@ use rustc_driver::driver::{compile_input, CompileController}; use rustc_metadata::cstore::CStore; use rustc_errors::registry::Registry; use syntax::codemap::FileName; +use rustc_trans_utils::trans_crate::TransCrate; use std::path::PathBuf; use std::rc::Rc; @@ -51,7 +53,7 @@ fn main() { compile(src.to_string(), tmpdir.join("out"), sysroot.clone()); } -fn basic_sess(sysroot: PathBuf) -> (Session, Rc<CStore>) { +fn basic_sess(sysroot: PathBuf) -> (Session, Rc<CStore>, Box<TransCrate>) { let mut opts = basic_options(); opts.output_types = OutputTypes::new(&[(OutputType::Exe, None)]); opts.maybe_sysroot = Some(sysroot); @@ -60,16 +62,26 @@ fn basic_sess(sysroot: PathBuf) -> (Session, Rc<CStore>) { } let descriptions = Registry::new(&rustc::DIAGNOSTICS); - let cstore = Rc::new(CStore::new(Box::new(rustc_trans::LlvmMetadataLoader))); let sess = build_session(opts, None, descriptions); - rustc_trans::init(&sess); + let trans = rustc_trans::LlvmTransCrate::new(&sess); + let cstore = Rc::new(CStore::new(trans.metadata_loader())); rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); - (sess, cstore) + (sess, cstore, trans) } fn compile(code: String, output: PathBuf, sysroot: PathBuf) { - let (sess, cstore) = basic_sess(sysroot); + let (sess, cstore, trans) = basic_sess(sysroot); let control = CompileController::basic(); let input = Input::Str { name: FileName::Anon, input: code }; - let _ = compile_input(&sess, &cstore, &None, &input, &None, &Some(output), None, &control); + let _ = compile_input( + trans, + &sess, + &cstore, + &None, + &input, + &None, + &Some(output), + None, + &control + ); } diff --git a/src/test/run-make/llvm-phase/Makefile b/src/test/run-make/llvm-phase/Makefile deleted file mode 100644 index 6a8e1728b20..00000000000 --- a/src/test/run-make/llvm-phase/Makefile +++ /dev/null @@ -1,5 +0,0 @@ --include ../tools.mk - -all: - $(RUSTC) test.rs - $(call RUN,test $(RUSTC)) diff --git a/src/test/run-make/llvm-phase/test.rs b/src/test/run-make/llvm-phase/test.rs deleted file mode 100644 index 2ff4593a801..00000000000 --- a/src/test/run-make/llvm-phase/test.rs +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(plugin, rustc_private, box_syntax)] - -extern crate rustc; -extern crate rustc_driver; -extern crate rustc_llvm; -extern crate rustc_trans; -#[macro_use] extern crate syntax; -extern crate getopts; - -use rustc_driver::{CompilerCalls, Compilation}; -use rustc_driver::driver::CompileController; -use rustc_trans::ModuleSource; -use rustc::session::Session; -use syntax::codemap::FileLoader; -use std::env; -use std::io; -use std::path::{PathBuf, Path}; - -struct JitLoader; - -impl FileLoader for JitLoader { - fn file_exists(&self, _: &Path) -> bool { true } - fn abs_path(&self, _: &Path) -> Option<PathBuf> { None } - fn read_file(&self, _: &Path) -> io::Result<String> { - Ok(r#" -#[no_mangle] -pub fn test_add(a: i32, b: i32) -> i32 { a + b } -"#.to_string()) - } -} - -#[derive(Copy, Clone)] -struct JitCalls; - -impl<'a> CompilerCalls<'a> for JitCalls { - fn build_controller(&mut self, - _: &Session, - _: &getopts::Matches) - -> CompileController<'a> { - let mut cc = CompileController::basic(); - cc.after_llvm.stop = Compilation::Stop; - cc.after_llvm.run_callback_on_error = true; - cc.after_llvm.callback = Box::new(|state| { - state.session.abort_if_errors(); - let trans = state.trans.unwrap(); - assert_eq!(trans.modules.len(), 1); - println!("name of compiled module = {}", trans.modules[0].name); - }); - cc - } -} - -fn main() { - use rustc_driver; - - let mut path = match std::env::args().nth(2) { - Some(path) => PathBuf::from(&path), - None => panic!("missing rustc path") - }; - - // Remove two segments from rustc path to get sysroot. - path.pop(); - path.pop(); - - let mut args: Vec<String> = - format!("_ _ --sysroot {} --crate-type dylib", path.to_str().unwrap()) - .split(' ').map(|s| s.to_string()).collect(); - args.push("--out-dir".to_string()); - args.push(env::var("TMPDIR").unwrap()); - args.push("-Ccodegen-units=1".to_string()); - - let (result, _) = rustc_driver::run_compiler( - &args, &mut JitCalls, Some(box JitLoader), None); - if let Err(n) = result { - panic!("Error {:?}", n); - } -} diff --git a/src/test/run-make/long-linker-command-lines-cmd-exe/Makefile b/src/test/run-make/long-linker-command-lines-cmd-exe/Makefile new file mode 100644 index 00000000000..debe9e93824 --- /dev/null +++ b/src/test/run-make/long-linker-command-lines-cmd-exe/Makefile @@ -0,0 +1,6 @@ +-include ../tools.mk + +all: + $(RUSTC) foo.rs -g + cp foo.bat $(TMPDIR)/ + OUT_DIR="$(TMPDIR)" RUSTC="$(RUSTC_ORIGINAL)" $(call RUN,foo) diff --git a/src/test/run-make/long-linker-command-lines-cmd-exe/foo.bat b/src/test/run-make/long-linker-command-lines-cmd-exe/foo.bat new file mode 100644 index 00000000000..a9350f12bbb --- /dev/null +++ b/src/test/run-make/long-linker-command-lines-cmd-exe/foo.bat @@ -0,0 +1 @@ +%MY_LINKER% %* diff --git a/src/test/run-make/long-linker-command-lines-cmd-exe/foo.rs b/src/test/run-make/long-linker-command-lines-cmd-exe/foo.rs new file mode 100644 index 00000000000..f9168a82e22 --- /dev/null +++ b/src/test/run-make/long-linker-command-lines-cmd-exe/foo.rs @@ -0,0 +1,96 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Like the `long-linker-command-lines` test this test attempts to blow +// a command line limit for running the linker. Unlike that test, however, +// this test is testing `cmd.exe` specifically rather than the OS. +// +// Unfortunately `cmd.exe` has a 8192 limit which is relatively small +// in the grand scheme of things and anyone sripting rustc's linker +// is probably using a `*.bat` script and is likely to hit this limit. +// +// This test uses a `foo.bat` script as the linker which just simply +// delegates back to this program. The compiler should use a lower +// limit for arguments before passing everything via `@`, which +// means that everything should still succeed here. + +use std::env; +use std::fs::{self, File}; +use std::io::{BufWriter, Write, Read}; +use std::path::PathBuf; +use std::process::Command; + +fn main() { + if !cfg!(windows) { + return + } + + let tmpdir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); + let ok = tmpdir.join("ok"); + let not_ok = tmpdir.join("not_ok"); + if env::var("YOU_ARE_A_LINKER").is_ok() { + match env::args().find(|a| a.contains("@")) { + Some(file) => { fs::copy(&file[1..], &ok).unwrap(); } + None => { File::create(¬_ok).unwrap(); } + } + return + } + + let rustc = env::var_os("RUSTC").unwrap_or("rustc".into()); + let me = env::current_exe().unwrap(); + let bat = me.parent() + .unwrap() + .join("foo.bat"); + let bat_linker = format!("linker={}", bat.display()); + for i in (1..).map(|i| i * 10) { + println!("attempt: {}", i); + + let file = tmpdir.join("bar.rs"); + let mut f = BufWriter::new(File::create(&file).unwrap()); + let mut lib_name = String::new(); + for _ in 0..i { + lib_name.push_str("foo"); + } + for j in 0..i { + writeln!(f, "#[link(name = \"{}{}\")]", lib_name, j).unwrap(); + } + writeln!(f, "extern {{}}\nfn main() {{}}").unwrap(); + f.into_inner().unwrap(); + + drop(fs::remove_file(&ok)); + drop(fs::remove_file(¬_ok)); + let status = Command::new(&rustc) + .arg(&file) + .arg("-C").arg(&bat_linker) + .arg("--out-dir").arg(&tmpdir) + .env("YOU_ARE_A_LINKER", "1") + .env("MY_LINKER", &me) + .status() + .unwrap(); + + if !status.success() { + panic!("rustc didn't succeed: {}", status); + } + + if !ok.exists() { + assert!(not_ok.exists()); + continue + } + + let mut contents = String::new(); + File::open(&ok).unwrap().read_to_string(&mut contents).unwrap(); + + for j in 0..i { + assert!(contents.contains(&format!("{}{}", lib_name, j))); + } + + break + } +} diff --git a/src/test/run-make/type-mismatch-same-crate-name/crateC.rs b/src/test/run-make/type-mismatch-same-crate-name/crateC.rs index da869d2145f..210bc4c8320 100644 --- a/src/test/run-make/type-mismatch-same-crate-name/crateC.rs +++ b/src/test/run-make/type-mismatch-same-crate-name/crateC.rs @@ -18,7 +18,7 @@ // compile-fail/type-mismatch-same-crate-name.rs // but deals with the case where one of the crates // is only introduced as an indirect dependency. -// and the type is accessed via a reexport. +// and the type is accessed via a re-export. // This is similar to how the error can be introduced // when using cargo's automatic dependency resolution. diff --git a/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs b/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs index d3f921e0878..878d64c3473 100644 --- a/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs +++ b/src/test/run-pass-fulldeps/auxiliary/lint_for_crate.rs @@ -23,26 +23,57 @@ use rustc_plugin::Registry; use rustc::hir; use syntax::attr; -declare_lint!(CRATE_NOT_OKAY, Warn, "crate not marked with #![crate_okay]"); +macro_rules! fake_lint_pass { + ($struct:ident, $lints:expr, $($attr:expr),*) => { + struct $struct; + + impl LintPass for $struct { + fn get_lints(&self) -> LintArray { + $lints + } + } -struct Pass; + impl<'a, 'tcx> LateLintPass<'a, 'tcx> for $struct { + fn check_crate(&mut self, cx: &LateContext, krate: &hir::Crate) { + $( + if !attr::contains_name(&krate.attrs, $attr) { + cx.span_lint(CRATE_NOT_OKAY, krate.span, + &format!("crate is not marked with #![{}]", $attr)); + } + )* + } + } -impl LintPass for Pass { - fn get_lints(&self) -> LintArray { - lint_array!(CRATE_NOT_OKAY) } } -impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { - fn check_crate(&mut self, cx: &LateContext, krate: &hir::Crate) { - if !attr::contains_name(&krate.attrs, "crate_okay") { - cx.span_lint(CRATE_NOT_OKAY, krate.span, - "crate is not marked with #![crate_okay]"); - } - } +declare_lint!(CRATE_NOT_OKAY, Warn, "crate not marked with #![crate_okay]"); +declare_lint!(CRATE_NOT_RED, Warn, "crate not marked with #![crate_red]"); +declare_lint!(CRATE_NOT_BLUE, Warn, "crate not marked with #![crate_blue]"); +declare_lint!(CRATE_NOT_GREY, Warn, "crate not marked with #![crate_grey]"); +declare_lint!(CRATE_NOT_GREEN, Warn, "crate not marked with #![crate_green]"); + +fake_lint_pass! { + PassOkay, + lint_array!(CRATE_NOT_OKAY), // Single lint + "crate_okay" +} + +fake_lint_pass! { + PassRedBlue, + lint_array!(CRATE_NOT_RED, CRATE_NOT_BLUE), // Multiple lints + "crate_red", "crate_blue" +} + +fake_lint_pass! { + PassGreyGreen, + lint_array!(CRATE_NOT_GREY, CRATE_NOT_GREEN, ), // Trailing comma + "crate_grey", "crate_green" } #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry) { - reg.register_late_lint_pass(box Pass); + reg.register_late_lint_pass(box PassOkay); + reg.register_late_lint_pass(box PassRedBlue); + reg.register_late_lint_pass(box PassGreyGreen); } diff --git a/src/test/run-pass-fulldeps/compiler-calls.rs b/src/test/run-pass-fulldeps/compiler-calls.rs index b5c1ee09903..85aa92ce260 100644 --- a/src/test/run-pass-fulldeps/compiler-calls.rs +++ b/src/test/run-pass-fulldeps/compiler-calls.rs @@ -18,6 +18,7 @@ extern crate getopts; extern crate rustc; extern crate rustc_driver; +extern crate rustc_trans_utils; extern crate syntax; extern crate rustc_errors as errors; @@ -25,6 +26,7 @@ use rustc::middle::cstore::CrateStore; use rustc::session::Session; use rustc::session::config::{self, Input}; use rustc_driver::{driver, CompilerCalls, Compilation}; +use rustc_trans_utils::trans_crate::TransCrate; use syntax::ast; use std::path::PathBuf; @@ -46,6 +48,7 @@ impl<'a> CompilerCalls<'a> for TestCalls { } fn late_callback(&mut self, + _: &TransCrate, _: &getopts::Matches, _: &Session, _: &CrateStore, diff --git a/src/test/run-pass-fulldeps/issue-15778-pass.rs b/src/test/run-pass-fulldeps/issue-15778-pass.rs index a767779687a..25800d40e71 100644 --- a/src/test/run-pass-fulldeps/issue-15778-pass.rs +++ b/src/test/run-pass-fulldeps/issue-15778-pass.rs @@ -15,5 +15,9 @@ #![feature(plugin, custom_attribute)] #![plugin(lint_for_crate)] #![crate_okay] +#![crate_blue] +#![crate_red] +#![crate_grey] +#![crate_green] pub fn main() { } diff --git a/src/test/run-pass/allocator-alloc-one.rs b/src/test/run-pass/allocator-alloc-one.rs index 712fa2d6001..eaa5bc90805 100644 --- a/src/test/run-pass/allocator-alloc-one.rs +++ b/src/test/run-pass/allocator-alloc-one.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(allocator_api, unique)] +#![feature(allocator_api, nonnull)] use std::heap::{Heap, Alloc}; diff --git a/src/test/run-pass/generator/yield-subtype.rs b/src/test/run-pass/generator/yield-subtype.rs index 5ea4b1fe93c..7e8a0d1e2b9 100644 --- a/src/test/run-pass/generator/yield-subtype.rs +++ b/src/test/run-pass/generator/yield-subtype.rs @@ -8,6 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// revisions:lexical nll +#![cfg_attr(nll, feature(nll))] + #![feature(generators)] fn bar<'a>() { diff --git a/src/test/run-pass/issue-23433.rs b/src/test/run-pass/issue-23433.rs index aa13d6fad47..7af732f561d 100644 --- a/src/test/run-pass/issue-23433.rs +++ b/src/test/run-pass/issue-23433.rs @@ -10,13 +10,11 @@ // Don't fail if we encounter a NonZero<*T> where T is an unsized type -#![feature(unique)] - -use std::ptr::Unique; +use std::ptr::NonNull; fn main() { let mut a = [0u8; 5]; - let b: Option<Unique<[u8]>> = Some(Unique::from(&mut a)); + let b: Option<NonNull<[u8]>> = Some(NonNull::from(&mut a)); match b { Some(_) => println!("Got `Some`"), None => panic!("Unexpected `None`"), diff --git a/src/test/run-pass/issue-25693.rs b/src/test/run-pass/issue-25693.rs index aee89befda8..0d9dc3cf605 100644 --- a/src/test/run-pass/issue-25693.rs +++ b/src/test/run-pass/issue-25693.rs @@ -8,16 +8,16 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub trait Paramters { type SelfRef; } +pub trait Parameters { type SelfRef; } struct RP<'a> { _marker: std::marker::PhantomData<&'a ()> } struct BP; -impl<'a> Paramters for RP<'a> { type SelfRef = &'a X<RP<'a>>; } -impl Paramters for BP { type SelfRef = Box<X<BP>>; } +impl<'a> Parameters for RP<'a> { type SelfRef = &'a X<RP<'a>>; } +impl Parameters for BP { type SelfRef = Box<X<BP>>; } pub struct Y; -pub enum X<P: Paramters> { +pub enum X<P: Parameters> { Nothing, SameAgain(P::SelfRef, Y) } diff --git a/src/test/run-pass/issue-46920-byte-array-patterns.rs b/src/test/run-pass/issue-46920-byte-array-patterns.rs new file mode 100644 index 00000000000..236f6995c51 --- /dev/null +++ b/src/test/run-pass/issue-46920-byte-array-patterns.rs @@ -0,0 +1,37 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +const CURSOR_PARTITION_LABEL: &'static [u8] = b"partition"; +const CURSOR_EVENT_TYPE_LABEL: &'static [u8] = b"event_type"; +const BYTE_PATTERN: &'static [u8; 5] = b"hello"; + +fn match_slice(x: &[u8]) -> u32 { + match x { + CURSOR_PARTITION_LABEL => 0, + CURSOR_EVENT_TYPE_LABEL => 1, + _ => 2, + } +} + +fn match_array(x: &[u8; 5]) -> bool { + match x { + BYTE_PATTERN => true, + _ => false + } +} + +fn main() { + assert_eq!(match_slice(b"abcde"), 2); + assert_eq!(match_slice(b"event_type"), 1); + assert_eq!(match_slice(b"partition"), 0); + + assert_eq!(match_array(b"hello"), true); + assert_eq!(match_array(b"hella"), false); +} diff --git a/src/test/run-pass/issue-46964.rs b/src/test/run-pass/issue-46964.rs new file mode 100644 index 00000000000..2a82c6dd438 --- /dev/null +++ b/src/test/run-pass/issue-46964.rs @@ -0,0 +1,28 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +mod my_mod { + #[derive(Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash)] + pub struct Name<'a> { + source: &'a str, + } + + pub const JSON: Name = Name { source: "JSON" }; +} + +pub fn crash() -> bool { + match (my_mod::JSON, None) { + (_, Some(my_mod::JSON)) => true, + (my_mod::JSON, None) => true, + _ => false, + } +} + +fn main() {} diff --git a/src/test/run-pass/nll/issue-47153-generic-const.rs b/src/test/run-pass/nll/issue-47153-generic-const.rs new file mode 100644 index 00000000000..9708ca1c142 --- /dev/null +++ b/src/test/run-pass/nll/issue-47153-generic-const.rs @@ -0,0 +1,27 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Regression test for #47153: constants in a generic context (such as +// a trait) used to ICE. + +#![feature(nll)] +#![allow(warnings)] + +trait Foo { + const B: bool = true; +} + +struct Bar<T> { x: T } + +impl<T> Bar<T> { + const B: bool = true; +} + +fn main() { } diff --git a/src/test/run-pass/result-opt-conversions.rs b/src/test/run-pass/result-opt-conversions.rs new file mode 100644 index 00000000000..0f6da002dda --- /dev/null +++ b/src/test/run-pass/result-opt-conversions.rs @@ -0,0 +1,57 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(transpose_result)] + +#[derive(Copy, Clone, Debug, PartialEq)] +struct BadNumErr; + +fn try_num(x: i32) -> Result<i32, BadNumErr> { + if x <= 5 { + Ok(x + 1) + } else { + Err(BadNumErr) + } +} + +type ResOpt = Result<Option<i32>, BadNumErr>; +type OptRes = Option<Result<i32, BadNumErr>>; + +fn main() { + let mut x: ResOpt = Ok(Some(5)); + let mut y: OptRes = Some(Ok(5)); + assert_eq!(x, y.transpose()); + assert_eq!(x.transpose(), y); + + x = Ok(None); + y = None; + assert_eq!(x, y.transpose()); + assert_eq!(x.transpose(), y); + + x = Err(BadNumErr); + y = Some(Err(BadNumErr)); + assert_eq!(x, y.transpose()); + assert_eq!(x.transpose(), y); + + let res: Result<Vec<i32>, BadNumErr> = + (0..10) + .map(|x| { + let y = try_num(x)?; + Ok(if y % 2 == 0 { + Some(y - 1) + } else { + None + }) + }) + .filter_map(Result::transpose) + .collect(); + + assert_eq!(res, Err(BadNumErr)) +} diff --git a/src/test/run-pass/unboxed-closures-prelude.rs b/src/test/run-pass/unboxed-closures-prelude.rs index b7835324010..f82b04f37c5 100644 --- a/src/test/run-pass/unboxed-closures-prelude.rs +++ b/src/test/run-pass/unboxed-closures-prelude.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// Tests that the reexports of `FnOnce` et al from the prelude work. +// Tests that the re-exports of `FnOnce` et al from the prelude work. // pretty-expanded FIXME #23616 diff --git a/src/test/rustdoc-js/basic.js b/src/test/rustdoc-js/basic.js new file mode 100644 index 00000000000..863437cac91 --- /dev/null +++ b/src/test/rustdoc-js/basic.js @@ -0,0 +1,25 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +const QUERY = 'String'; + +const EXPECTED = { + 'others': [ + { 'path': 'std::string', 'name': 'String' }, + { 'path': 'std::ffi', 'name': 'OsString' }, + { 'path': 'std::ffi', 'name': 'CString' }, + ], + 'in_args': [ + { 'path': 'std::str', 'name': 'eq' }, + ], + 'returned': [ + { 'path': 'std::string::String', 'name': 'add' }, + ], +}; diff --git a/src/test/rustdoc-js/enum-option.js b/src/test/rustdoc-js/enum-option.js new file mode 100644 index 00000000000..3dac983b11b --- /dev/null +++ b/src/test/rustdoc-js/enum-option.js @@ -0,0 +1,17 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +const QUERY = 'enum:Option'; + +const EXPECTED = { + 'others': [ + { 'path': 'std::option', 'name': 'Option' }, + ], +}; diff --git a/src/test/rustdoc-js/fn-forget.js b/src/test/rustdoc-js/fn-forget.js new file mode 100644 index 00000000000..10310d5eaf7 --- /dev/null +++ b/src/test/rustdoc-js/fn-forget.js @@ -0,0 +1,18 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +const QUERY = 'fn:forget'; + +const EXPECTED = { + 'others': [ + { 'path': 'std::mem', 'name': 'forget' }, + { 'path': 'std::fmt', 'name': 'format' }, + ], +}; diff --git a/src/test/rustdoc-js/from_u.js b/src/test/rustdoc-js/from_u.js new file mode 100644 index 00000000000..0296788f7a0 --- /dev/null +++ b/src/test/rustdoc-js/from_u.js @@ -0,0 +1,21 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +const QUERY = 'from_u'; + +const EXPECTED = { + 'others': [ + { 'path': 'std::char', 'name': 'from_u32' }, + { 'path': 'std::str', 'name': 'from_utf8' }, + { 'path': 'std::string::String', 'name': 'from_utf8' }, + { 'path': 'std::i32', 'name': 'from_unsigned' }, + { 'path': 'std::i128', 'name': 'from_unsigned' }, + ], +}; diff --git a/src/test/rustdoc-js/macro-print.js b/src/test/rustdoc-js/macro-print.js new file mode 100644 index 00000000000..811ba3474af --- /dev/null +++ b/src/test/rustdoc-js/macro-print.js @@ -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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +const QUERY = 'macro:print'; + +const EXPECTED = { + 'others': [ + { 'path': 'std', 'name': 'print' }, + { 'path': 'std', 'name': 'eprint' }, + { 'path': 'std', 'name': 'println' }, + { 'path': 'std', 'name': 'eprintln' }, + ], +}; diff --git a/src/test/rustdoc-js/string-from_ut.js b/src/test/rustdoc-js/string-from_ut.js new file mode 100644 index 00000000000..3d08ee37366 --- /dev/null +++ b/src/test/rustdoc-js/string-from_ut.js @@ -0,0 +1,21 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +const QUERY = 'String::from_ut'; + +const EXPECTED = { + 'others': [ + { 'path': 'std::string::String', 'name': 'from_utf8' }, + { 'path': 'std::string::String', 'name': 'from_utf8' }, + { 'path': 'std::string::String', 'name': 'from_utf8_lossy' }, + { 'path': 'std::string::String', 'name': 'from_utf16_lossy' }, + { 'path': 'std::string::String', 'name': 'from_utf8_unchecked' }, + ], +}; diff --git a/src/test/rustdoc-js/struct-vec.js b/src/test/rustdoc-js/struct-vec.js new file mode 100644 index 00000000000..a91bc2d0da2 --- /dev/null +++ b/src/test/rustdoc-js/struct-vec.js @@ -0,0 +1,19 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +const QUERY = 'struct:Vec'; + +const EXPECTED = { + 'others': [ + { 'path': 'std::vec', 'name': 'Vec' }, + { 'path': 'std::collections', 'name': 'VecDeque' }, + { 'path': 'alloc::raw_vec', 'name': 'RawVec' }, + ], +}; diff --git a/src/test/rustdoc/inline_cross/auxiliary/impl-inline-without-trait.rs b/src/test/rustdoc/inline_cross/auxiliary/impl-inline-without-trait.rs new file mode 100644 index 00000000000..5d4adb28cd8 --- /dev/null +++ b/src/test/rustdoc/inline_cross/auxiliary/impl-inline-without-trait.rs @@ -0,0 +1,18 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub trait MyTrait { + /// docs for my_trait_method + fn my_trait_method() {} +} + +pub struct MyStruct; + +impl MyTrait for MyStruct {} diff --git a/src/test/rustdoc/inline_cross/auxiliary/rustdoc-nonreachable-impls.rs b/src/test/rustdoc/inline_cross/auxiliary/rustdoc-nonreachable-impls.rs index 22a311d5797..5fee36959c2 100644 --- a/src/test/rustdoc/inline_cross/auxiliary/rustdoc-nonreachable-impls.rs +++ b/src/test/rustdoc/inline_cross/auxiliary/rustdoc-nonreachable-impls.rs @@ -36,7 +36,7 @@ pub mod hidden { pub struct Wobble; - // these should only be shown if they're reexported correctly + // these should only be shown if they're re-exported correctly impl Qux for ::Foo {} impl Qux for Wobble {} impl ::Bark for Wobble {} diff --git a/src/test/rustdoc/inline_cross/impl-inline-without-trait.rs b/src/test/rustdoc/inline_cross/impl-inline-without-trait.rs new file mode 100644 index 00000000000..ea97d9d6ac2 --- /dev/null +++ b/src/test/rustdoc/inline_cross/impl-inline-without-trait.rs @@ -0,0 +1,22 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:impl-inline-without-trait.rs +// build-aux-docs +// ignore-cross-compile + +#![crate_name = "foo"] + +extern crate impl_inline_without_trait; + +// @has 'foo/struct.MyStruct.html' +// @has - '//*[@id="method.my_trait_method"]' 'fn my_trait_method()' +// @has - '//*[@class="docblock"]' 'docs for my_trait_method' +pub use impl_inline_without_trait::MyStruct; diff --git a/src/test/ui-fulldeps/resolve-error.stderr b/src/test/ui-fulldeps/resolve-error.stderr index be7ebae70ad..9121ce1720c 100644 --- a/src/test/ui-fulldeps/resolve-error.stderr +++ b/src/test/ui-fulldeps/resolve-error.stderr @@ -38,13 +38,13 @@ error: cannot find macro `FooWithLongNama!` in this scope --> $DIR/resolve-error.rs:62:5 | 62 | FooWithLongNama!(); - | ^^^^^^^^^^^^^^^ help: you could try the macro: `FooWithLongNam!` + | ^^^^^^^^^^^^^^^ help: you could try the macro: `FooWithLongNam` error: cannot find macro `attr_proc_macra!` in this scope --> $DIR/resolve-error.rs:65:5 | 65 | attr_proc_macra!(); - | ^^^^^^^^^^^^^^^ help: you could try the macro: `attr_proc_mac!` + | ^^^^^^^^^^^^^^^ help: you could try the macro: `attr_proc_mac` error: cannot find macro `Dlona!` in this scope --> $DIR/resolve-error.rs:68:5 @@ -56,7 +56,7 @@ error: cannot find macro `bang_proc_macrp!` in this scope --> $DIR/resolve-error.rs:71:5 | 71 | bang_proc_macrp!(); - | ^^^^^^^^^^^^^^^ help: you could try the macro: `bang_proc_macro!` + | ^^^^^^^^^^^^^^^ help: you could try the macro: `bang_proc_macro` error: aborting due to 10 previous errors diff --git a/src/test/ui-fulldeps/update-references.sh b/src/test/ui-fulldeps/update-references.sh index c2c842fcc49..c2c842fcc49 100644..100755 --- a/src/test/ui-fulldeps/update-references.sh +++ b/src/test/ui-fulldeps/update-references.sh diff --git a/src/test/ui/anonymous-higher-ranked-lifetime.stderr b/src/test/ui/anonymous-higher-ranked-lifetime.stderr index e364a4d8b14..4bd3b684b7b 100644 --- a/src/test/ui/anonymous-higher-ranked-lifetime.stderr +++ b/src/test/ui/anonymous-higher-ranked-lifetime.stderr @@ -6,7 +6,11 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `for<'r, 's> fn(&'r (), &'s ()) -> _` | - = note: required by `f1` +note: required by `f1` + --> $DIR/anonymous-higher-ranked-lifetime.rs:26:1 + | +26 | fn f1<F>(_: F) where F: Fn(&(), &()) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:13:5 @@ -16,7 +20,11 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `for<'a, 'r> fn(&'a (), &'r ()) -> _` | - = note: required by `f2` +note: required by `f2` + --> $DIR/anonymous-higher-ranked-lifetime.rs:27:1 + | +27 | fn f2<F>(_: F) where F: for<'a> Fn(&'a (), &()) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:14:5 @@ -26,7 +34,11 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `for<'r> fn(&(), &'r ()) -> _` | - = note: required by `f3` +note: required by `f3` + --> $DIR/anonymous-higher-ranked-lifetime.rs:28:1 + | +28 | fn f3<'a, F>(_: F) where F: Fn(&'a (), &()) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:15:5 @@ -36,7 +48,11 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `for<'s, 'r> fn(&'s (), &'r ()) -> _` | - = note: required by `f4` +note: required by `f4` + --> $DIR/anonymous-higher-ranked-lifetime.rs:29:1 + | +29 | fn f4<F>(_: F) where F: for<'r> Fn(&(), &'r ()) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:16:5 @@ -46,7 +62,11 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `for<'r> fn(&'r (), &'r ()) -> _` | - = note: required by `f5` +note: required by `f5` + --> $DIR/anonymous-higher-ranked-lifetime.rs:30:1 + | +30 | fn f5<F>(_: F) where F: for<'r> Fn(&'r (), &'r ()) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:17:5 @@ -56,7 +76,11 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `for<'r> fn(&'r (), std::boxed::Box<for<'s> std::ops::Fn(&'s ()) + 'static>) -> _` | - = note: required by `g1` +note: required by `g1` + --> $DIR/anonymous-higher-ranked-lifetime.rs:33:1 + | +33 | fn g1<F>(_: F) where F: Fn(&(), Box<Fn(&())>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:18:5 @@ -66,7 +90,11 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `for<'r> fn(&'r (), for<'s> fn(&'s ())) -> _` | - = note: required by `g2` +note: required by `g2` + --> $DIR/anonymous-higher-ranked-lifetime.rs:34:1 + | +34 | fn g2<F>(_: F) where F: Fn(&(), fn(&())) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:19:5 @@ -76,7 +104,11 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `for<'s> fn(&'s (), std::boxed::Box<for<'r> std::ops::Fn(&'r ()) + 'static>) -> _` | - = note: required by `g3` +note: required by `g3` + --> $DIR/anonymous-higher-ranked-lifetime.rs:35:1 + | +35 | fn g3<F>(_: F) where F: for<'s> Fn(&'s (), Box<Fn(&())>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:20:5 @@ -86,7 +118,11 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `for<'s> fn(&'s (), for<'r> fn(&'r ())) -> _` | - = note: required by `g4` +note: required by `g4` + --> $DIR/anonymous-higher-ranked-lifetime.rs:36:1 + | +36 | fn g4<F>(_: F) where F: Fn(&(), for<'r> fn(&'r ())) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:21:5 @@ -96,7 +132,11 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `for<'r, 's> fn(&'r (), std::boxed::Box<for<'t0> std::ops::Fn(&'t0 ()) + 'static>, &'s (), for<'t0, 't1> fn(&'t0 (), &'t1 ())) -> _` | - = note: required by `h1` +note: required by `h1` + --> $DIR/anonymous-higher-ranked-lifetime.rs:39:1 + | +39 | fn h1<F>(_: F) where F: Fn(&(), Box<Fn(&())>, &(), fn(&(), &())) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:22:5 @@ -106,7 +146,11 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `for<'r, 't0> fn(&'r (), std::boxed::Box<for<'s> std::ops::Fn(&'s ()) + 'static>, &'t0 (), for<'s, 't1> fn(&'s (), &'t1 ())) -> _` | - = note: required by `h2` +note: required by `h2` + --> $DIR/anonymous-higher-ranked-lifetime.rs:40:1 + | +40 | fn h2<F>(_: F) where F: for<'t0> Fn(&(), Box<Fn(&())>, &'t0 (), fn(&(), &())) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 11 previous errors diff --git a/src/test/ui/block-result/issue-20862.stderr b/src/test/ui/block-result/issue-20862.stderr index 7c88d789fd3..3b4f514de7d 100644 --- a/src/test/ui/block-result/issue-20862.stderr +++ b/src/test/ui/block-result/issue-20862.stderr @@ -13,7 +13,7 @@ error[E0618]: expected function, found `()` --> $DIR/issue-20862.rs:17:13 | 17 | let x = foo(5)(2); - | ^^^^^^^^^ + | ^^^^^^^^^ not a function error: aborting due to 2 previous errors diff --git a/src/test/ui/borrowck/issue-45983.rs b/src/test/ui/borrowck/issue-45983.rs new file mode 100644 index 00000000000..a6e5067195f --- /dev/null +++ b/src/test/ui/borrowck/issue-45983.rs @@ -0,0 +1,19 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn give_any<F: for<'r> FnOnce(&'r ())>(f: F) { + f(&()); +} + +fn main() { + let x = None; + give_any(|y| x = Some(y)); + //~^ ERROR borrowed data cannot be stored outside of its closure +} diff --git a/src/test/ui/borrowck/issue-45983.stderr b/src/test/ui/borrowck/issue-45983.stderr new file mode 100644 index 00000000000..496f15c289c --- /dev/null +++ b/src/test/ui/borrowck/issue-45983.stderr @@ -0,0 +1,12 @@ +error: borrowed data cannot be stored outside of its closure + --> $DIR/issue-45983.rs:17:27 + | +16 | let x = None; + | - borrowed data cannot be stored into here... +17 | give_any(|y| x = Some(y)); + | --- ^ cannot be stored outside of its closure + | | + | ...because it cannot outlive this closure + +error: aborting due to previous error + diff --git a/src/test/compile-fail/issue-7573.rs b/src/test/ui/borrowck/issue-7573.rs index d13da1d9fd9..8f1545fa009 100644 --- a/src/test/compile-fail/issue-7573.rs +++ b/src/test/ui/borrowck/issue-7573.rs @@ -24,9 +24,14 @@ impl CrateId { } pub fn remove_package_from_database() { - let mut lines_to_use: Vec<&CrateId> = Vec::new(); //~ ERROR E0495 + let mut lines_to_use: Vec<&CrateId> = Vec::new(); + //~^ NOTE cannot infer an appropriate lifetime let push_id = |installed_id: &CrateId| { + //~^ NOTE borrowed data cannot outlive this closure + //~| NOTE ...so that variable is valid at time of its declaration lines_to_use.push(installed_id); + //~^ ERROR borrowed data cannot be stored outside of its closure + //~| NOTE cannot be stored outside of its closure }; list_database(push_id); diff --git a/src/test/ui/borrowck/issue-7573.stderr b/src/test/ui/borrowck/issue-7573.stderr new file mode 100644 index 00000000000..99b48d9276c --- /dev/null +++ b/src/test/ui/borrowck/issue-7573.stderr @@ -0,0 +1,16 @@ +error: borrowed data cannot be stored outside of its closure + --> $DIR/issue-7573.rs:32:27 + | +27 | let mut lines_to_use: Vec<&CrateId> = Vec::new(); + | - cannot infer an appropriate lifetime... +28 | //~^ NOTE cannot infer an appropriate lifetime +29 | let push_id = |installed_id: &CrateId| { + | ------- ------------------------ borrowed data cannot outlive this closure + | | + | ...so that variable is valid at time of its declaration +... +32 | lines_to_use.push(installed_id); + | ^^^^^^^^^^^^ cannot be stored outside of its closure + +error: aborting due to previous error + diff --git a/src/test/compile-fail/regions-escape-bound-fn-2.rs b/src/test/ui/borrowck/regions-escape-bound-fn-2.rs index 1329d05a0f6..1c38dee99a7 100644 --- a/src/test/compile-fail/regions-escape-bound-fn-2.rs +++ b/src/test/ui/borrowck/regions-escape-bound-fn-2.rs @@ -16,5 +16,5 @@ fn with_int<F>(f: F) where F: FnOnce(&isize) { fn main() { let mut x = None; with_int(|y| x = Some(y)); - //~^ ERROR cannot infer + //~^ ERROR borrowed data cannot be stored outside of its closure } diff --git a/src/test/ui/borrowck/regions-escape-bound-fn-2.stderr b/src/test/ui/borrowck/regions-escape-bound-fn-2.stderr new file mode 100644 index 00000000000..3d88f4fd52e --- /dev/null +++ b/src/test/ui/borrowck/regions-escape-bound-fn-2.stderr @@ -0,0 +1,12 @@ +error: borrowed data cannot be stored outside of its closure + --> $DIR/regions-escape-bound-fn-2.rs:18:27 + | +17 | let mut x = None; + | ----- borrowed data cannot be stored into here... +18 | with_int(|y| x = Some(y)); + | --- ^ cannot be stored outside of its closure + | | + | ...because it cannot outlive this closure + +error: aborting due to previous error + diff --git a/src/test/compile-fail/regions-escape-bound-fn.rs b/src/test/ui/borrowck/regions-escape-bound-fn.rs index 02e62ffddfd..c22742371ac 100644 --- a/src/test/compile-fail/regions-escape-bound-fn.rs +++ b/src/test/ui/borrowck/regions-escape-bound-fn.rs @@ -15,5 +15,6 @@ fn with_int<F>(f: F) where F: FnOnce(&isize) { fn main() { let mut x: Option<&isize> = None; - with_int(|y| x = Some(y)); //~ ERROR cannot infer + with_int(|y| x = Some(y)); + //~^ ERROR borrowed data cannot be stored outside of its closure } diff --git a/src/test/ui/borrowck/regions-escape-bound-fn.stderr b/src/test/ui/borrowck/regions-escape-bound-fn.stderr new file mode 100644 index 00000000000..a2ad7c3f768 --- /dev/null +++ b/src/test/ui/borrowck/regions-escape-bound-fn.stderr @@ -0,0 +1,12 @@ +error: borrowed data cannot be stored outside of its closure + --> $DIR/regions-escape-bound-fn.rs:18:27 + | +17 | let mut x: Option<&isize> = None; + | ----- borrowed data cannot be stored into here... +18 | with_int(|y| x = Some(y)); + | --- ^ cannot be stored outside of its closure + | | + | ...because it cannot outlive this closure + +error: aborting due to previous error + diff --git a/src/test/compile-fail/regions-escape-unboxed-closure.rs b/src/test/ui/borrowck/regions-escape-unboxed-closure.rs index cf41fad2708..5a214504df4 100644 --- a/src/test/compile-fail/regions-escape-unboxed-closure.rs +++ b/src/test/ui/borrowck/regions-escape-unboxed-closure.rs @@ -13,5 +13,6 @@ fn with_int(f: &mut FnMut(&isize)) { fn main() { let mut x: Option<&isize> = None; - with_int(&mut |y| x = Some(y)); //~ ERROR cannot infer + with_int(&mut |y| x = Some(y)); + //~^ ERROR borrowed data cannot be stored outside of its closure } diff --git a/src/test/ui/borrowck/regions-escape-unboxed-closure.stderr b/src/test/ui/borrowck/regions-escape-unboxed-closure.stderr new file mode 100644 index 00000000000..4b01e42fa67 --- /dev/null +++ b/src/test/ui/borrowck/regions-escape-unboxed-closure.stderr @@ -0,0 +1,12 @@ +error: borrowed data cannot be stored outside of its closure + --> $DIR/regions-escape-unboxed-closure.rs:16:32 + | +15 | let mut x: Option<&isize> = None; + | ----- borrowed data cannot be stored into here... +16 | with_int(&mut |y| x = Some(y)); + | --- ^ cannot be stored outside of its closure + | | + | ...because it cannot outlive this closure + +error: aborting due to previous error + diff --git a/src/test/compile-fail/closure-expected-type/expect-region-supply-region.rs b/src/test/ui/closure-expected-type/expect-region-supply-region.rs index 9da12dc901f..a464c5853e1 100644 --- a/src/test/compile-fail/closure-expected-type/expect-region-supply-region.rs +++ b/src/test/ui/closure-expected-type/expect-region-supply-region.rs @@ -25,7 +25,7 @@ fn expect_bound_supply_nothing() { // it to escape into `f`: let mut f: Option<&u32> = None; closure_expecting_bound(|x| { - f = Some(x); //~ ERROR E0495 + f = Some(x); //~ ERROR borrowed data cannot be stored outside of its closure }); } @@ -35,7 +35,7 @@ fn expect_bound_supply_bound() { // closure: let mut f: Option<&u32> = None; closure_expecting_bound(|x: &u32| { - f = Some(x); //~ ERROR E0495 + f = Some(x); //~ ERROR borrowed data cannot be stored outside of its closure }); } @@ -50,7 +50,7 @@ fn expect_bound_supply_named<'x>() { // And we still cannot let `x` escape into `f`. f = Some(x); - //~^ ERROR cannot infer + //~^ ERROR borrowed data cannot be stored outside of its closure }); } diff --git a/src/test/ui/closure-expected-type/expect-region-supply-region.stderr b/src/test/ui/closure-expected-type/expect-region-supply-region.stderr new file mode 100644 index 00000000000..ebb1e561e57 --- /dev/null +++ b/src/test/ui/closure-expected-type/expect-region-supply-region.stderr @@ -0,0 +1,98 @@ +error: borrowed data cannot be stored outside of its closure + --> $DIR/expect-region-supply-region.rs:28:18 + | +26 | let mut f: Option<&u32> = None; + | ----- borrowed data cannot be stored into here... +27 | closure_expecting_bound(|x| { + | --- ...because it cannot outlive this closure +28 | f = Some(x); //~ ERROR borrowed data cannot be stored outside of its closure + | ^ cannot be stored outside of its closure + +error: borrowed data cannot be stored outside of its closure + --> $DIR/expect-region-supply-region.rs:38:18 + | +36 | let mut f: Option<&u32> = None; + | ----- borrowed data cannot be stored into here... +37 | closure_expecting_bound(|x: &u32| { + | --------- ...because it cannot outlive this closure +38 | f = Some(x); //~ ERROR borrowed data cannot be stored outside of its closure + | ^ cannot be stored outside of its closure + +error[E0308]: mismatched types + --> $DIR/expect-region-supply-region.rs:47:33 + | +47 | closure_expecting_bound(|x: &'x u32| { + | ^^^^^^^ lifetime mismatch + | + = note: expected type `&u32` + found type `&'x u32` +note: the anonymous lifetime #2 defined on the body at 47:29... + --> $DIR/expect-region-supply-region.rs:47:29 + | +47 | closure_expecting_bound(|x: &'x u32| { + | _____________________________^ +48 | | //~^ ERROR mismatched types +49 | | //~| ERROR mismatched types +50 | | +... | +53 | | //~^ ERROR borrowed data cannot be stored outside of its closure +54 | | }); + | |_____^ +note: ...does not necessarily outlive the lifetime 'x as defined on the function body at 42:1 + --> $DIR/expect-region-supply-region.rs:42:1 + | +42 | / fn expect_bound_supply_named<'x>() { +43 | | let mut f: Option<&u32> = None; +44 | | +45 | | // Here we give a type annotation that `x` should be free. We get +... | +54 | | }); +55 | | } + | |_^ + +error[E0308]: mismatched types + --> $DIR/expect-region-supply-region.rs:47:33 + | +47 | closure_expecting_bound(|x: &'x u32| { + | ^^^^^^^ lifetime mismatch + | + = note: expected type `&u32` + found type `&'x u32` +note: the lifetime 'x as defined on the function body at 42:1... + --> $DIR/expect-region-supply-region.rs:42:1 + | +42 | / fn expect_bound_supply_named<'x>() { +43 | | let mut f: Option<&u32> = None; +44 | | +45 | | // Here we give a type annotation that `x` should be free. We get +... | +54 | | }); +55 | | } + | |_^ +note: ...does not necessarily outlive the anonymous lifetime #2 defined on the body at 47:29 + --> $DIR/expect-region-supply-region.rs:47:29 + | +47 | closure_expecting_bound(|x: &'x u32| { + | _____________________________^ +48 | | //~^ ERROR mismatched types +49 | | //~| ERROR mismatched types +50 | | +... | +53 | | //~^ ERROR borrowed data cannot be stored outside of its closure +54 | | }); + | |_____^ + +error: borrowed data cannot be stored outside of its closure + --> $DIR/expect-region-supply-region.rs:52:18 + | +43 | let mut f: Option<&u32> = None; + | ----- borrowed data cannot be stored into here... +... +47 | closure_expecting_bound(|x: &'x u32| { + | ------------ ...because it cannot outlive this closure +... +52 | f = Some(x); + | ^ cannot be stored outside of its closure + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr index d5c4add34b5..7ca3e8728fd 100644 --- a/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr +++ b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr @@ -10,7 +10,11 @@ error[E0277]: the trait bound `i8: Foo<i32>` is not satisfied <i8 as Foo<u32>> <i8 as Foo<u64>> <i8 as Foo<bool>> - = note: required by `Foo::bar` +note: required by `Foo::bar` + --> $DIR/issue-39802-show-5-trait-impls.rs:12:5 + | +12 | fn bar(&self){} + | ^^^^^^^^^^^^^ error[E0277]: the trait bound `u8: Foo<i32>` is not satisfied --> $DIR/issue-39802-show-5-trait-impls.rs:35:5 @@ -23,7 +27,11 @@ error[E0277]: the trait bound `u8: Foo<i32>` is not satisfied <u8 as Foo<u32>> <u8 as Foo<u64>> <u8 as Foo<bool>> - = note: required by `Foo::bar` +note: required by `Foo::bar` + --> $DIR/issue-39802-show-5-trait-impls.rs:12:5 + | +12 | fn bar(&self){} + | ^^^^^^^^^^^^^ error[E0277]: the trait bound `bool: Foo<i32>` is not satisfied --> $DIR/issue-39802-show-5-trait-impls.rs:36:5 @@ -37,7 +45,11 @@ error[E0277]: the trait bound `bool: Foo<i32>` is not satisfied <bool as Foo<u32>> <bool as Foo<u64>> and 2 others - = note: required by `Foo::bar` +note: required by `Foo::bar` + --> $DIR/issue-39802-show-5-trait-impls.rs:12:5 + | +12 | fn bar(&self){} + | ^^^^^^^^^^^^^ error: aborting due to 3 previous errors diff --git a/src/test/ui/did_you_mean/recursion_limit.stderr b/src/test/ui/did_you_mean/recursion_limit.stderr index 7fac604ba49..2bc7e9e46e7 100644 --- a/src/test/ui/did_you_mean/recursion_limit.stderr +++ b/src/test/ui/did_you_mean/recursion_limit.stderr @@ -15,7 +15,11 @@ error[E0275]: overflow evaluating the requirement `K: std::marker::Send` = note: required because it appears within the type `C` = note: required because it appears within the type `B` = note: required because it appears within the type `A` - = note: required by `is_send` +note: required by `is_send` + --> $DIR/recursion_limit.rs:41:1 + | +41 | fn is_send<T:Send>() { } + | ^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/empty-struct-unit-expr.rs b/src/test/ui/empty-struct-unit-expr.rs index c33960193b0..941292a7ec2 100644 --- a/src/test/ui/empty-struct-unit-expr.rs +++ b/src/test/ui/empty-struct-unit-expr.rs @@ -24,8 +24,8 @@ enum E { fn main() { let e2 = Empty2(); //~ ERROR expected function, found `Empty2` let e4 = E::Empty4(); - //~^ ERROR expected function, found `E::Empty4` [E0618] + //~^ ERROR expected function, found enum variant `E::Empty4` [E0618] let xe2 = XEmpty2(); //~ ERROR expected function, found `empty_struct::XEmpty2` let xe4 = XE::XEmpty4(); - //~^ ERROR expected function, found `XE::XEmpty4` [E0618] + //~^ ERROR expected function, found enum variant `XE::XEmpty4` [E0618] } diff --git a/src/test/ui/empty-struct-unit-expr.stderr b/src/test/ui/empty-struct-unit-expr.stderr index 3ce63ed9f42..aa242a530d0 100644 --- a/src/test/ui/empty-struct-unit-expr.stderr +++ b/src/test/ui/empty-struct-unit-expr.stderr @@ -1,41 +1,40 @@ error[E0618]: expected function, found `Empty2` --> $DIR/empty-struct-unit-expr.rs:25:14 | -25 | let e2 = Empty2(); //~ ERROR expected function, found `Empty2` - | ^^^^^^^^ - | -note: defined here - --> $DIR/empty-struct-unit-expr.rs:18:1 - | 18 | struct Empty2; - | ^^^^^^^^^^^^^^ + | -------------- `Empty2` defined here +... +25 | let e2 = Empty2(); //~ ERROR expected function, found `Empty2` + | ^^^^^^^^ not a function -error[E0618]: expected function, found `E::Empty4` +error[E0618]: expected function, found enum variant `E::Empty4` --> $DIR/empty-struct-unit-expr.rs:26:14 | +21 | Empty4 + | ------ `E::Empty4` defined here +... 26 | let e4 = E::Empty4(); - | ^^^^^^^^^^^ - | - = help: did you mean to write `E::Empty4`? -note: defined here - --> $DIR/empty-struct-unit-expr.rs:21:5 + | ^^^^^^^^^^^ not a function +help: `E::Empty4` is a unit variant, you need to write it without the parenthesis | -21 | Empty4 - | ^^^^^^ +26 | let e4 = E::Empty4; + | ^^^^^^^^^ error[E0618]: expected function, found `empty_struct::XEmpty2` --> $DIR/empty-struct-unit-expr.rs:28:15 | 28 | let xe2 = XEmpty2(); //~ ERROR expected function, found `empty_struct::XEmpty2` - | ^^^^^^^^^ + | ^^^^^^^^^ not a function -error[E0618]: expected function, found `XE::XEmpty4` +error[E0618]: expected function, found enum variant `XE::XEmpty4` --> $DIR/empty-struct-unit-expr.rs:29:15 | 29 | let xe4 = XE::XEmpty4(); - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ not a function +help: `XE::XEmpty4` is a unit variant, you need to write it without the parenthesis | - = help: did you mean to write `XE::XEmpty4`? +29 | let xe4 = XE::XEmpty4; + | ^^^^^^^^^^^ error: aborting due to 4 previous errors diff --git a/src/test/ui/feature-gate-abi-msp430-interrupt.stderr b/src/test/ui/feature-gate-abi-msp430-interrupt.stderr index b05be6e4391..e1621d34d46 100644 --- a/src/test/ui/feature-gate-abi-msp430-interrupt.stderr +++ b/src/test/ui/feature-gate-abi-msp430-interrupt.stderr @@ -1,4 +1,4 @@ -error: msp430-interrupt ABI is experimental and subject to change (see issue #38487) +error[E0658]: msp430-interrupt ABI is experimental and subject to change (see issue #38487) --> $DIR/feature-gate-abi-msp430-interrupt.rs:14:1 | 14 | extern "msp430-interrupt" fn foo() {} diff --git a/src/test/ui/feature-gate-abi.stderr b/src/test/ui/feature-gate-abi.stderr index 7d2ad0be391..ce31474caed 100644 --- a/src/test/ui/feature-gate-abi.stderr +++ b/src/test/ui/feature-gate-abi.stderr @@ -1,4 +1,4 @@ -error: intrinsics are subject to change +error[E0658]: intrinsics are subject to change --> $DIR/feature-gate-abi.rs:19:1 | 19 | extern "rust-intrinsic" fn f1() {} //~ ERROR intrinsics are subject to change @@ -6,7 +6,7 @@ error: intrinsics are subject to change | = help: add #![feature(intrinsics)] to the crate attributes to enable -error: platform intrinsics are experimental and possibly buggy (see issue #27731) +error[E0658]: platform intrinsics are experimental and possibly buggy (see issue #27731) --> $DIR/feature-gate-abi.rs:20:1 | 20 | extern "platform-intrinsic" fn f2() {} //~ ERROR platform intrinsics are experimental @@ -14,7 +14,7 @@ error: platform intrinsics are experimental and possibly buggy (see issue #27731 | = help: add #![feature(platform_intrinsics)] to the crate attributes to enable -error: vectorcall is experimental and subject to change +error[E0658]: vectorcall is experimental and subject to change --> $DIR/feature-gate-abi.rs:21:1 | 21 | extern "vectorcall" fn f3() {} //~ ERROR vectorcall is experimental and subject to change @@ -22,7 +22,7 @@ error: vectorcall is experimental and subject to change | = help: add #![feature(abi_vectorcall)] to the crate attributes to enable -error: rust-call ABI is subject to change (see issue #29625) +error[E0658]: rust-call ABI is subject to change (see issue #29625) --> $DIR/feature-gate-abi.rs:22:1 | 22 | extern "rust-call" fn f4() {} //~ ERROR rust-call ABI is subject to change @@ -30,7 +30,7 @@ error: rust-call ABI is subject to change (see issue #29625) | = help: add #![feature(unboxed_closures)] to the crate attributes to enable -error: msp430-interrupt ABI is experimental and subject to change (see issue #38487) +error[E0658]: msp430-interrupt ABI is experimental and subject to change (see issue #38487) --> $DIR/feature-gate-abi.rs:23:1 | 23 | extern "msp430-interrupt" fn f5() {} //~ ERROR msp430-interrupt ABI is experimental @@ -38,7 +38,7 @@ error: msp430-interrupt ABI is experimental and subject to change (see issue #38 | = help: add #![feature(abi_msp430_interrupt)] to the crate attributes to enable -error: PTX ABIs are experimental and subject to change +error[E0658]: PTX ABIs are experimental and subject to change --> $DIR/feature-gate-abi.rs:24:1 | 24 | extern "ptx-kernel" fn f6() {} //~ ERROR PTX ABIs are experimental and subject to change @@ -46,7 +46,7 @@ error: PTX ABIs are experimental and subject to change | = help: add #![feature(abi_ptx)] to the crate attributes to enable -error: x86-interrupt ABI is experimental and subject to change (see issue #40180) +error[E0658]: x86-interrupt ABI is experimental and subject to change (see issue #40180) --> $DIR/feature-gate-abi.rs:25:1 | 25 | extern "x86-interrupt" fn f7() {} //~ ERROR x86-interrupt ABI is experimental @@ -54,7 +54,7 @@ error: x86-interrupt ABI is experimental and subject to change (see issue #40180 | = help: add #![feature(abi_x86_interrupt)] to the crate attributes to enable -error: thiscall is experimental and subject to change +error[E0658]: thiscall is experimental and subject to change --> $DIR/feature-gate-abi.rs:26:1 | 26 | extern "thiscall" fn f8() {} //~ ERROR thiscall is experimental and subject to change @@ -62,7 +62,7 @@ error: thiscall is experimental and subject to change | = help: add #![feature(abi_thiscall)] to the crate attributes to enable -error: intrinsics are subject to change +error[E0658]: intrinsics are subject to change --> $DIR/feature-gate-abi.rs:30:5 | 30 | extern "rust-intrinsic" fn m1(); //~ ERROR intrinsics are subject to change @@ -70,7 +70,7 @@ error: intrinsics are subject to change | = help: add #![feature(intrinsics)] to the crate attributes to enable -error: platform intrinsics are experimental and possibly buggy (see issue #27731) +error[E0658]: platform intrinsics are experimental and possibly buggy (see issue #27731) --> $DIR/feature-gate-abi.rs:31:5 | 31 | extern "platform-intrinsic" fn m2(); //~ ERROR platform intrinsics are experimental @@ -78,7 +78,7 @@ error: platform intrinsics are experimental and possibly buggy (see issue #27731 | = help: add #![feature(platform_intrinsics)] to the crate attributes to enable -error: vectorcall is experimental and subject to change +error[E0658]: vectorcall is experimental and subject to change --> $DIR/feature-gate-abi.rs:32:5 | 32 | extern "vectorcall" fn m3(); //~ ERROR vectorcall is experimental and subject to change @@ -86,7 +86,7 @@ error: vectorcall is experimental and subject to change | = help: add #![feature(abi_vectorcall)] to the crate attributes to enable -error: rust-call ABI is subject to change (see issue #29625) +error[E0658]: rust-call ABI is subject to change (see issue #29625) --> $DIR/feature-gate-abi.rs:33:5 | 33 | extern "rust-call" fn m4(); //~ ERROR rust-call ABI is subject to change @@ -94,7 +94,7 @@ error: rust-call ABI is subject to change (see issue #29625) | = help: add #![feature(unboxed_closures)] to the crate attributes to enable -error: msp430-interrupt ABI is experimental and subject to change (see issue #38487) +error[E0658]: msp430-interrupt ABI is experimental and subject to change (see issue #38487) --> $DIR/feature-gate-abi.rs:34:5 | 34 | extern "msp430-interrupt" fn m5(); //~ ERROR msp430-interrupt ABI is experimental @@ -102,7 +102,7 @@ error: msp430-interrupt ABI is experimental and subject to change (see issue #38 | = help: add #![feature(abi_msp430_interrupt)] to the crate attributes to enable -error: PTX ABIs are experimental and subject to change +error[E0658]: PTX ABIs are experimental and subject to change --> $DIR/feature-gate-abi.rs:35:5 | 35 | extern "ptx-kernel" fn m6(); //~ ERROR PTX ABIs are experimental and subject to change @@ -110,7 +110,7 @@ error: PTX ABIs are experimental and subject to change | = help: add #![feature(abi_ptx)] to the crate attributes to enable -error: x86-interrupt ABI is experimental and subject to change (see issue #40180) +error[E0658]: x86-interrupt ABI is experimental and subject to change (see issue #40180) --> $DIR/feature-gate-abi.rs:36:5 | 36 | extern "x86-interrupt" fn m7(); //~ ERROR x86-interrupt ABI is experimental @@ -118,7 +118,7 @@ error: x86-interrupt ABI is experimental and subject to change (see issue #40180 | = help: add #![feature(abi_x86_interrupt)] to the crate attributes to enable -error: thiscall is experimental and subject to change +error[E0658]: thiscall is experimental and subject to change --> $DIR/feature-gate-abi.rs:37:5 | 37 | extern "thiscall" fn m8(); //~ ERROR thiscall is experimental and subject to change @@ -126,7 +126,7 @@ error: thiscall is experimental and subject to change | = help: add #![feature(abi_thiscall)] to the crate attributes to enable -error: intrinsics are subject to change +error[E0658]: intrinsics are subject to change --> $DIR/feature-gate-abi.rs:39:5 | 39 | extern "rust-intrinsic" fn dm1() {} //~ ERROR intrinsics are subject to change @@ -134,7 +134,7 @@ error: intrinsics are subject to change | = help: add #![feature(intrinsics)] to the crate attributes to enable -error: platform intrinsics are experimental and possibly buggy (see issue #27731) +error[E0658]: platform intrinsics are experimental and possibly buggy (see issue #27731) --> $DIR/feature-gate-abi.rs:40:5 | 40 | extern "platform-intrinsic" fn dm2() {} //~ ERROR platform intrinsics are experimental @@ -142,7 +142,7 @@ error: platform intrinsics are experimental and possibly buggy (see issue #27731 | = help: add #![feature(platform_intrinsics)] to the crate attributes to enable -error: vectorcall is experimental and subject to change +error[E0658]: vectorcall is experimental and subject to change --> $DIR/feature-gate-abi.rs:41:5 | 41 | extern "vectorcall" fn dm3() {} //~ ERROR vectorcall is experimental and subject to change @@ -150,7 +150,7 @@ error: vectorcall is experimental and subject to change | = help: add #![feature(abi_vectorcall)] to the crate attributes to enable -error: rust-call ABI is subject to change (see issue #29625) +error[E0658]: rust-call ABI is subject to change (see issue #29625) --> $DIR/feature-gate-abi.rs:42:5 | 42 | extern "rust-call" fn dm4() {} //~ ERROR rust-call ABI is subject to change @@ -158,7 +158,7 @@ error: rust-call ABI is subject to change (see issue #29625) | = help: add #![feature(unboxed_closures)] to the crate attributes to enable -error: msp430-interrupt ABI is experimental and subject to change (see issue #38487) +error[E0658]: msp430-interrupt ABI is experimental and subject to change (see issue #38487) --> $DIR/feature-gate-abi.rs:43:5 | 43 | extern "msp430-interrupt" fn dm5() {} //~ ERROR msp430-interrupt ABI is experimental @@ -166,7 +166,7 @@ error: msp430-interrupt ABI is experimental and subject to change (see issue #38 | = help: add #![feature(abi_msp430_interrupt)] to the crate attributes to enable -error: PTX ABIs are experimental and subject to change +error[E0658]: PTX ABIs are experimental and subject to change --> $DIR/feature-gate-abi.rs:44:5 | 44 | extern "ptx-kernel" fn dm6() {} //~ ERROR PTX ABIs are experimental and subject to change @@ -174,7 +174,7 @@ error: PTX ABIs are experimental and subject to change | = help: add #![feature(abi_ptx)] to the crate attributes to enable -error: x86-interrupt ABI is experimental and subject to change (see issue #40180) +error[E0658]: x86-interrupt ABI is experimental and subject to change (see issue #40180) --> $DIR/feature-gate-abi.rs:45:5 | 45 | extern "x86-interrupt" fn dm7() {} //~ ERROR x86-interrupt ABI is experimental @@ -182,7 +182,7 @@ error: x86-interrupt ABI is experimental and subject to change (see issue #40180 | = help: add #![feature(abi_x86_interrupt)] to the crate attributes to enable -error: thiscall is experimental and subject to change +error[E0658]: thiscall is experimental and subject to change --> $DIR/feature-gate-abi.rs:46:5 | 46 | extern "thiscall" fn dm8() {} //~ ERROR thiscall is experimental and subject to change @@ -190,7 +190,7 @@ error: thiscall is experimental and subject to change | = help: add #![feature(abi_thiscall)] to the crate attributes to enable -error: intrinsics are subject to change +error[E0658]: intrinsics are subject to change --> $DIR/feature-gate-abi.rs:53:5 | 53 | extern "rust-intrinsic" fn m1() {} //~ ERROR intrinsics are subject to change @@ -198,7 +198,7 @@ error: intrinsics are subject to change | = help: add #![feature(intrinsics)] to the crate attributes to enable -error: platform intrinsics are experimental and possibly buggy (see issue #27731) +error[E0658]: platform intrinsics are experimental and possibly buggy (see issue #27731) --> $DIR/feature-gate-abi.rs:54:5 | 54 | extern "platform-intrinsic" fn m2() {} //~ ERROR platform intrinsics are experimental @@ -206,7 +206,7 @@ error: platform intrinsics are experimental and possibly buggy (see issue #27731 | = help: add #![feature(platform_intrinsics)] to the crate attributes to enable -error: vectorcall is experimental and subject to change +error[E0658]: vectorcall is experimental and subject to change --> $DIR/feature-gate-abi.rs:55:5 | 55 | extern "vectorcall" fn m3() {} //~ ERROR vectorcall is experimental and subject to change @@ -214,7 +214,7 @@ error: vectorcall is experimental and subject to change | = help: add #![feature(abi_vectorcall)] to the crate attributes to enable -error: rust-call ABI is subject to change (see issue #29625) +error[E0658]: rust-call ABI is subject to change (see issue #29625) --> $DIR/feature-gate-abi.rs:56:5 | 56 | extern "rust-call" fn m4() {} //~ ERROR rust-call ABI is subject to change @@ -222,7 +222,7 @@ error: rust-call ABI is subject to change (see issue #29625) | = help: add #![feature(unboxed_closures)] to the crate attributes to enable -error: msp430-interrupt ABI is experimental and subject to change (see issue #38487) +error[E0658]: msp430-interrupt ABI is experimental and subject to change (see issue #38487) --> $DIR/feature-gate-abi.rs:57:5 | 57 | extern "msp430-interrupt" fn m5() {} //~ ERROR msp430-interrupt ABI is experimental @@ -230,7 +230,7 @@ error: msp430-interrupt ABI is experimental and subject to change (see issue #38 | = help: add #![feature(abi_msp430_interrupt)] to the crate attributes to enable -error: PTX ABIs are experimental and subject to change +error[E0658]: PTX ABIs are experimental and subject to change --> $DIR/feature-gate-abi.rs:58:5 | 58 | extern "ptx-kernel" fn m6() {} //~ ERROR PTX ABIs are experimental and subject to change @@ -238,7 +238,7 @@ error: PTX ABIs are experimental and subject to change | = help: add #![feature(abi_ptx)] to the crate attributes to enable -error: x86-interrupt ABI is experimental and subject to change (see issue #40180) +error[E0658]: x86-interrupt ABI is experimental and subject to change (see issue #40180) --> $DIR/feature-gate-abi.rs:59:5 | 59 | extern "x86-interrupt" fn m7() {} //~ ERROR x86-interrupt ABI is experimental @@ -246,7 +246,7 @@ error: x86-interrupt ABI is experimental and subject to change (see issue #40180 | = help: add #![feature(abi_x86_interrupt)] to the crate attributes to enable -error: thiscall is experimental and subject to change +error[E0658]: thiscall is experimental and subject to change --> $DIR/feature-gate-abi.rs:60:5 | 60 | extern "thiscall" fn m8() {} //~ ERROR thiscall is experimental and subject to change @@ -254,7 +254,7 @@ error: thiscall is experimental and subject to change | = help: add #![feature(abi_thiscall)] to the crate attributes to enable -error: intrinsics are subject to change +error[E0658]: intrinsics are subject to change --> $DIR/feature-gate-abi.rs:65:5 | 65 | extern "rust-intrinsic" fn im1() {} //~ ERROR intrinsics are subject to change @@ -262,7 +262,7 @@ error: intrinsics are subject to change | = help: add #![feature(intrinsics)] to the crate attributes to enable -error: platform intrinsics are experimental and possibly buggy (see issue #27731) +error[E0658]: platform intrinsics are experimental and possibly buggy (see issue #27731) --> $DIR/feature-gate-abi.rs:66:5 | 66 | extern "platform-intrinsic" fn im2() {} //~ ERROR platform intrinsics are experimental @@ -270,7 +270,7 @@ error: platform intrinsics are experimental and possibly buggy (see issue #27731 | = help: add #![feature(platform_intrinsics)] to the crate attributes to enable -error: vectorcall is experimental and subject to change +error[E0658]: vectorcall is experimental and subject to change --> $DIR/feature-gate-abi.rs:67:5 | 67 | extern "vectorcall" fn im3() {} //~ ERROR vectorcall is experimental and subject to change @@ -278,7 +278,7 @@ error: vectorcall is experimental and subject to change | = help: add #![feature(abi_vectorcall)] to the crate attributes to enable -error: rust-call ABI is subject to change (see issue #29625) +error[E0658]: rust-call ABI is subject to change (see issue #29625) --> $DIR/feature-gate-abi.rs:68:5 | 68 | extern "rust-call" fn im4() {} //~ ERROR rust-call ABI is subject to change @@ -286,7 +286,7 @@ error: rust-call ABI is subject to change (see issue #29625) | = help: add #![feature(unboxed_closures)] to the crate attributes to enable -error: msp430-interrupt ABI is experimental and subject to change (see issue #38487) +error[E0658]: msp430-interrupt ABI is experimental and subject to change (see issue #38487) --> $DIR/feature-gate-abi.rs:69:5 | 69 | extern "msp430-interrupt" fn im5() {} //~ ERROR msp430-interrupt ABI is experimental @@ -294,7 +294,7 @@ error: msp430-interrupt ABI is experimental and subject to change (see issue #38 | = help: add #![feature(abi_msp430_interrupt)] to the crate attributes to enable -error: PTX ABIs are experimental and subject to change +error[E0658]: PTX ABIs are experimental and subject to change --> $DIR/feature-gate-abi.rs:70:5 | 70 | extern "ptx-kernel" fn im6() {} //~ ERROR PTX ABIs are experimental and subject to change @@ -302,7 +302,7 @@ error: PTX ABIs are experimental and subject to change | = help: add #![feature(abi_ptx)] to the crate attributes to enable -error: x86-interrupt ABI is experimental and subject to change (see issue #40180) +error[E0658]: x86-interrupt ABI is experimental and subject to change (see issue #40180) --> $DIR/feature-gate-abi.rs:71:5 | 71 | extern "x86-interrupt" fn im7() {} //~ ERROR x86-interrupt ABI is experimental @@ -310,7 +310,7 @@ error: x86-interrupt ABI is experimental and subject to change (see issue #40180 | = help: add #![feature(abi_x86_interrupt)] to the crate attributes to enable -error: thiscall is experimental and subject to change +error[E0658]: thiscall is experimental and subject to change --> $DIR/feature-gate-abi.rs:72:5 | 72 | extern "thiscall" fn im8() {} //~ ERROR thiscall is experimental and subject to change @@ -318,7 +318,7 @@ error: thiscall is experimental and subject to change | = help: add #![feature(abi_thiscall)] to the crate attributes to enable -error: intrinsics are subject to change +error[E0658]: intrinsics are subject to change --> $DIR/feature-gate-abi.rs:76:11 | 76 | type A1 = extern "rust-intrinsic" fn(); //~ ERROR intrinsics are subject to change @@ -326,7 +326,7 @@ error: intrinsics are subject to change | = help: add #![feature(intrinsics)] to the crate attributes to enable -error: platform intrinsics are experimental and possibly buggy (see issue #27731) +error[E0658]: platform intrinsics are experimental and possibly buggy (see issue #27731) --> $DIR/feature-gate-abi.rs:77:11 | 77 | type A2 = extern "platform-intrinsic" fn(); //~ ERROR platform intrinsics are experimental @@ -334,7 +334,7 @@ error: platform intrinsics are experimental and possibly buggy (see issue #27731 | = help: add #![feature(platform_intrinsics)] to the crate attributes to enable -error: vectorcall is experimental and subject to change +error[E0658]: vectorcall is experimental and subject to change --> $DIR/feature-gate-abi.rs:78:11 | 78 | type A3 = extern "vectorcall" fn(); //~ ERROR vectorcall is experimental and subject to change @@ -342,7 +342,7 @@ error: vectorcall is experimental and subject to change | = help: add #![feature(abi_vectorcall)] to the crate attributes to enable -error: rust-call ABI is subject to change (see issue #29625) +error[E0658]: rust-call ABI is subject to change (see issue #29625) --> $DIR/feature-gate-abi.rs:79:11 | 79 | type A4 = extern "rust-call" fn(); //~ ERROR rust-call ABI is subject to change @@ -350,7 +350,7 @@ error: rust-call ABI is subject to change (see issue #29625) | = help: add #![feature(unboxed_closures)] to the crate attributes to enable -error: msp430-interrupt ABI is experimental and subject to change (see issue #38487) +error[E0658]: msp430-interrupt ABI is experimental and subject to change (see issue #38487) --> $DIR/feature-gate-abi.rs:80:11 | 80 | type A5 = extern "msp430-interrupt" fn(); //~ ERROR msp430-interrupt ABI is experimental @@ -358,7 +358,7 @@ error: msp430-interrupt ABI is experimental and subject to change (see issue #38 | = help: add #![feature(abi_msp430_interrupt)] to the crate attributes to enable -error: PTX ABIs are experimental and subject to change +error[E0658]: PTX ABIs are experimental and subject to change --> $DIR/feature-gate-abi.rs:81:11 | 81 | type A6 = extern "ptx-kernel" fn (); //~ ERROR PTX ABIs are experimental and subject to change @@ -366,7 +366,7 @@ error: PTX ABIs are experimental and subject to change | = help: add #![feature(abi_ptx)] to the crate attributes to enable -error: x86-interrupt ABI is experimental and subject to change (see issue #40180) +error[E0658]: x86-interrupt ABI is experimental and subject to change (see issue #40180) --> $DIR/feature-gate-abi.rs:82:11 | 82 | type A7 = extern "x86-interrupt" fn(); //~ ERROR x86-interrupt ABI is experimental @@ -374,7 +374,7 @@ error: x86-interrupt ABI is experimental and subject to change (see issue #40180 | = help: add #![feature(abi_x86_interrupt)] to the crate attributes to enable -error: thiscall is experimental and subject to change +error[E0658]: thiscall is experimental and subject to change --> $DIR/feature-gate-abi.rs:83:11 | 83 | type A8 = extern "thiscall" fn(); //~ ERROR thiscall is experimental and subject to change @@ -382,7 +382,7 @@ error: thiscall is experimental and subject to change | = help: add #![feature(abi_thiscall)] to the crate attributes to enable -error: intrinsics are subject to change +error[E0658]: intrinsics are subject to change --> $DIR/feature-gate-abi.rs:86:1 | 86 | extern "rust-intrinsic" {} //~ ERROR intrinsics are subject to change @@ -390,7 +390,7 @@ error: intrinsics are subject to change | = help: add #![feature(intrinsics)] to the crate attributes to enable -error: platform intrinsics are experimental and possibly buggy (see issue #27731) +error[E0658]: platform intrinsics are experimental and possibly buggy (see issue #27731) --> $DIR/feature-gate-abi.rs:87:1 | 87 | extern "platform-intrinsic" {} //~ ERROR platform intrinsics are experimental @@ -398,7 +398,7 @@ error: platform intrinsics are experimental and possibly buggy (see issue #27731 | = help: add #![feature(platform_intrinsics)] to the crate attributes to enable -error: vectorcall is experimental and subject to change +error[E0658]: vectorcall is experimental and subject to change --> $DIR/feature-gate-abi.rs:88:1 | 88 | extern "vectorcall" {} //~ ERROR vectorcall is experimental and subject to change @@ -406,7 +406,7 @@ error: vectorcall is experimental and subject to change | = help: add #![feature(abi_vectorcall)] to the crate attributes to enable -error: rust-call ABI is subject to change (see issue #29625) +error[E0658]: rust-call ABI is subject to change (see issue #29625) --> $DIR/feature-gate-abi.rs:89:1 | 89 | extern "rust-call" {} //~ ERROR rust-call ABI is subject to change @@ -414,7 +414,7 @@ error: rust-call ABI is subject to change (see issue #29625) | = help: add #![feature(unboxed_closures)] to the crate attributes to enable -error: msp430-interrupt ABI is experimental and subject to change (see issue #38487) +error[E0658]: msp430-interrupt ABI is experimental and subject to change (see issue #38487) --> $DIR/feature-gate-abi.rs:90:1 | 90 | extern "msp430-interrupt" {} //~ ERROR msp430-interrupt ABI is experimental @@ -422,7 +422,7 @@ error: msp430-interrupt ABI is experimental and subject to change (see issue #38 | = help: add #![feature(abi_msp430_interrupt)] to the crate attributes to enable -error: PTX ABIs are experimental and subject to change +error[E0658]: PTX ABIs are experimental and subject to change --> $DIR/feature-gate-abi.rs:91:1 | 91 | extern "ptx-kernel" {} //~ ERROR PTX ABIs are experimental and subject to change @@ -430,7 +430,7 @@ error: PTX ABIs are experimental and subject to change | = help: add #![feature(abi_ptx)] to the crate attributes to enable -error: x86-interrupt ABI is experimental and subject to change (see issue #40180) +error[E0658]: x86-interrupt ABI is experimental and subject to change (see issue #40180) --> $DIR/feature-gate-abi.rs:92:1 | 92 | extern "x86-interrupt" {} //~ ERROR x86-interrupt ABI is experimental @@ -438,7 +438,7 @@ error: x86-interrupt ABI is experimental and subject to change (see issue #40180 | = help: add #![feature(abi_x86_interrupt)] to the crate attributes to enable -error: thiscall is experimental and subject to change +error[E0658]: thiscall is experimental and subject to change --> $DIR/feature-gate-abi.rs:93:1 | 93 | extern "thiscall" {} //~ ERROR thiscall is experimental and subject to change diff --git a/src/test/ui/feature-gate-abi_unadjusted.stderr b/src/test/ui/feature-gate-abi_unadjusted.stderr index 3cc43847156..b3f7cd218d3 100644 --- a/src/test/ui/feature-gate-abi_unadjusted.stderr +++ b/src/test/ui/feature-gate-abi_unadjusted.stderr @@ -1,4 +1,4 @@ -error: unadjusted ABI is an implementation detail and perma-unstable +error[E0658]: unadjusted ABI is an implementation detail and perma-unstable --> $DIR/feature-gate-abi_unadjusted.rs:11:1 | 11 | / extern "unadjusted" fn foo() { diff --git a/src/test/ui/feature-gate-advanced-slice-features.stderr b/src/test/ui/feature-gate-advanced-slice-features.stderr index 815593d07a5..63ede50e1ea 100644 --- a/src/test/ui/feature-gate-advanced-slice-features.stderr +++ b/src/test/ui/feature-gate-advanced-slice-features.stderr @@ -1,4 +1,4 @@ -error: multiple-element slice matches anywhere but at the end of a slice (e.g. `[0, ..xs, 0]`) are experimental (see issue #23121) +error[E0658]: multiple-element slice matches anywhere but at the end of a slice (e.g. `[0, ..xs, 0]`) are experimental (see issue #23121) --> $DIR/feature-gate-advanced-slice-features.rs:18:9 | 18 | [ xs.., 4, 5 ] => {} //~ ERROR multiple-element slice matches @@ -6,7 +6,7 @@ error: multiple-element slice matches anywhere but at the end of a slice (e.g. ` | = help: add #![feature(advanced_slice_patterns)] to the crate attributes to enable -error: multiple-element slice matches anywhere but at the end of a slice (e.g. `[0, ..xs, 0]`) are experimental (see issue #23121) +error[E0658]: multiple-element slice matches anywhere but at the end of a slice (e.g. `[0, ..xs, 0]`) are experimental (see issue #23121) --> $DIR/feature-gate-advanced-slice-features.rs:19:9 | 19 | [ 1, xs.., 5 ] => {} //~ ERROR multiple-element slice matches diff --git a/src/test/ui/feature-gate-allocator_internals.stderr b/src/test/ui/feature-gate-allocator_internals.stderr index f1f4705b3bb..76d96f929be 100644 --- a/src/test/ui/feature-gate-allocator_internals.stderr +++ b/src/test/ui/feature-gate-allocator_internals.stderr @@ -1,4 +1,4 @@ -error: the `#[default_lib_allocator]` attribute is an experimental feature +error[E0658]: the `#[default_lib_allocator]` attribute is an experimental feature --> $DIR/feature-gate-allocator_internals.rs:11:1 | 11 | #![default_lib_allocator] //~ ERROR: attribute is an experimental feature diff --git a/src/test/ui/feature-gate-allow-internal-unsafe-nested-macro.stderr b/src/test/ui/feature-gate-allow-internal-unsafe-nested-macro.stderr index 40bdde37ee8..31de8d76285 100644 --- a/src/test/ui/feature-gate-allow-internal-unsafe-nested-macro.stderr +++ b/src/test/ui/feature-gate-allow-internal-unsafe-nested-macro.stderr @@ -1,4 +1,4 @@ -error: allow_internal_unsafe side-steps the unsafe_code lint +error[E0658]: allow_internal_unsafe side-steps the unsafe_code lint --> $DIR/feature-gate-allow-internal-unsafe-nested-macro.rs:18:9 | 18 | #[allow_internal_unsafe] //~ ERROR allow_internal_unsafe side-steps diff --git a/src/test/ui/feature-gate-allow-internal-unstable-nested-macro.stderr b/src/test/ui/feature-gate-allow-internal-unstable-nested-macro.stderr index 60d72fbc3b3..3e2573eda21 100644 --- a/src/test/ui/feature-gate-allow-internal-unstable-nested-macro.stderr +++ b/src/test/ui/feature-gate-allow-internal-unstable-nested-macro.stderr @@ -1,4 +1,4 @@ -error: allow_internal_unstable side-steps feature gating and stability checks +error[E0658]: allow_internal_unstable side-steps feature gating and stability checks --> $DIR/feature-gate-allow-internal-unstable-nested-macro.rs:18:9 | 18 | #[allow_internal_unstable] //~ ERROR allow_internal_unstable side-steps diff --git a/src/test/ui/feature-gate-allow-internal-unstable-struct.stderr b/src/test/ui/feature-gate-allow-internal-unstable-struct.stderr index 2fb86ce8f4e..e19f3288e81 100644 --- a/src/test/ui/feature-gate-allow-internal-unstable-struct.stderr +++ b/src/test/ui/feature-gate-allow-internal-unstable-struct.stderr @@ -1,4 +1,4 @@ -error: allow_internal_unstable side-steps feature gating and stability checks +error[E0658]: allow_internal_unstable side-steps feature gating and stability checks --> $DIR/feature-gate-allow-internal-unstable-struct.rs:14:1 | 14 | #[allow_internal_unstable] //~ ERROR allow_internal_unstable side-steps diff --git a/src/test/ui/feature-gate-allow-internal-unstable.stderr b/src/test/ui/feature-gate-allow-internal-unstable.stderr index a5740a1a789..f110afb35a0 100644 --- a/src/test/ui/feature-gate-allow-internal-unstable.stderr +++ b/src/test/ui/feature-gate-allow-internal-unstable.stderr @@ -1,4 +1,4 @@ -error: allow_internal_unstable side-steps feature gating and stability checks +error[E0658]: allow_internal_unstable side-steps feature gating and stability checks --> $DIR/feature-gate-allow-internal-unstable.rs:13:1 | 13 | #[allow_internal_unstable] //~ ERROR allow_internal_unstable side-steps diff --git a/src/test/ui/feature-gate-allow_fail.stderr b/src/test/ui/feature-gate-allow_fail.stderr index 65cd137459a..e04f44886dd 100644 --- a/src/test/ui/feature-gate-allow_fail.stderr +++ b/src/test/ui/feature-gate-allow_fail.stderr @@ -1,4 +1,4 @@ -error: allow_fail attribute is currently unstable (see issue #42219) +error[E0658]: allow_fail attribute is currently unstable (see issue #42219) --> $DIR/feature-gate-allow_fail.rs:13:1 | 13 | #[allow_fail] //~ ERROR allow_fail attribute is currently unstable diff --git a/src/test/ui/feature-gate-arbitrary-self-types.stderr b/src/test/ui/feature-gate-arbitrary-self-types.stderr index 2ef517cc9e1..ca47d40dc8f 100644 --- a/src/test/ui/feature-gate-arbitrary-self-types.stderr +++ b/src/test/ui/feature-gate-arbitrary-self-types.stderr @@ -1,4 +1,4 @@ -error: arbitrary `self` types are unstable (see issue #44874) +error[E0658]: arbitrary `self` types are unstable (see issue #44874) --> $DIR/feature-gate-arbitrary-self-types.rs:14:18 | 14 | fn foo(self: Rc<Box<Self>>); //~ ERROR arbitrary `self` types are unstable @@ -7,7 +7,7 @@ error: arbitrary `self` types are unstable (see issue #44874) = help: add #![feature(arbitrary_self_types)] to the crate attributes to enable = help: consider changing to `self`, `&self`, `&mut self`, or `self: Box<Self>` -error: arbitrary `self` types are unstable (see issue #44874) +error[E0658]: arbitrary `self` types are unstable (see issue #44874) --> $DIR/feature-gate-arbitrary-self-types.rs:20:18 | 20 | fn foo(self: Rc<Box<Self>>) {} //~ ERROR arbitrary `self` types are unstable @@ -16,7 +16,7 @@ error: arbitrary `self` types are unstable (see issue #44874) = help: add #![feature(arbitrary_self_types)] to the crate attributes to enable = help: consider changing to `self`, `&self`, `&mut self`, or `self: Box<Self>` -error: arbitrary `self` types are unstable (see issue #44874) +error[E0658]: arbitrary `self` types are unstable (see issue #44874) --> $DIR/feature-gate-arbitrary-self-types.rs:24:18 | 24 | fn bar(self: Box<Rc<Self>>) {} //~ ERROR arbitrary `self` types are unstable diff --git a/src/test/ui/feature-gate-arbitrary_self_types-raw-pointer.stderr b/src/test/ui/feature-gate-arbitrary_self_types-raw-pointer.stderr index d629ac4c60f..33e8806678d 100644 --- a/src/test/ui/feature-gate-arbitrary_self_types-raw-pointer.stderr +++ b/src/test/ui/feature-gate-arbitrary_self_types-raw-pointer.stderr @@ -1,4 +1,4 @@ -error: raw pointer `self` is unstable (see issue #44874) +error[E0658]: raw pointer `self` is unstable (see issue #44874) --> $DIR/feature-gate-arbitrary_self_types-raw-pointer.rs:19:18 | 19 | fn bar(self: *const Self); @@ -7,7 +7,7 @@ error: raw pointer `self` is unstable (see issue #44874) = help: add #![feature(arbitrary_self_types)] to the crate attributes to enable = help: consider changing to `self`, `&self`, `&mut self`, or `self: Box<Self>` -error: raw pointer `self` is unstable (see issue #44874) +error[E0658]: raw pointer `self` is unstable (see issue #44874) --> $DIR/feature-gate-arbitrary_self_types-raw-pointer.rs:14:18 | 14 | fn foo(self: *const Self) {} @@ -16,7 +16,7 @@ error: raw pointer `self` is unstable (see issue #44874) = help: add #![feature(arbitrary_self_types)] to the crate attributes to enable = help: consider changing to `self`, `&self`, `&mut self`, or `self: Box<Self>` -error: raw pointer `self` is unstable (see issue #44874) +error[E0658]: raw pointer `self` is unstable (see issue #44874) --> $DIR/feature-gate-arbitrary_self_types-raw-pointer.rs:24:18 | 24 | fn bar(self: *const Self) {} diff --git a/src/test/ui/feature-gate-asm.stderr b/src/test/ui/feature-gate-asm.stderr index ff68a4fb23e..481e6dc7055 100644 --- a/src/test/ui/feature-gate-asm.stderr +++ b/src/test/ui/feature-gate-asm.stderr @@ -1,4 +1,4 @@ -error: inline assembly is not stable enough for use and is subject to change (see issue #29722) +error[E0658]: inline assembly is not stable enough for use and is subject to change (see issue #29722) --> $DIR/feature-gate-asm.rs:13:9 | 13 | asm!(""); //~ ERROR inline assembly is not stable enough diff --git a/src/test/ui/feature-gate-asm2.stderr b/src/test/ui/feature-gate-asm2.stderr index 1e02cede61d..aba0f72d35c 100644 --- a/src/test/ui/feature-gate-asm2.stderr +++ b/src/test/ui/feature-gate-asm2.stderr @@ -1,4 +1,4 @@ -error: inline assembly is not stable enough for use and is subject to change (see issue #29722) +error[E0658]: inline assembly is not stable enough for use and is subject to change (see issue #29722) --> $DIR/feature-gate-asm2.rs:15:24 | 15 | println!("{}", asm!("")); //~ ERROR inline assembly is not stable diff --git a/src/test/ui/feature-gate-assoc-type-defaults.stderr b/src/test/ui/feature-gate-assoc-type-defaults.stderr index 5e288469168..1d44797cddc 100644 --- a/src/test/ui/feature-gate-assoc-type-defaults.stderr +++ b/src/test/ui/feature-gate-assoc-type-defaults.stderr @@ -1,4 +1,4 @@ -error: associated type defaults are unstable (see issue #29661) +error[E0658]: associated type defaults are unstable (see issue #29661) --> $DIR/feature-gate-assoc-type-defaults.rs:14:5 | 14 | type Bar = u8; //~ ERROR associated type defaults are unstable diff --git a/src/test/ui/feature-gate-box-expr.stderr b/src/test/ui/feature-gate-box-expr.stderr index cef5adbd15a..f9cccde3761 100644 --- a/src/test/ui/feature-gate-box-expr.stderr +++ b/src/test/ui/feature-gate-box-expr.stderr @@ -1,4 +1,4 @@ -error: box expression syntax is experimental; you can call `Box::new` instead. (see issue #27779) +error[E0658]: box expression syntax is experimental; you can call `Box::new` instead. (see issue #27779) --> $DIR/feature-gate-box-expr.rs:22:13 | 22 | let x = box 'c'; //~ ERROR box expression syntax is experimental diff --git a/src/test/ui/feature-gate-box_patterns.stderr b/src/test/ui/feature-gate-box_patterns.stderr index 0a30de58a1f..ca009331b69 100644 --- a/src/test/ui/feature-gate-box_patterns.stderr +++ b/src/test/ui/feature-gate-box_patterns.stderr @@ -1,4 +1,4 @@ -error: box pattern syntax is experimental (see issue #29641) +error[E0658]: box pattern syntax is experimental (see issue #29641) --> $DIR/feature-gate-box_patterns.rs:12:9 | 12 | let box x = Box::new('c'); //~ ERROR box pattern syntax is experimental diff --git a/src/test/ui/feature-gate-box_syntax.stderr b/src/test/ui/feature-gate-box_syntax.stderr index 9b21dd03051..eefaa724650 100644 --- a/src/test/ui/feature-gate-box_syntax.stderr +++ b/src/test/ui/feature-gate-box_syntax.stderr @@ -1,4 +1,4 @@ -error: box expression syntax is experimental; you can call `Box::new` instead. (see issue #27779) +error[E0658]: box expression syntax is experimental; you can call `Box::new` instead. (see issue #27779) --> $DIR/feature-gate-box_syntax.rs:14:13 | 14 | let x = box 3; diff --git a/src/test/ui/feature-gate-catch_expr.stderr b/src/test/ui/feature-gate-catch_expr.stderr index f486373d225..4b3bfbbe27a 100644 --- a/src/test/ui/feature-gate-catch_expr.stderr +++ b/src/test/ui/feature-gate-catch_expr.stderr @@ -1,4 +1,4 @@ -error: `catch` expression is experimental (see issue #31436) +error[E0658]: `catch` expression is experimental (see issue #31436) --> $DIR/feature-gate-catch_expr.rs:12:24 | 12 | let catch_result = do catch { //~ ERROR `catch` expression is experimental diff --git a/src/test/ui/feature-gate-cfg-target-feature.stderr b/src/test/ui/feature-gate-cfg-target-feature.stderr index 60dc6fbb57e..f808e78acce 100644 --- a/src/test/ui/feature-gate-cfg-target-feature.stderr +++ b/src/test/ui/feature-gate-cfg-target-feature.stderr @@ -1,4 +1,4 @@ -error: `cfg(target_feature)` is experimental and subject to change (see issue #29717) +error[E0658]: `cfg(target_feature)` is experimental and subject to change (see issue #29717) --> $DIR/feature-gate-cfg-target-feature.rs:12:12 | 12 | #[cfg_attr(target_feature = "x", x)] //~ ERROR `cfg(target_feature)` is experimental @@ -6,7 +6,7 @@ error: `cfg(target_feature)` is experimental and subject to change (see issue #2 | = help: add #![feature(cfg_target_feature)] to the crate attributes to enable -error: `cfg(target_feature)` is experimental and subject to change (see issue #29717) +error[E0658]: `cfg(target_feature)` is experimental and subject to change (see issue #29717) --> $DIR/feature-gate-cfg-target-feature.rs:11:7 | 11 | #[cfg(target_feature = "x")] //~ ERROR `cfg(target_feature)` is experimental @@ -14,7 +14,7 @@ error: `cfg(target_feature)` is experimental and subject to change (see issue #2 | = help: add #![feature(cfg_target_feature)] to the crate attributes to enable -error: `cfg(target_feature)` is experimental and subject to change (see issue #29717) +error[E0658]: `cfg(target_feature)` is experimental and subject to change (see issue #29717) --> $DIR/feature-gate-cfg-target-feature.rs:15:19 | 15 | #[cfg(not(any(all(target_feature = "x"))))] //~ ERROR `cfg(target_feature)` is experimental @@ -22,7 +22,7 @@ error: `cfg(target_feature)` is experimental and subject to change (see issue #2 | = help: add #![feature(cfg_target_feature)] to the crate attributes to enable -error: `cfg(target_feature)` is experimental and subject to change (see issue #29717) +error[E0658]: `cfg(target_feature)` is experimental and subject to change (see issue #29717) --> $DIR/feature-gate-cfg-target-feature.rs:19:10 | 19 | cfg!(target_feature = "x"); diff --git a/src/test/ui/feature-gate-cfg-target-has-atomic.stderr b/src/test/ui/feature-gate-cfg-target-has-atomic.stderr index 5daf5de7123..ace23b38d2d 100644 --- a/src/test/ui/feature-gate-cfg-target-has-atomic.stderr +++ b/src/test/ui/feature-gate-cfg-target-has-atomic.stderr @@ -1,4 +1,4 @@ -error: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976) +error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976) --> $DIR/feature-gate-cfg-target-has-atomic.rs:23:7 | 23 | #[cfg(target_has_atomic = "8")] @@ -6,7 +6,7 @@ error: `cfg(target_has_atomic)` is experimental and subject to change (see issue | = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable -error: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976) +error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976) --> $DIR/feature-gate-cfg-target-has-atomic.rs:29:7 | 29 | #[cfg(target_has_atomic = "8")] @@ -14,7 +14,7 @@ error: `cfg(target_has_atomic)` is experimental and subject to change (see issue | = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable -error: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976) +error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976) --> $DIR/feature-gate-cfg-target-has-atomic.rs:34:7 | 34 | #[cfg(target_has_atomic = "16")] @@ -22,7 +22,7 @@ error: `cfg(target_has_atomic)` is experimental and subject to change (see issue | = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable -error: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976) +error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976) --> $DIR/feature-gate-cfg-target-has-atomic.rs:39:7 | 39 | #[cfg(target_has_atomic = "16")] @@ -30,7 +30,7 @@ error: `cfg(target_has_atomic)` is experimental and subject to change (see issue | = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable -error: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976) +error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976) --> $DIR/feature-gate-cfg-target-has-atomic.rs:44:7 | 44 | #[cfg(target_has_atomic = "32")] @@ -38,7 +38,7 @@ error: `cfg(target_has_atomic)` is experimental and subject to change (see issue | = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable -error: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976) +error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976) --> $DIR/feature-gate-cfg-target-has-atomic.rs:49:7 | 49 | #[cfg(target_has_atomic = "32")] @@ -46,7 +46,7 @@ error: `cfg(target_has_atomic)` is experimental and subject to change (see issue | = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable -error: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976) +error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976) --> $DIR/feature-gate-cfg-target-has-atomic.rs:54:7 | 54 | #[cfg(target_has_atomic = "64")] @@ -54,7 +54,7 @@ error: `cfg(target_has_atomic)` is experimental and subject to change (see issue | = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable -error: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976) +error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976) --> $DIR/feature-gate-cfg-target-has-atomic.rs:59:7 | 59 | #[cfg(target_has_atomic = "64")] @@ -62,7 +62,7 @@ error: `cfg(target_has_atomic)` is experimental and subject to change (see issue | = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable -error: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976) +error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976) --> $DIR/feature-gate-cfg-target-has-atomic.rs:64:7 | 64 | #[cfg(target_has_atomic = "ptr")] @@ -70,7 +70,7 @@ error: `cfg(target_has_atomic)` is experimental and subject to change (see issue | = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable -error: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976) +error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976) --> $DIR/feature-gate-cfg-target-has-atomic.rs:69:7 | 69 | #[cfg(target_has_atomic = "ptr")] @@ -78,7 +78,7 @@ error: `cfg(target_has_atomic)` is experimental and subject to change (see issue | = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable -error: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976) +error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976) --> $DIR/feature-gate-cfg-target-has-atomic.rs:76:10 | 76 | cfg!(target_has_atomic = "8"); @@ -86,7 +86,7 @@ error: `cfg(target_has_atomic)` is experimental and subject to change (see issue | = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable -error: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976) +error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976) --> $DIR/feature-gate-cfg-target-has-atomic.rs:78:10 | 78 | cfg!(target_has_atomic = "16"); @@ -94,7 +94,7 @@ error: `cfg(target_has_atomic)` is experimental and subject to change (see issue | = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable -error: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976) +error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976) --> $DIR/feature-gate-cfg-target-has-atomic.rs:80:10 | 80 | cfg!(target_has_atomic = "32"); @@ -102,7 +102,7 @@ error: `cfg(target_has_atomic)` is experimental and subject to change (see issue | = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable -error: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976) +error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976) --> $DIR/feature-gate-cfg-target-has-atomic.rs:82:10 | 82 | cfg!(target_has_atomic = "64"); @@ -110,7 +110,7 @@ error: `cfg(target_has_atomic)` is experimental and subject to change (see issue | = help: add #![feature(cfg_target_has_atomic)] to the crate attributes to enable -error: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976) +error[E0658]: `cfg(target_has_atomic)` is experimental and subject to change (see issue #32976) --> $DIR/feature-gate-cfg-target-has-atomic.rs:84:10 | 84 | cfg!(target_has_atomic = "ptr"); diff --git a/src/test/ui/feature-gate-cfg-target-thread-local.stderr b/src/test/ui/feature-gate-cfg-target-thread-local.stderr index 9e2eea6e0a4..a0a03bdcd46 100644 --- a/src/test/ui/feature-gate-cfg-target-thread-local.stderr +++ b/src/test/ui/feature-gate-cfg-target-thread-local.stderr @@ -1,4 +1,4 @@ -error: `cfg(target_thread_local)` is experimental and subject to change (see issue #29594) +error[E0658]: `cfg(target_thread_local)` is experimental and subject to change (see issue #29594) --> $DIR/feature-gate-cfg-target-thread-local.rs:19:16 | 19 | #[cfg_attr(target_thread_local, thread_local)] diff --git a/src/test/ui/feature-gate-cfg-target-vendor.stderr b/src/test/ui/feature-gate-cfg-target-vendor.stderr index c5709600dba..3e4a74636f9 100644 --- a/src/test/ui/feature-gate-cfg-target-vendor.stderr +++ b/src/test/ui/feature-gate-cfg-target-vendor.stderr @@ -1,4 +1,4 @@ -error: `cfg(target_vendor)` is experimental and subject to change (see issue #29718) +error[E0658]: `cfg(target_vendor)` is experimental and subject to change (see issue #29718) --> $DIR/feature-gate-cfg-target-vendor.rs:12:12 | 12 | #[cfg_attr(target_vendor = "x", x)] //~ ERROR `cfg(target_vendor)` is experimental @@ -6,7 +6,7 @@ error: `cfg(target_vendor)` is experimental and subject to change (see issue #29 | = help: add #![feature(cfg_target_vendor)] to the crate attributes to enable -error: `cfg(target_vendor)` is experimental and subject to change (see issue #29718) +error[E0658]: `cfg(target_vendor)` is experimental and subject to change (see issue #29718) --> $DIR/feature-gate-cfg-target-vendor.rs:11:7 | 11 | #[cfg(target_vendor = "x")] //~ ERROR `cfg(target_vendor)` is experimental @@ -14,7 +14,7 @@ error: `cfg(target_vendor)` is experimental and subject to change (see issue #29 | = help: add #![feature(cfg_target_vendor)] to the crate attributes to enable -error: `cfg(target_vendor)` is experimental and subject to change (see issue #29718) +error[E0658]: `cfg(target_vendor)` is experimental and subject to change (see issue #29718) --> $DIR/feature-gate-cfg-target-vendor.rs:15:19 | 15 | #[cfg(not(any(all(target_vendor = "x"))))] //~ ERROR `cfg(target_vendor)` is experimental @@ -22,7 +22,7 @@ error: `cfg(target_vendor)` is experimental and subject to change (see issue #29 | = help: add #![feature(cfg_target_vendor)] to the crate attributes to enable -error: `cfg(target_vendor)` is experimental and subject to change (see issue #29718) +error[E0658]: `cfg(target_vendor)` is experimental and subject to change (see issue #29718) --> $DIR/feature-gate-cfg-target-vendor.rs:19:10 | 19 | cfg!(target_vendor = "x"); diff --git a/src/test/ui/feature-gate-compiler-builtins.stderr b/src/test/ui/feature-gate-compiler-builtins.stderr index ebf42b2bdd8..edb3c5d62ae 100644 --- a/src/test/ui/feature-gate-compiler-builtins.stderr +++ b/src/test/ui/feature-gate-compiler-builtins.stderr @@ -1,4 +1,4 @@ -error: the `#[compiler_builtins]` attribute is used to identify the `compiler_builtins` crate which contains compiler-rt intrinsics and will never be stable +error[E0658]: the `#[compiler_builtins]` attribute is used to identify the `compiler_builtins` crate which contains compiler-rt intrinsics and will never be stable --> $DIR/feature-gate-compiler-builtins.rs:11:1 | 11 | #![compiler_builtins] //~ ERROR the `#[compiler_builtins]` attribute is diff --git a/src/test/ui/feature-gate-concat_idents.stderr b/src/test/ui/feature-gate-concat_idents.stderr index c980668c298..d0a07e3d3c9 100644 --- a/src/test/ui/feature-gate-concat_idents.stderr +++ b/src/test/ui/feature-gate-concat_idents.stderr @@ -1,4 +1,4 @@ -error: `concat_idents` is not stable enough for use and is subject to change (see issue #29599) +error[E0658]: `concat_idents` is not stable enough for use and is subject to change (see issue #29599) --> $DIR/feature-gate-concat_idents.rs:15:13 | 15 | let a = concat_idents!(X, Y_1); //~ ERROR `concat_idents` is not stable @@ -6,7 +6,7 @@ error: `concat_idents` is not stable enough for use and is subject to change (se | = help: add #![feature(concat_idents)] to the crate attributes to enable -error: `concat_idents` is not stable enough for use and is subject to change (see issue #29599) +error[E0658]: `concat_idents` is not stable enough for use and is subject to change (see issue #29599) --> $DIR/feature-gate-concat_idents.rs:16:13 | 16 | let b = concat_idents!(X, Y_2); //~ ERROR `concat_idents` is not stable diff --git a/src/test/ui/feature-gate-concat_idents2.stderr b/src/test/ui/feature-gate-concat_idents2.stderr index 9cfd954eec8..0ef6921c64d 100644 --- a/src/test/ui/feature-gate-concat_idents2.stderr +++ b/src/test/ui/feature-gate-concat_idents2.stderr @@ -1,4 +1,4 @@ -error: `concat_idents` is not stable enough for use and is subject to change (see issue #29599) +error[E0658]: `concat_idents` is not stable enough for use and is subject to change (see issue #29599) --> $DIR/feature-gate-concat_idents2.rs:14:5 | 14 | concat_idents!(a, b); //~ ERROR `concat_idents` is not stable enough diff --git a/src/test/ui/feature-gate-concat_idents3.stderr b/src/test/ui/feature-gate-concat_idents3.stderr index 8399ca3c501..a9a1e493a45 100644 --- a/src/test/ui/feature-gate-concat_idents3.stderr +++ b/src/test/ui/feature-gate-concat_idents3.stderr @@ -1,4 +1,4 @@ -error: `concat_idents` is not stable enough for use and is subject to change (see issue #29599) +error[E0658]: `concat_idents` is not stable enough for use and is subject to change (see issue #29599) --> $DIR/feature-gate-concat_idents3.rs:17:20 | 17 | assert_eq!(10, concat_idents!(X, Y_1)); //~ ERROR `concat_idents` is not stable @@ -6,7 +6,7 @@ error: `concat_idents` is not stable enough for use and is subject to change (se | = help: add #![feature(concat_idents)] to the crate attributes to enable -error: `concat_idents` is not stable enough for use and is subject to change (see issue #29599) +error[E0658]: `concat_idents` is not stable enough for use and is subject to change (see issue #29599) --> $DIR/feature-gate-concat_idents3.rs:18:20 | 18 | assert_eq!(20, concat_idents!(X, Y_2)); //~ ERROR `concat_idents` is not stable diff --git a/src/test/ui/feature-gate-conservative_impl_trait.stderr b/src/test/ui/feature-gate-conservative_impl_trait.stderr index 72a4f52926a..f3d39477387 100644 --- a/src/test/ui/feature-gate-conservative_impl_trait.stderr +++ b/src/test/ui/feature-gate-conservative_impl_trait.stderr @@ -1,4 +1,4 @@ -error: `impl Trait` in return position is experimental (see issue #34511) +error[E0658]: `impl Trait` in return position is experimental (see issue #34511) --> $DIR/feature-gate-conservative_impl_trait.rs:11:13 | 11 | fn foo() -> impl Fn() { || {} } diff --git a/src/test/ui/feature-gate-const_fn.stderr b/src/test/ui/feature-gate-const_fn.stderr index c62229ac71b..ecd1ff5a6c4 100644 --- a/src/test/ui/feature-gate-const_fn.stderr +++ b/src/test/ui/feature-gate-const_fn.stderr @@ -16,7 +16,7 @@ error[E0379]: trait fns cannot be declared const 27 | const fn foo() -> u32 { 0 } //~ ERROR const fn is unstable | ^^^^^ trait fns cannot be const -error: const fn is unstable (see issue #24111) +error[E0658]: const fn is unstable (see issue #24111) --> $DIR/feature-gate-const_fn.rs:13:1 | 13 | const fn foo() -> usize { 0 } //~ ERROR const fn is unstable @@ -24,7 +24,7 @@ error: const fn is unstable (see issue #24111) | = help: add #![feature(const_fn)] to the crate attributes to enable -error: const fn is unstable (see issue #24111) +error[E0658]: const fn is unstable (see issue #24111) --> $DIR/feature-gate-const_fn.rs:16:5 | 16 | const fn foo() -> u32; //~ ERROR const fn is unstable @@ -32,7 +32,7 @@ error: const fn is unstable (see issue #24111) | = help: add #![feature(const_fn)] to the crate attributes to enable -error: const fn is unstable (see issue #24111) +error[E0658]: const fn is unstable (see issue #24111) --> $DIR/feature-gate-const_fn.rs:18:5 | 18 | const fn bar() -> u32 { 0 } //~ ERROR const fn is unstable @@ -40,7 +40,7 @@ error: const fn is unstable (see issue #24111) | = help: add #![feature(const_fn)] to the crate attributes to enable -error: const fn is unstable (see issue #24111) +error[E0658]: const fn is unstable (see issue #24111) --> $DIR/feature-gate-const_fn.rs:23:5 | 23 | const fn baz() -> u32 { 0 } //~ ERROR const fn is unstable @@ -48,7 +48,7 @@ error: const fn is unstable (see issue #24111) | = help: add #![feature(const_fn)] to the crate attributes to enable -error: const fn is unstable (see issue #24111) +error[E0658]: const fn is unstable (see issue #24111) --> $DIR/feature-gate-const_fn.rs:27:5 | 27 | const fn foo() -> u32 { 0 } //~ ERROR const fn is unstable diff --git a/src/test/ui/feature-gate-crate_in_paths.stderr b/src/test/ui/feature-gate-crate_in_paths.stderr index b13c82ecfc9..322a38a996f 100644 --- a/src/test/ui/feature-gate-crate_in_paths.stderr +++ b/src/test/ui/feature-gate-crate_in_paths.stderr @@ -1,4 +1,4 @@ -error: `crate` in paths is experimental (see issue #45477) +error[E0658]: `crate` in paths is experimental (see issue #45477) --> $DIR/feature-gate-crate_in_paths.rs:14:15 | 14 | let _ = ::crate::S; //~ ERROR `crate` in paths is experimental diff --git a/src/test/ui/feature-gate-crate_visibility_modifier.stderr b/src/test/ui/feature-gate-crate_visibility_modifier.stderr index 0862744b87b..fadc76bc0c0 100644 --- a/src/test/ui/feature-gate-crate_visibility_modifier.stderr +++ b/src/test/ui/feature-gate-crate_visibility_modifier.stderr @@ -1,4 +1,4 @@ -error: `crate` visibility modifier is experimental (see issue #45388) +error[E0658]: `crate` visibility modifier is experimental (see issue #45388) --> $DIR/feature-gate-crate_visibility_modifier.rs:11:1 | 11 | crate struct Bender { //~ ERROR `crate` visibility modifier is experimental diff --git a/src/test/ui/feature-gate-custom_attribute.stderr b/src/test/ui/feature-gate-custom_attribute.stderr index 866ebfe8f2f..f4d726c8c41 100644 --- a/src/test/ui/feature-gate-custom_attribute.stderr +++ b/src/test/ui/feature-gate-custom_attribute.stderr @@ -1,4 +1,4 @@ -error: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) +error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) --> $DIR/feature-gate-custom_attribute.rs:17:1 | 17 | #[fake_attr] //~ ERROR attribute `fake_attr` is currently unknown @@ -6,7 +6,7 @@ error: The attribute `fake_attr` is currently unknown to the compiler and may ha | = help: add #![feature(custom_attribute)] to the crate attributes to enable -error: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) +error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) --> $DIR/feature-gate-custom_attribute.rs:18:1 | 18 | #[fake_attr(100)] //~ ERROR attribute `fake_attr` is currently unknown @@ -14,7 +14,7 @@ error: The attribute `fake_attr` is currently unknown to the compiler and may ha | = help: add #![feature(custom_attribute)] to the crate attributes to enable -error: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) +error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) --> $DIR/feature-gate-custom_attribute.rs:19:1 | 19 | #[fake_attr(1, 2, 3)] //~ ERROR attribute `fake_attr` is currently unknown @@ -22,7 +22,7 @@ error: The attribute `fake_attr` is currently unknown to the compiler and may ha | = help: add #![feature(custom_attribute)] to the crate attributes to enable -error: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) +error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) --> $DIR/feature-gate-custom_attribute.rs:20:1 | 20 | #[fake_attr("hello")] //~ ERROR attribute `fake_attr` is currently unknown @@ -30,7 +30,7 @@ error: The attribute `fake_attr` is currently unknown to the compiler and may ha | = help: add #![feature(custom_attribute)] to the crate attributes to enable -error: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) +error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) --> $DIR/feature-gate-custom_attribute.rs:21:1 | 21 | #[fake_attr(name = "hello")] //~ ERROR attribute `fake_attr` is currently unknown @@ -38,7 +38,7 @@ error: The attribute `fake_attr` is currently unknown to the compiler and may ha | = help: add #![feature(custom_attribute)] to the crate attributes to enable -error: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) +error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) --> $DIR/feature-gate-custom_attribute.rs:22:1 | 22 | #[fake_attr(1, "hi", key = 12, true, false)] //~ ERROR attribute `fake_attr` is currently unknown @@ -46,7 +46,7 @@ error: The attribute `fake_attr` is currently unknown to the compiler and may ha | = help: add #![feature(custom_attribute)] to the crate attributes to enable -error: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) +error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) --> $DIR/feature-gate-custom_attribute.rs:23:1 | 23 | #[fake_attr(key = "hello", val = 10)] //~ ERROR attribute `fake_attr` is currently unknown @@ -54,7 +54,7 @@ error: The attribute `fake_attr` is currently unknown to the compiler and may ha | = help: add #![feature(custom_attribute)] to the crate attributes to enable -error: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) +error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) --> $DIR/feature-gate-custom_attribute.rs:24:1 | 24 | #[fake_attr(key("hello"), val(10))] //~ ERROR attribute `fake_attr` is currently unknown @@ -62,7 +62,7 @@ error: The attribute `fake_attr` is currently unknown to the compiler and may ha | = help: add #![feature(custom_attribute)] to the crate attributes to enable -error: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) +error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) --> $DIR/feature-gate-custom_attribute.rs:25:1 | 25 | #[fake_attr(enabled = true, disabled = false)] //~ ERROR attribute `fake_attr` is currently unknown @@ -70,7 +70,7 @@ error: The attribute `fake_attr` is currently unknown to the compiler and may ha | = help: add #![feature(custom_attribute)] to the crate attributes to enable -error: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) +error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) --> $DIR/feature-gate-custom_attribute.rs:26:1 | 26 | #[fake_attr(true)] //~ ERROR attribute `fake_attr` is currently unknown @@ -78,7 +78,7 @@ error: The attribute `fake_attr` is currently unknown to the compiler and may ha | = help: add #![feature(custom_attribute)] to the crate attributes to enable -error: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) +error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) --> $DIR/feature-gate-custom_attribute.rs:27:1 | 27 | #[fake_attr(pi = 3.14159)] //~ ERROR attribute `fake_attr` is currently unknown @@ -86,7 +86,7 @@ error: The attribute `fake_attr` is currently unknown to the compiler and may ha | = help: add #![feature(custom_attribute)] to the crate attributes to enable -error: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) +error[E0658]: The attribute `fake_attr` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) --> $DIR/feature-gate-custom_attribute.rs:28:1 | 28 | #[fake_attr(b"hi")] //~ ERROR attribute `fake_attr` is currently unknown @@ -94,7 +94,7 @@ error: The attribute `fake_attr` is currently unknown to the compiler and may ha | = help: add #![feature(custom_attribute)] to the crate attributes to enable -error: The attribute `fake_doc` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) +error[E0658]: The attribute `fake_doc` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) --> $DIR/feature-gate-custom_attribute.rs:29:1 | 29 | #[fake_doc(r"doc")] //~ ERROR attribute `fake_doc` is currently unknown diff --git a/src/test/ui/feature-gate-custom_attribute2.stderr b/src/test/ui/feature-gate-custom_attribute2.stderr index 3e4ea58a7a3..08878e17204 100644 --- a/src/test/ui/feature-gate-custom_attribute2.stderr +++ b/src/test/ui/feature-gate-custom_attribute2.stderr @@ -1,4 +1,4 @@ -error: The attribute `lt_struct` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) +error[E0658]: The attribute `lt_struct` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) --> $DIR/feature-gate-custom_attribute2.rs:23:13 | 23 | struct StLt<#[lt_struct] 'a>(&'a u32); @@ -6,7 +6,7 @@ error: The attribute `lt_struct` is currently unknown to the compiler and may ha | = help: add #![feature(custom_attribute)] to the crate attributes to enable -error: The attribute `ty_struct` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) +error[E0658]: The attribute `ty_struct` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) --> $DIR/feature-gate-custom_attribute2.rs:25:13 | 25 | struct StTy<#[ty_struct] I>(I); @@ -14,7 +14,7 @@ error: The attribute `ty_struct` is currently unknown to the compiler and may ha | = help: add #![feature(custom_attribute)] to the crate attributes to enable -error: The attribute `lt_enum` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) +error[E0658]: The attribute `lt_enum` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) --> $DIR/feature-gate-custom_attribute2.rs:28:11 | 28 | enum EnLt<#[lt_enum] 'b> { A(&'b u32), B } @@ -22,7 +22,7 @@ error: The attribute `lt_enum` is currently unknown to the compiler and may have | = help: add #![feature(custom_attribute)] to the crate attributes to enable -error: The attribute `ty_enum` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) +error[E0658]: The attribute `ty_enum` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) --> $DIR/feature-gate-custom_attribute2.rs:30:11 | 30 | enum EnTy<#[ty_enum] J> { A(J), B } @@ -30,7 +30,7 @@ error: The attribute `ty_enum` is currently unknown to the compiler and may have | = help: add #![feature(custom_attribute)] to the crate attributes to enable -error: The attribute `lt_trait` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) +error[E0658]: The attribute `lt_trait` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) --> $DIR/feature-gate-custom_attribute2.rs:33:12 | 33 | trait TrLt<#[lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; } @@ -38,7 +38,7 @@ error: The attribute `lt_trait` is currently unknown to the compiler and may hav | = help: add #![feature(custom_attribute)] to the crate attributes to enable -error: The attribute `ty_trait` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) +error[E0658]: The attribute `ty_trait` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) --> $DIR/feature-gate-custom_attribute2.rs:35:12 | 35 | trait TrTy<#[ty_trait] K> { fn foo(&self, _: K); } @@ -46,7 +46,7 @@ error: The attribute `ty_trait` is currently unknown to the compiler and may hav | = help: add #![feature(custom_attribute)] to the crate attributes to enable -error: The attribute `lt_type` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) +error[E0658]: The attribute `lt_type` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) --> $DIR/feature-gate-custom_attribute2.rs:38:11 | 38 | type TyLt<#[lt_type] 'd> = &'d u32; @@ -54,7 +54,7 @@ error: The attribute `lt_type` is currently unknown to the compiler and may have | = help: add #![feature(custom_attribute)] to the crate attributes to enable -error: The attribute `ty_type` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) +error[E0658]: The attribute `ty_type` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) --> $DIR/feature-gate-custom_attribute2.rs:40:11 | 40 | type TyTy<#[ty_type] L> = (L, ); @@ -62,7 +62,7 @@ error: The attribute `ty_type` is currently unknown to the compiler and may have | = help: add #![feature(custom_attribute)] to the crate attributes to enable -error: The attribute `lt_inherent` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) +error[E0658]: The attribute `lt_inherent` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) --> $DIR/feature-gate-custom_attribute2.rs:43:6 | 43 | impl<#[lt_inherent] 'e> StLt<'e> { } @@ -70,7 +70,7 @@ error: The attribute `lt_inherent` is currently unknown to the compiler and may | = help: add #![feature(custom_attribute)] to the crate attributes to enable -error: The attribute `ty_inherent` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) +error[E0658]: The attribute `ty_inherent` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) --> $DIR/feature-gate-custom_attribute2.rs:45:6 | 45 | impl<#[ty_inherent] M> StTy<M> { } @@ -78,7 +78,7 @@ error: The attribute `ty_inherent` is currently unknown to the compiler and may | = help: add #![feature(custom_attribute)] to the crate attributes to enable -error: The attribute `lt_impl_for` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) +error[E0658]: The attribute `lt_impl_for` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) --> $DIR/feature-gate-custom_attribute2.rs:48:6 | 48 | impl<#[lt_impl_for] 'f> TrLt<'f> for StLt<'f> { @@ -86,7 +86,7 @@ error: The attribute `lt_impl_for` is currently unknown to the compiler and may | = help: add #![feature(custom_attribute)] to the crate attributes to enable -error: The attribute `ty_impl_for` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) +error[E0658]: The attribute `ty_impl_for` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) --> $DIR/feature-gate-custom_attribute2.rs:52:6 | 52 | impl<#[ty_impl_for] N> TrTy<N> for StTy<N> { @@ -94,7 +94,7 @@ error: The attribute `ty_impl_for` is currently unknown to the compiler and may | = help: add #![feature(custom_attribute)] to the crate attributes to enable -error: The attribute `lt_fn` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) +error[E0658]: The attribute `lt_fn` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) --> $DIR/feature-gate-custom_attribute2.rs:57:9 | 57 | fn f_lt<#[lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } } @@ -102,7 +102,7 @@ error: The attribute `lt_fn` is currently unknown to the compiler and may have m | = help: add #![feature(custom_attribute)] to the crate attributes to enable -error: The attribute `ty_fn` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) +error[E0658]: The attribute `ty_fn` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) --> $DIR/feature-gate-custom_attribute2.rs:59:9 | 59 | fn f_ty<#[ty_fn] O>(_: O) { } @@ -110,7 +110,7 @@ error: The attribute `ty_fn` is currently unknown to the compiler and may have m | = help: add #![feature(custom_attribute)] to the crate attributes to enable -error: The attribute `lt_meth` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) +error[E0658]: The attribute `lt_meth` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) --> $DIR/feature-gate-custom_attribute2.rs:63:13 | 63 | fn m_lt<#[lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } } @@ -118,7 +118,7 @@ error: The attribute `lt_meth` is currently unknown to the compiler and may have | = help: add #![feature(custom_attribute)] to the crate attributes to enable -error: The attribute `ty_meth` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) +error[E0658]: The attribute `ty_meth` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) --> $DIR/feature-gate-custom_attribute2.rs:65:13 | 65 | fn m_ty<#[ty_meth] P>(_: P) { } @@ -126,7 +126,7 @@ error: The attribute `ty_meth` is currently unknown to the compiler and may have | = help: add #![feature(custom_attribute)] to the crate attributes to enable -error: The attribute `lt_hof` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) +error[E0658]: The attribute `lt_hof` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) --> $DIR/feature-gate-custom_attribute2.rs:70:19 | 70 | where Q: for <#[lt_hof] 'i> Fn(&'i [u32]) -> &'i u32 diff --git a/src/test/ui/feature-gate-custom_derive.stderr b/src/test/ui/feature-gate-custom_derive.stderr index e806c808631..86066285a55 100644 --- a/src/test/ui/feature-gate-custom_derive.stderr +++ b/src/test/ui/feature-gate-custom_derive.stderr @@ -1,4 +1,4 @@ -error: attributes of the form `#[derive_*]` are reserved for the compiler (see issue #29644) +error[E0658]: attributes of the form `#[derive_*]` are reserved for the compiler (see issue #29644) --> $DIR/feature-gate-custom_derive.rs:11:1 | 11 | #[derive_Clone] diff --git a/src/test/ui/feature-gate-decl_macro.stderr b/src/test/ui/feature-gate-decl_macro.stderr index 49ce4eb10b6..c7144f09bd6 100644 --- a/src/test/ui/feature-gate-decl_macro.stderr +++ b/src/test/ui/feature-gate-decl_macro.stderr @@ -1,4 +1,4 @@ -error: `macro` is experimental (see issue #39412) +error[E0658]: `macro` is experimental (see issue #39412) --> $DIR/feature-gate-decl_macro.rs:13:1 | 13 | macro m() {} //~ ERROR `macro` is experimental (see issue #39412) diff --git a/src/test/ui/feature-gate-doc_cfg.stderr b/src/test/ui/feature-gate-doc_cfg.stderr index c2d8a934ab8..e009e0bc3c4 100644 --- a/src/test/ui/feature-gate-doc_cfg.stderr +++ b/src/test/ui/feature-gate-doc_cfg.stderr @@ -1,4 +1,4 @@ -error: #[doc(cfg(...))] is experimental (see issue #43781) +error[E0658]: #[doc(cfg(...))] is experimental (see issue #43781) --> $DIR/feature-gate-doc_cfg.rs:11:1 | 11 | #[doc(cfg(unix))] //~ ERROR: #[doc(cfg(...))] is experimental diff --git a/src/test/ui/feature-gate-doc_masked.stderr b/src/test/ui/feature-gate-doc_masked.stderr index 11020765304..ee2d384e998 100644 --- a/src/test/ui/feature-gate-doc_masked.stderr +++ b/src/test/ui/feature-gate-doc_masked.stderr @@ -1,4 +1,4 @@ -error: #[doc(masked)] is experimental (see issue #44027) +error[E0658]: #[doc(masked)] is experimental (see issue #44027) --> $DIR/feature-gate-doc_masked.rs:11:1 | 11 | #[doc(masked)] //~ ERROR: #[doc(masked)] is experimental diff --git a/src/test/ui/feature-gate-doc_spotlight.stderr b/src/test/ui/feature-gate-doc_spotlight.stderr index b743a1e94bc..36d854892be 100644 --- a/src/test/ui/feature-gate-doc_spotlight.stderr +++ b/src/test/ui/feature-gate-doc_spotlight.stderr @@ -1,4 +1,4 @@ -error: #[doc(spotlight)] is experimental (see issue #45040) +error[E0658]: #[doc(spotlight)] is experimental (see issue #45040) --> $DIR/feature-gate-doc_spotlight.rs:11:1 | 11 | #[doc(spotlight)] //~ ERROR: #[doc(spotlight)] is experimental diff --git a/src/test/ui/feature-gate-dotdoteq_in_patterns.stderr b/src/test/ui/feature-gate-dotdoteq_in_patterns.stderr index 5319dcef2d5..2d26c6ae8eb 100644 --- a/src/test/ui/feature-gate-dotdoteq_in_patterns.stderr +++ b/src/test/ui/feature-gate-dotdoteq_in_patterns.stderr @@ -1,4 +1,4 @@ -error: `..=` syntax in patterns is experimental (see issue #28237) +error[E0658]: `..=` syntax in patterns is experimental (see issue #28237) --> $DIR/feature-gate-dotdoteq_in_patterns.rs:13:9 | 13 | 0 ..= 3 => {} //~ ERROR `..=` syntax in patterns is experimental diff --git a/src/test/ui/feature-gate-dropck-ugeh.stderr b/src/test/ui/feature-gate-dropck-ugeh.stderr index b030ebcd881..cdeca7026b0 100644 --- a/src/test/ui/feature-gate-dropck-ugeh.stderr +++ b/src/test/ui/feature-gate-dropck-ugeh.stderr @@ -1,4 +1,4 @@ -error: unsafe_destructor_blind_to_params has been replaced by may_dangle and will be removed in the future (see issue #28498) +error[E0658]: unsafe_destructor_blind_to_params has been replaced by may_dangle and will be removed in the future (see issue #28498) --> $DIR/feature-gate-dropck-ugeh.rs:29:5 | 29 | #[unsafe_destructor_blind_to_params] // This is the UGEH attribute diff --git a/src/test/ui/feature-gate-dyn-trait.stderr b/src/test/ui/feature-gate-dyn-trait.stderr index 28ecfdf1131..d6ba4b8ad66 100644 --- a/src/test/ui/feature-gate-dyn-trait.stderr +++ b/src/test/ui/feature-gate-dyn-trait.stderr @@ -1,4 +1,4 @@ -error: `dyn Trait` syntax is unstable (see issue #44662) +error[E0658]: `dyn Trait` syntax is unstable (see issue #44662) --> $DIR/feature-gate-dyn-trait.rs:12:14 | 12 | type A = Box<dyn Trait>; //~ ERROR `dyn Trait` syntax is unstable diff --git a/src/test/ui/feature-gate-exclusive-range-pattern.stderr b/src/test/ui/feature-gate-exclusive-range-pattern.stderr index c6785d6f29d..3185281ce4b 100644 --- a/src/test/ui/feature-gate-exclusive-range-pattern.stderr +++ b/src/test/ui/feature-gate-exclusive-range-pattern.stderr @@ -1,4 +1,4 @@ -error: exclusive range pattern syntax is experimental (see issue #37854) +error[E0658]: exclusive range pattern syntax is experimental (see issue #37854) --> $DIR/feature-gate-exclusive-range-pattern.rs:13:9 | 13 | 0 .. 3 => {} //~ ERROR exclusive range pattern syntax is experimental diff --git a/src/test/ui/feature-gate-extern_in_paths.stderr b/src/test/ui/feature-gate-extern_in_paths.stderr index ac68e79e1ca..022e53b6be0 100644 --- a/src/test/ui/feature-gate-extern_in_paths.stderr +++ b/src/test/ui/feature-gate-extern_in_paths.stderr @@ -1,4 +1,4 @@ -error: `extern` in paths is experimental (see issue #44660) +error[E0658]: `extern` in paths is experimental (see issue #44660) --> $DIR/feature-gate-extern_in_paths.rs:14:13 | 14 | let _ = extern::std::vec::Vec::new(); //~ ERROR `extern` in paths is experimental diff --git a/src/test/ui/feature-gate-extern_types.stderr b/src/test/ui/feature-gate-extern_types.stderr index 3815862e899..71caa37963f 100644 --- a/src/test/ui/feature-gate-extern_types.stderr +++ b/src/test/ui/feature-gate-extern_types.stderr @@ -1,4 +1,4 @@ -error: extern types are experimental (see issue #43467) +error[E0658]: extern types are experimental (see issue #43467) --> $DIR/feature-gate-extern_types.rs:12:5 | 12 | type T; //~ ERROR extern types are experimental diff --git a/src/test/ui/feature-gate-external_doc.stderr b/src/test/ui/feature-gate-external_doc.stderr index 5479ab8bc91..db6c99bceed 100644 --- a/src/test/ui/feature-gate-external_doc.stderr +++ b/src/test/ui/feature-gate-external_doc.stderr @@ -1,4 +1,4 @@ -error: #[doc(include = "...")] is experimental (see issue #44732) +error[E0658]: #[doc(include = "...")] is experimental (see issue #44732) --> $DIR/feature-gate-external_doc.rs:11:1 | 11 | #[doc(include="asdf.md")] //~ ERROR: #[doc(include = "...")] is experimental diff --git a/src/test/ui/feature-gate-fundamental.stderr b/src/test/ui/feature-gate-fundamental.stderr index 0fc75ee30b9..28d8a80e602 100644 --- a/src/test/ui/feature-gate-fundamental.stderr +++ b/src/test/ui/feature-gate-fundamental.stderr @@ -1,4 +1,4 @@ -error: the `#[fundamental]` attribute is an experimental feature (see issue #29635) +error[E0658]: the `#[fundamental]` attribute is an experimental feature (see issue #29635) --> $DIR/feature-gate-fundamental.rs:11:1 | 11 | #[fundamental] //~ ERROR the `#[fundamental]` attribute is an experimental feature diff --git a/src/test/ui/feature-gate-generators.stderr b/src/test/ui/feature-gate-generators.stderr index 82acb401338..f559227f717 100644 --- a/src/test/ui/feature-gate-generators.stderr +++ b/src/test/ui/feature-gate-generators.stderr @@ -1,4 +1,4 @@ -error: yield syntax is experimental +error[E0658]: yield syntax is experimental --> $DIR/feature-gate-generators.rs:12:5 | 12 | yield true; //~ ERROR yield syntax is experimental diff --git a/src/test/ui/feature-gate-generic_associated_types.stderr b/src/test/ui/feature-gate-generic_associated_types.stderr index 7b2507e1fb1..c047914fb3b 100644 --- a/src/test/ui/feature-gate-generic_associated_types.stderr +++ b/src/test/ui/feature-gate-generic_associated_types.stderr @@ -1,4 +1,4 @@ -error: generic associated types are unstable (see issue #44265) +error[E0658]: generic associated types are unstable (see issue #44265) --> $DIR/feature-gate-generic_associated_types.rs:14:5 | 14 | type Pointer<T>: Deref<Target = T>; @@ -6,7 +6,7 @@ error: generic associated types are unstable (see issue #44265) | = help: add #![feature(generic_associated_types)] to the crate attributes to enable -error: generic associated types are unstable (see issue #44265) +error[E0658]: generic associated types are unstable (see issue #44265) --> $DIR/feature-gate-generic_associated_types.rs:16:5 | 16 | type Pointer2<T>: Deref<Target = T> where T: Clone, U: Clone; @@ -14,7 +14,7 @@ error: generic associated types are unstable (see issue #44265) | = help: add #![feature(generic_associated_types)] to the crate attributes to enable -error: generic associated types are unstable (see issue #44265) +error[E0658]: generic associated types are unstable (see issue #44265) --> $DIR/feature-gate-generic_associated_types.rs:22:5 | 22 | type Pointer<usize> = Box<usize>; @@ -22,7 +22,7 @@ error: generic associated types are unstable (see issue #44265) | = help: add #![feature(generic_associated_types)] to the crate attributes to enable -error: generic associated types are unstable (see issue #44265) +error[E0658]: generic associated types are unstable (see issue #44265) --> $DIR/feature-gate-generic_associated_types.rs:24:5 | 24 | type Pointer2<u32> = Box<u32>; diff --git a/src/test/ui/feature-gate-generic_param_attrs.stderr b/src/test/ui/feature-gate-generic_param_attrs.stderr index da2e6403029..a18d104cc2b 100644 --- a/src/test/ui/feature-gate-generic_param_attrs.stderr +++ b/src/test/ui/feature-gate-generic_param_attrs.stderr @@ -1,4 +1,4 @@ -error: attributes on lifetime bindings are experimental (see issue #34761) +error[E0658]: attributes on lifetime bindings are experimental (see issue #34761) --> $DIR/feature-gate-generic_param_attrs.rs:22:13 | 22 | struct StLt<#[rustc_lt_struct] 'a>(&'a u32); @@ -6,7 +6,7 @@ error: attributes on lifetime bindings are experimental (see issue #34761) | = help: add #![feature(generic_param_attrs)] to the crate attributes to enable -error: attributes on type parameter bindings are experimental (see issue #34761) +error[E0658]: attributes on type parameter bindings are experimental (see issue #34761) --> $DIR/feature-gate-generic_param_attrs.rs:24:13 | 24 | struct StTy<#[rustc_ty_struct] I>(I); @@ -14,7 +14,7 @@ error: attributes on type parameter bindings are experimental (see issue #34761) | = help: add #![feature(generic_param_attrs)] to the crate attributes to enable -error: attributes on lifetime bindings are experimental (see issue #34761) +error[E0658]: attributes on lifetime bindings are experimental (see issue #34761) --> $DIR/feature-gate-generic_param_attrs.rs:27:11 | 27 | enum EnLt<#[rustc_lt_enum] 'b> { A(&'b u32), B } @@ -22,7 +22,7 @@ error: attributes on lifetime bindings are experimental (see issue #34761) | = help: add #![feature(generic_param_attrs)] to the crate attributes to enable -error: attributes on type parameter bindings are experimental (see issue #34761) +error[E0658]: attributes on type parameter bindings are experimental (see issue #34761) --> $DIR/feature-gate-generic_param_attrs.rs:29:11 | 29 | enum EnTy<#[rustc_ty_enum] J> { A(J), B } @@ -30,7 +30,7 @@ error: attributes on type parameter bindings are experimental (see issue #34761) | = help: add #![feature(generic_param_attrs)] to the crate attributes to enable -error: attributes on lifetime bindings are experimental (see issue #34761) +error[E0658]: attributes on lifetime bindings are experimental (see issue #34761) --> $DIR/feature-gate-generic_param_attrs.rs:32:12 | 32 | trait TrLt<#[rustc_lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; } @@ -38,7 +38,7 @@ error: attributes on lifetime bindings are experimental (see issue #34761) | = help: add #![feature(generic_param_attrs)] to the crate attributes to enable -error: attributes on type parameter bindings are experimental (see issue #34761) +error[E0658]: attributes on type parameter bindings are experimental (see issue #34761) --> $DIR/feature-gate-generic_param_attrs.rs:34:12 | 34 | trait TrTy<#[rustc_ty_trait] K> { fn foo(&self, _: K); } @@ -46,7 +46,7 @@ error: attributes on type parameter bindings are experimental (see issue #34761) | = help: add #![feature(generic_param_attrs)] to the crate attributes to enable -error: attributes on lifetime bindings are experimental (see issue #34761) +error[E0658]: attributes on lifetime bindings are experimental (see issue #34761) --> $DIR/feature-gate-generic_param_attrs.rs:37:11 | 37 | type TyLt<#[rustc_lt_type] 'd> = &'d u32; @@ -54,7 +54,7 @@ error: attributes on lifetime bindings are experimental (see issue #34761) | = help: add #![feature(generic_param_attrs)] to the crate attributes to enable -error: attributes on type parameter bindings are experimental (see issue #34761) +error[E0658]: attributes on type parameter bindings are experimental (see issue #34761) --> $DIR/feature-gate-generic_param_attrs.rs:39:11 | 39 | type TyTy<#[rustc_ty_type] L> = (L, ); @@ -62,7 +62,7 @@ error: attributes on type parameter bindings are experimental (see issue #34761) | = help: add #![feature(generic_param_attrs)] to the crate attributes to enable -error: attributes on lifetime bindings are experimental (see issue #34761) +error[E0658]: attributes on lifetime bindings are experimental (see issue #34761) --> $DIR/feature-gate-generic_param_attrs.rs:42:6 | 42 | impl<#[rustc_lt_inherent] 'e> StLt<'e> { } @@ -70,7 +70,7 @@ error: attributes on lifetime bindings are experimental (see issue #34761) | = help: add #![feature(generic_param_attrs)] to the crate attributes to enable -error: attributes on type parameter bindings are experimental (see issue #34761) +error[E0658]: attributes on type parameter bindings are experimental (see issue #34761) --> $DIR/feature-gate-generic_param_attrs.rs:44:6 | 44 | impl<#[rustc_ty_inherent] M> StTy<M> { } @@ -78,7 +78,7 @@ error: attributes on type parameter bindings are experimental (see issue #34761) | = help: add #![feature(generic_param_attrs)] to the crate attributes to enable -error: attributes on lifetime bindings are experimental (see issue #34761) +error[E0658]: attributes on lifetime bindings are experimental (see issue #34761) --> $DIR/feature-gate-generic_param_attrs.rs:47:6 | 47 | impl<#[rustc_lt_impl_for] 'f> TrLt<'f> for StLt<'f> { @@ -86,7 +86,7 @@ error: attributes on lifetime bindings are experimental (see issue #34761) | = help: add #![feature(generic_param_attrs)] to the crate attributes to enable -error: attributes on type parameter bindings are experimental (see issue #34761) +error[E0658]: attributes on type parameter bindings are experimental (see issue #34761) --> $DIR/feature-gate-generic_param_attrs.rs:51:6 | 51 | impl<#[rustc_ty_impl_for] N> TrTy<N> for StTy<N> { @@ -94,7 +94,7 @@ error: attributes on type parameter bindings are experimental (see issue #34761) | = help: add #![feature(generic_param_attrs)] to the crate attributes to enable -error: attributes on lifetime bindings are experimental (see issue #34761) +error[E0658]: attributes on lifetime bindings are experimental (see issue #34761) --> $DIR/feature-gate-generic_param_attrs.rs:56:9 | 56 | fn f_lt<#[rustc_lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } } @@ -102,7 +102,7 @@ error: attributes on lifetime bindings are experimental (see issue #34761) | = help: add #![feature(generic_param_attrs)] to the crate attributes to enable -error: attributes on type parameter bindings are experimental (see issue #34761) +error[E0658]: attributes on type parameter bindings are experimental (see issue #34761) --> $DIR/feature-gate-generic_param_attrs.rs:58:9 | 58 | fn f_ty<#[rustc_ty_fn] O>(_: O) { } @@ -110,7 +110,7 @@ error: attributes on type parameter bindings are experimental (see issue #34761) | = help: add #![feature(generic_param_attrs)] to the crate attributes to enable -error: attributes on lifetime bindings are experimental (see issue #34761) +error[E0658]: attributes on lifetime bindings are experimental (see issue #34761) --> $DIR/feature-gate-generic_param_attrs.rs:62:13 | 62 | fn m_lt<#[rustc_lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } } @@ -118,7 +118,7 @@ error: attributes on lifetime bindings are experimental (see issue #34761) | = help: add #![feature(generic_param_attrs)] to the crate attributes to enable -error: attributes on type parameter bindings are experimental (see issue #34761) +error[E0658]: attributes on type parameter bindings are experimental (see issue #34761) --> $DIR/feature-gate-generic_param_attrs.rs:64:13 | 64 | fn m_ty<#[rustc_ty_meth] P>(_: P) { } @@ -126,7 +126,7 @@ error: attributes on type parameter bindings are experimental (see issue #34761) | = help: add #![feature(generic_param_attrs)] to the crate attributes to enable -error: attributes on lifetime bindings are experimental (see issue #34761) +error[E0658]: attributes on lifetime bindings are experimental (see issue #34761) --> $DIR/feature-gate-generic_param_attrs.rs:69:19 | 69 | where Q: for <#[rustc_lt_hof] 'i> Fn(&'i [u32]) -> &'i u32 diff --git a/src/test/ui/feature-gate-global_allocator.stderr b/src/test/ui/feature-gate-global_allocator.stderr index 7e6c4288ff3..8d82f6ee9e3 100644 --- a/src/test/ui/feature-gate-global_allocator.stderr +++ b/src/test/ui/feature-gate-global_allocator.stderr @@ -1,4 +1,4 @@ -error: the `#[global_allocator]` attribute is an experimental feature +error[E0658]: the `#[global_allocator]` attribute is an experimental feature --> $DIR/feature-gate-global_allocator.rs:11:1 | 11 | #[global_allocator] //~ ERROR: attribute is an experimental feature diff --git a/src/test/ui/feature-gate-global_asm.stderr b/src/test/ui/feature-gate-global_asm.stderr index de0ba1a7b32..ca946579f5d 100644 --- a/src/test/ui/feature-gate-global_asm.stderr +++ b/src/test/ui/feature-gate-global_asm.stderr @@ -1,4 +1,4 @@ -error: `global_asm!` is not stable enough for use and is subject to change (see issue #35119) +error[E0658]: `global_asm!` is not stable enough for use and is subject to change (see issue #35119) --> $DIR/feature-gate-global_asm.rs:11:1 | 11 | global_asm!(""); //~ ERROR `global_asm!` is not stable diff --git a/src/test/ui/feature-gate-i128_type.stderr b/src/test/ui/feature-gate-i128_type.stderr index df623cac49a..06fdeadbbf6 100644 --- a/src/test/ui/feature-gate-i128_type.stderr +++ b/src/test/ui/feature-gate-i128_type.stderr @@ -1,4 +1,4 @@ -error: 128-bit integers are not stable (see issue #35118) +error[E0658]: 128-bit integers are not stable (see issue #35118) --> $DIR/feature-gate-i128_type.rs:12:5 | 12 | 0i128; //~ ERROR 128-bit integers are not stable @@ -6,7 +6,7 @@ error: 128-bit integers are not stable (see issue #35118) | = help: add #![feature(i128_type)] to the crate attributes to enable -error: 128-bit integers are not stable (see issue #35118) +error[E0658]: 128-bit integers are not stable (see issue #35118) --> $DIR/feature-gate-i128_type.rs:16:5 | 16 | 0u128; //~ ERROR 128-bit integers are not stable diff --git a/src/test/ui/feature-gate-i128_type2.stderr b/src/test/ui/feature-gate-i128_type2.stderr index 26653a5739b..ee81a269214 100644 --- a/src/test/ui/feature-gate-i128_type2.stderr +++ b/src/test/ui/feature-gate-i128_type2.stderr @@ -1,4 +1,4 @@ -error: 128-bit type is unstable (see issue #35118) +error[E0658]: 128-bit type is unstable (see issue #35118) --> $DIR/feature-gate-i128_type2.rs:13:15 | 13 | fn test1() -> i128 { //~ ERROR 128-bit type is unstable @@ -6,7 +6,7 @@ error: 128-bit type is unstable (see issue #35118) | = help: add #![feature(i128_type)] to the crate attributes to enable -error: 128-bit type is unstable (see issue #35118) +error[E0658]: 128-bit type is unstable (see issue #35118) --> $DIR/feature-gate-i128_type2.rs:17:17 | 17 | fn test1_2() -> u128 { //~ ERROR 128-bit type is unstable @@ -14,7 +14,7 @@ error: 128-bit type is unstable (see issue #35118) | = help: add #![feature(i128_type)] to the crate attributes to enable -error: 128-bit type is unstable (see issue #35118) +error[E0658]: 128-bit type is unstable (see issue #35118) --> $DIR/feature-gate-i128_type2.rs:22:12 | 22 | let x: i128 = 0; //~ ERROR 128-bit type is unstable @@ -22,7 +22,7 @@ error: 128-bit type is unstable (see issue #35118) | = help: add #![feature(i128_type)] to the crate attributes to enable -error: 128-bit type is unstable (see issue #35118) +error[E0658]: 128-bit type is unstable (see issue #35118) --> $DIR/feature-gate-i128_type2.rs:26:12 | 26 | let x: u128 = 0; //~ ERROR 128-bit type is unstable @@ -32,7 +32,7 @@ error: 128-bit type is unstable (see issue #35118) error[E0601]: main function not found -error: repr with 128-bit type is unstable (see issue #35118) +error[E0658]: repr with 128-bit type is unstable (see issue #35118) --> $DIR/feature-gate-i128_type2.rs:30:1 | 30 | / enum A { //~ ERROR 128-bit type is unstable diff --git a/src/test/ui/feature-gate-intrinsics.stderr b/src/test/ui/feature-gate-intrinsics.stderr index 5382122e30e..918c749504a 100644 --- a/src/test/ui/feature-gate-intrinsics.stderr +++ b/src/test/ui/feature-gate-intrinsics.stderr @@ -1,4 +1,4 @@ -error: intrinsics are subject to change +error[E0658]: intrinsics are subject to change --> $DIR/feature-gate-intrinsics.rs:11:1 | 11 | / extern "rust-intrinsic" { //~ ERROR intrinsics are subject to change @@ -8,7 +8,7 @@ error: intrinsics are subject to change | = help: add #![feature(intrinsics)] to the crate attributes to enable -error: intrinsics are subject to change +error[E0658]: intrinsics are subject to change --> $DIR/feature-gate-intrinsics.rs:15:1 | 15 | / extern "rust-intrinsic" fn baz() { //~ ERROR intrinsics are subject to change diff --git a/src/test/ui/feature-gate-lang-items.stderr b/src/test/ui/feature-gate-lang-items.stderr index dab8ce23192..28e3dab8fa7 100644 --- a/src/test/ui/feature-gate-lang-items.stderr +++ b/src/test/ui/feature-gate-lang-items.stderr @@ -1,4 +1,4 @@ -error: language items are subject to change +error[E0658]: language items are subject to change --> $DIR/feature-gate-lang-items.rs:11:1 | 11 | #[lang="foo"] //~ ERROR language items are subject to change diff --git a/src/test/ui/feature-gate-link_args.stderr b/src/test/ui/feature-gate-link_args.stderr index d6d059007d1..78070d52f1f 100644 --- a/src/test/ui/feature-gate-link_args.stderr +++ b/src/test/ui/feature-gate-link_args.stderr @@ -1,4 +1,4 @@ -error: the `link_args` attribute is experimental and not portable across platforms, it is recommended to use `#[link(name = "foo")] instead (see issue #29596) +error[E0658]: the `link_args` attribute is experimental and not portable across platforms, it is recommended to use `#[link(name = "foo")] instead (see issue #29596) --> $DIR/feature-gate-link_args.rs:22:1 | 22 | #[link_args = "-l expected_use_case"] @@ -6,7 +6,7 @@ error: the `link_args` attribute is experimental and not portable across platfor | = help: add #![feature(link_args)] to the crate attributes to enable -error: the `link_args` attribute is experimental and not portable across platforms, it is recommended to use `#[link(name = "foo")] instead (see issue #29596) +error[E0658]: the `link_args` attribute is experimental and not portable across platforms, it is recommended to use `#[link(name = "foo")] instead (see issue #29596) --> $DIR/feature-gate-link_args.rs:26:1 | 26 | #[link_args = "-l unexected_use_on_non_extern_item"] @@ -14,7 +14,7 @@ error: the `link_args` attribute is experimental and not portable across platfor | = help: add #![feature(link_args)] to the crate attributes to enable -error: the `link_args` attribute is experimental and not portable across platforms, it is recommended to use `#[link(name = "foo")] instead (see issue #29596) +error[E0658]: the `link_args` attribute is experimental and not portable across platforms, it is recommended to use `#[link(name = "foo")] instead (see issue #29596) --> $DIR/feature-gate-link_args.rs:19:1 | 19 | #![link_args = "-l unexpected_use_as_inner_attr_on_mod"] diff --git a/src/test/ui/feature-gate-link_cfg.stderr b/src/test/ui/feature-gate-link_cfg.stderr index bbc52bd9d20..8aada72fb0c 100644 --- a/src/test/ui/feature-gate-link_cfg.stderr +++ b/src/test/ui/feature-gate-link_cfg.stderr @@ -1,4 +1,4 @@ -error: is feature gated (see issue #37406) +error[E0658]: is feature gated (see issue #37406) --> $DIR/feature-gate-link_cfg.rs:11:1 | 11 | #[link(name = "foo", cfg(foo))] diff --git a/src/test/ui/feature-gate-link_llvm_intrinsics.stderr b/src/test/ui/feature-gate-link_llvm_intrinsics.stderr index b2e2caaa51a..136658f23fd 100644 --- a/src/test/ui/feature-gate-link_llvm_intrinsics.stderr +++ b/src/test/ui/feature-gate-link_llvm_intrinsics.stderr @@ -1,4 +1,4 @@ -error: linking to LLVM intrinsics is experimental (see issue #29602) +error[E0658]: linking to LLVM intrinsics is experimental (see issue #29602) --> $DIR/feature-gate-link_llvm_intrinsics.rs:13:5 | 13 | fn sqrt(x: f32) -> f32; diff --git a/src/test/ui/feature-gate-linkage.stderr b/src/test/ui/feature-gate-linkage.stderr index 62d857ddf2c..54764b1920c 100644 --- a/src/test/ui/feature-gate-linkage.stderr +++ b/src/test/ui/feature-gate-linkage.stderr @@ -1,4 +1,4 @@ -error: the `linkage` attribute is experimental and not portable across platforms (see issue #29603) +error[E0658]: the `linkage` attribute is experimental and not portable across platforms (see issue #29603) --> $DIR/feature-gate-linkage.rs:12:5 | 12 | #[linkage = "extern_weak"] static foo: isize; diff --git a/src/test/ui/feature-gate-linker-flavor.stderr b/src/test/ui/feature-gate-linker-flavor.stderr index 383e75e3d17..e58693d35c2 100644 --- a/src/test/ui/feature-gate-linker-flavor.stderr +++ b/src/test/ui/feature-gate-linker-flavor.stderr @@ -1,4 +1,4 @@ -error: the `#[used]` attribute is an experimental feature (see issue #40289) +error[E0658]: the `#[used]` attribute is an experimental feature (see issue #40289) --> $DIR/feature-gate-linker-flavor.rs:16:1 | 16 | #[used] diff --git a/src/test/ui/feature-gate-log_syntax.stderr b/src/test/ui/feature-gate-log_syntax.stderr index f1c0d305f6c..363b1753f4a 100644 --- a/src/test/ui/feature-gate-log_syntax.stderr +++ b/src/test/ui/feature-gate-log_syntax.stderr @@ -1,4 +1,4 @@ -error: `log_syntax!` is not stable enough for use and is subject to change (see issue #29598) +error[E0658]: `log_syntax!` is not stable enough for use and is subject to change (see issue #29598) --> $DIR/feature-gate-log_syntax.rs:12:5 | 12 | log_syntax!() //~ ERROR `log_syntax!` is not stable enough diff --git a/src/test/ui/feature-gate-log_syntax2.stderr b/src/test/ui/feature-gate-log_syntax2.stderr index b1bb5557eed..f47a5076e79 100644 --- a/src/test/ui/feature-gate-log_syntax2.stderr +++ b/src/test/ui/feature-gate-log_syntax2.stderr @@ -1,4 +1,4 @@ -error: `log_syntax!` is not stable enough for use and is subject to change (see issue #29598) +error[E0658]: `log_syntax!` is not stable enough for use and is subject to change (see issue #29598) --> $DIR/feature-gate-log_syntax2.rs:14:20 | 14 | println!("{}", log_syntax!()); //~ ERROR `log_syntax!` is not stable diff --git a/src/test/ui/feature-gate-macro-lifetime-matcher.stderr b/src/test/ui/feature-gate-macro-lifetime-matcher.stderr index e78f7684cf2..553a7d3d131 100644 --- a/src/test/ui/feature-gate-macro-lifetime-matcher.stderr +++ b/src/test/ui/feature-gate-macro-lifetime-matcher.stderr @@ -1,4 +1,4 @@ -error: :lifetime fragment specifier is experimental and subject to change (see issue #46895) +error[E0658]: :lifetime fragment specifier is experimental and subject to change (see issue #46895) --> $DIR/feature-gate-macro-lifetime-matcher.rs:14:19 | 14 | macro_rules! m { ($lt:lifetime) => {} } diff --git a/src/test/ui/feature-gate-macro-vis-matcher.stderr b/src/test/ui/feature-gate-macro-vis-matcher.stderr index 09db5009165..ee1844c0922 100644 --- a/src/test/ui/feature-gate-macro-vis-matcher.stderr +++ b/src/test/ui/feature-gate-macro-vis-matcher.stderr @@ -1,4 +1,4 @@ -error: :vis fragment specifier is experimental and subject to change (see issue #41022) +error[E0658]: :vis fragment specifier is experimental and subject to change (see issue #41022) --> $DIR/feature-gate-macro-vis-matcher.rs:14:19 | 14 | macro_rules! m { ($v:vis) => {} } diff --git a/src/test/ui/feature-gate-main.stderr b/src/test/ui/feature-gate-main.stderr index 90cf12822c8..56e9c8b37e3 100644 --- a/src/test/ui/feature-gate-main.stderr +++ b/src/test/ui/feature-gate-main.stderr @@ -1,4 +1,4 @@ -error: declaration of a nonstandard #[main] function may change over time, for now a top-level `fn main()` is required (see issue #29634) +error[E0658]: declaration of a nonstandard #[main] function may change over time, for now a top-level `fn main()` is required (see issue #29634) --> $DIR/feature-gate-main.rs:12:1 | 12 | fn foo() {} //~ ERROR: declaration of a nonstandard #[main] function may change over time diff --git a/src/test/ui/feature-gate-match_beginning_vert.stderr b/src/test/ui/feature-gate-match_beginning_vert.stderr index 88053adfafa..1d45dedb497 100644 --- a/src/test/ui/feature-gate-match_beginning_vert.stderr +++ b/src/test/ui/feature-gate-match_beginning_vert.stderr @@ -1,4 +1,4 @@ -error: Use of a '|' at the beginning of a match arm is experimental (see issue #44101) +error[E0658]: Use of a '|' at the beginning of a match arm is experimental (see issue #44101) --> $DIR/feature-gate-match_beginning_vert.rs:24:9 | 24 | | A => println!("A"), @@ -6,7 +6,7 @@ error: Use of a '|' at the beginning of a match arm is experimental (see issue # | = help: add #![feature(match_beginning_vert)] to the crate attributes to enable -error: Use of a '|' at the beginning of a match arm is experimental (see issue #44101) +error[E0658]: Use of a '|' at the beginning of a match arm is experimental (see issue #44101) --> $DIR/feature-gate-match_beginning_vert.rs:26:9 | 26 | | B | C => println!("BC!"), @@ -14,7 +14,7 @@ error: Use of a '|' at the beginning of a match arm is experimental (see issue # | = help: add #![feature(match_beginning_vert)] to the crate attributes to enable -error: Use of a '|' at the beginning of a match arm is experimental (see issue #44101) +error[E0658]: Use of a '|' at the beginning of a match arm is experimental (see issue #44101) --> $DIR/feature-gate-match_beginning_vert.rs:28:9 | 28 | | _ => {}, diff --git a/src/test/ui/feature-gate-match_default_bindings.stderr b/src/test/ui/feature-gate-match_default_bindings.stderr index d86e8248f08..1bedfb7f8be 100644 --- a/src/test/ui/feature-gate-match_default_bindings.stderr +++ b/src/test/ui/feature-gate-match_default_bindings.stderr @@ -1,4 +1,4 @@ -error: non-reference pattern used to match a reference (see issue #42640) +error[E0658]: non-reference pattern used to match a reference (see issue #42640) --> $DIR/feature-gate-match_default_bindings.rs:13:9 | 13 | Some(n) => {}, diff --git a/src/test/ui/feature-gate-may-dangle.stderr b/src/test/ui/feature-gate-may-dangle.stderr index e51723d058e..a3a3f7bd174 100644 --- a/src/test/ui/feature-gate-may-dangle.stderr +++ b/src/test/ui/feature-gate-may-dangle.stderr @@ -1,4 +1,4 @@ -error: may_dangle has unstable semantics and may be removed in the future (see issue #34761) +error[E0658]: may_dangle has unstable semantics and may be removed in the future (see issue #34761) --> $DIR/feature-gate-may-dangle.rs:18:6 | 18 | impl<#[may_dangle] A> Drop for Pt<A> { diff --git a/src/test/ui/feature-gate-naked_functions.stderr b/src/test/ui/feature-gate-naked_functions.stderr index 9655982574c..5f72234e5df 100644 --- a/src/test/ui/feature-gate-naked_functions.stderr +++ b/src/test/ui/feature-gate-naked_functions.stderr @@ -1,4 +1,4 @@ -error: the `#[naked]` attribute is an experimental feature (see issue #32408) +error[E0658]: the `#[naked]` attribute is an experimental feature (see issue #32408) --> $DIR/feature-gate-naked_functions.rs:11:1 | 11 | #[naked] @@ -6,7 +6,7 @@ error: the `#[naked]` attribute is an experimental feature (see issue #32408) | = help: add #![feature(naked_functions)] to the crate attributes to enable -error: the `#[naked]` attribute is an experimental feature (see issue #32408) +error[E0658]: the `#[naked]` attribute is an experimental feature (see issue #32408) --> $DIR/feature-gate-naked_functions.rs:15:1 | 15 | #[naked] diff --git a/src/test/ui/feature-gate-needs-allocator.stderr b/src/test/ui/feature-gate-needs-allocator.stderr index 5124c10cb47..11b8c31e6df 100644 --- a/src/test/ui/feature-gate-needs-allocator.stderr +++ b/src/test/ui/feature-gate-needs-allocator.stderr @@ -1,4 +1,4 @@ -error: the `#[needs_allocator]` attribute is an experimental feature +error[E0658]: the `#[needs_allocator]` attribute is an experimental feature --> $DIR/feature-gate-needs-allocator.rs:11:1 | 11 | #![needs_allocator] //~ ERROR the `#[needs_allocator]` attribute is diff --git a/src/test/ui/feature-gate-never_type.stderr b/src/test/ui/feature-gate-never_type.stderr index c242e613ead..2fd04f51e7e 100644 --- a/src/test/ui/feature-gate-never_type.stderr +++ b/src/test/ui/feature-gate-never_type.stderr @@ -1,4 +1,4 @@ -error: The `!` type is experimental (see issue #35121) +error[E0658]: The `!` type is experimental (see issue #35121) --> $DIR/feature-gate-never_type.rs:17:17 | 17 | type Ma = (u32, !, i32); //~ ERROR type is experimental @@ -6,7 +6,7 @@ error: The `!` type is experimental (see issue #35121) | = help: add #![feature(never_type)] to the crate attributes to enable -error: The `!` type is experimental (see issue #35121) +error[E0658]: The `!` type is experimental (see issue #35121) --> $DIR/feature-gate-never_type.rs:18:20 | 18 | type Meeshka = Vec<!>; //~ ERROR type is experimental @@ -14,7 +14,7 @@ error: The `!` type is experimental (see issue #35121) | = help: add #![feature(never_type)] to the crate attributes to enable -error: The `!` type is experimental (see issue #35121) +error[E0658]: The `!` type is experimental (see issue #35121) --> $DIR/feature-gate-never_type.rs:19:16 | 19 | type Mow = &fn(!) -> !; //~ ERROR type is experimental @@ -22,7 +22,7 @@ error: The `!` type is experimental (see issue #35121) | = help: add #![feature(never_type)] to the crate attributes to enable -error: The `!` type is experimental (see issue #35121) +error[E0658]: The `!` type is experimental (see issue #35121) --> $DIR/feature-gate-never_type.rs:20:19 | 20 | type Skwoz = &mut !; //~ ERROR type is experimental @@ -30,7 +30,7 @@ error: The `!` type is experimental (see issue #35121) | = help: add #![feature(never_type)] to the crate attributes to enable -error: The `!` type is experimental (see issue #35121) +error[E0658]: The `!` type is experimental (see issue #35121) --> $DIR/feature-gate-never_type.rs:23:16 | 23 | type Wub = !; //~ ERROR type is experimental diff --git a/src/test/ui/feature-gate-no-debug.stderr b/src/test/ui/feature-gate-no-debug.stderr index 83a8189c095..c7af8cf6aab 100644 --- a/src/test/ui/feature-gate-no-debug.stderr +++ b/src/test/ui/feature-gate-no-debug.stderr @@ -1,4 +1,4 @@ -error: the `#[no_debug]` attribute was an experimental feature that has been deprecated due to lack of demand (see issue #29721) +error[E0658]: the `#[no_debug]` attribute was an experimental feature that has been deprecated due to lack of demand (see issue #29721) --> $DIR/feature-gate-no-debug.rs:13:1 | 13 | #[no_debug] //~ ERROR the `#[no_debug]` attribute was diff --git a/src/test/ui/feature-gate-no_core.stderr b/src/test/ui/feature-gate-no_core.stderr index 02e0b176249..7fc89852002 100644 --- a/src/test/ui/feature-gate-no_core.stderr +++ b/src/test/ui/feature-gate-no_core.stderr @@ -1,4 +1,4 @@ -error: no_core is experimental (see issue #29639) +error[E0658]: no_core is experimental (see issue #29639) --> $DIR/feature-gate-no_core.rs:11:1 | 11 | #![no_core] //~ ERROR no_core is experimental diff --git a/src/test/ui/feature-gate-non_ascii_idents.stderr b/src/test/ui/feature-gate-non_ascii_idents.stderr index 90d0b8daee7..deb707752b0 100644 --- a/src/test/ui/feature-gate-non_ascii_idents.stderr +++ b/src/test/ui/feature-gate-non_ascii_idents.stderr @@ -1,4 +1,4 @@ -error: non-ascii idents are not fully supported. (see issue #28979) +error[E0658]: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:11:1 | 11 | extern crate core as bäz; //~ ERROR non-ascii idents @@ -6,7 +6,7 @@ error: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error: non-ascii idents are not fully supported. (see issue #28979) +error[E0658]: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:13:5 | 13 | use föö::bar; //~ ERROR non-ascii idents @@ -14,7 +14,7 @@ error: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error: non-ascii idents are not fully supported. (see issue #28979) +error[E0658]: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:15:1 | 15 | mod föö { //~ ERROR non-ascii idents @@ -22,7 +22,7 @@ error: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error: non-ascii idents are not fully supported. (see issue #28979) +error[E0658]: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:19:1 | 19 | / fn bär( //~ ERROR non-ascii idents @@ -36,7 +36,7 @@ error: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error: non-ascii idents are not fully supported. (see issue #28979) +error[E0658]: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:20:5 | 20 | bäz: isize //~ ERROR non-ascii idents @@ -44,7 +44,7 @@ error: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error: non-ascii idents are not fully supported. (see issue #28979) +error[E0658]: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:22:9 | 22 | let _ö: isize; //~ ERROR non-ascii idents @@ -52,7 +52,7 @@ error: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error: non-ascii idents are not fully supported. (see issue #28979) +error[E0658]: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:25:10 | 25 | (_ä, _) => {} //~ ERROR non-ascii idents @@ -60,7 +60,7 @@ error: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error: non-ascii idents are not fully supported. (see issue #28979) +error[E0658]: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:29:1 | 29 | struct Föö { //~ ERROR non-ascii idents @@ -68,7 +68,7 @@ error: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error: non-ascii idents are not fully supported. (see issue #28979) +error[E0658]: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:30:5 | 30 | föö: isize //~ ERROR non-ascii idents @@ -76,7 +76,7 @@ error: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error: non-ascii idents are not fully supported. (see issue #28979) +error[E0658]: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:33:1 | 33 | enum Bär { //~ ERROR non-ascii idents @@ -84,7 +84,7 @@ error: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error: non-ascii idents are not fully supported. (see issue #28979) +error[E0658]: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:34:5 | 34 | Bäz { //~ ERROR non-ascii idents @@ -92,7 +92,7 @@ error: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error: non-ascii idents are not fully supported. (see issue #28979) +error[E0658]: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:35:9 | 35 | qüx: isize //~ ERROR non-ascii idents @@ -100,7 +100,7 @@ error: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error: non-ascii idents are not fully supported. (see issue #28979) +error[E0658]: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:40:5 | 40 | fn qüx(); //~ ERROR non-ascii idents diff --git a/src/test/ui/feature-gate-non_exhaustive.stderr b/src/test/ui/feature-gate-non_exhaustive.stderr index 775e65b90fa..320f40e31b8 100644 --- a/src/test/ui/feature-gate-non_exhaustive.stderr +++ b/src/test/ui/feature-gate-non_exhaustive.stderr @@ -1,4 +1,4 @@ -error: non exhaustive is an experimental feature (see issue #44109) +error[E0658]: non exhaustive is an experimental feature (see issue #44109) --> $DIR/feature-gate-non_exhaustive.rs:13:1 | 13 | #[non_exhaustive] //~ERROR non exhaustive is an experimental feature (see issue #44109) diff --git a/src/test/ui/feature-gate-omit-gdb-pretty-printer-section.stderr b/src/test/ui/feature-gate-omit-gdb-pretty-printer-section.stderr index e50e1b4c0b5..4ceb697d0df 100644 --- a/src/test/ui/feature-gate-omit-gdb-pretty-printer-section.stderr +++ b/src/test/ui/feature-gate-omit-gdb-pretty-printer-section.stderr @@ -1,4 +1,4 @@ -error: the `#[omit_gdb_pretty_printer_section]` attribute is just used for the Rust test suite +error[E0658]: the `#[omit_gdb_pretty_printer_section]` attribute is just used for the Rust test suite --> $DIR/feature-gate-omit-gdb-pretty-printer-section.rs:11:1 | 11 | #[omit_gdb_pretty_printer_section] //~ ERROR the `#[omit_gdb_pretty_printer_section]` attribute is diff --git a/src/test/ui/feature-gate-on-unimplemented.stderr b/src/test/ui/feature-gate-on-unimplemented.stderr index 06944a14736..b1658c3be16 100644 --- a/src/test/ui/feature-gate-on-unimplemented.stderr +++ b/src/test/ui/feature-gate-on-unimplemented.stderr @@ -1,4 +1,4 @@ -error: the `#[rustc_on_unimplemented]` attribute is an experimental feature (see issue #29628) +error[E0658]: the `#[rustc_on_unimplemented]` attribute is an experimental feature (see issue #29628) --> $DIR/feature-gate-on-unimplemented.rs:14:1 | 14 | #[rustc_on_unimplemented = "test error `{Self}` with `{Bar}`"] diff --git a/src/test/ui/feature-gate-optin-builtin-traits.stderr b/src/test/ui/feature-gate-optin-builtin-traits.stderr index d66da1224f8..beb734a8ef8 100644 --- a/src/test/ui/feature-gate-optin-builtin-traits.stderr +++ b/src/test/ui/feature-gate-optin-builtin-traits.stderr @@ -1,4 +1,4 @@ -error: auto traits are experimental and possibly buggy (see issue #13231) +error[E0658]: auto traits are experimental and possibly buggy (see issue #13231) --> $DIR/feature-gate-optin-builtin-traits.rs:20:1 | 20 | auto trait AutoDummyTrait {} @@ -6,7 +6,7 @@ error: auto traits are experimental and possibly buggy (see issue #13231) | = help: add #![feature(optin_builtin_traits)] to the crate attributes to enable -error: negative trait bounds are not yet fully implemented; use marker types for now (see issue #13231) +error[E0658]: negative trait bounds are not yet fully implemented; use marker types for now (see issue #13231) --> $DIR/feature-gate-optin-builtin-traits.rs:23:1 | 23 | impl !DummyTrait for DummyStruct {} diff --git a/src/test/ui/feature-gate-placement-expr.stderr b/src/test/ui/feature-gate-placement-expr.stderr index fdb7b506711..c588cabe239 100644 --- a/src/test/ui/feature-gate-placement-expr.stderr +++ b/src/test/ui/feature-gate-placement-expr.stderr @@ -1,4 +1,4 @@ -error: placement-in expression syntax is experimental and subject to change. (see issue #27779) +error[E0658]: placement-in expression syntax is experimental and subject to change. (see issue #27779) --> $DIR/feature-gate-placement-expr.rs:24:13 | 24 | let x = HEAP <- 'c'; //~ ERROR placement-in expression syntax is experimental diff --git a/src/test/ui/feature-gate-plugin.stderr b/src/test/ui/feature-gate-plugin.stderr index b94d3299abc..b54b2d89994 100644 --- a/src/test/ui/feature-gate-plugin.stderr +++ b/src/test/ui/feature-gate-plugin.stderr @@ -1,4 +1,4 @@ -error: compiler plugins are experimental and possibly buggy (see issue #29597) +error[E0658]: compiler plugins are experimental and possibly buggy (see issue #29597) --> $DIR/feature-gate-plugin.rs:13:1 | 13 | #![plugin(foo)] diff --git a/src/test/ui/feature-gate-plugin_registrar.stderr b/src/test/ui/feature-gate-plugin_registrar.stderr index 3710239142a..fb5bd9d1afe 100644 --- a/src/test/ui/feature-gate-plugin_registrar.stderr +++ b/src/test/ui/feature-gate-plugin_registrar.stderr @@ -1,4 +1,4 @@ -error: compiler plugins are experimental and possibly buggy (see issue #29597) +error[E0658]: compiler plugins are experimental and possibly buggy (see issue #29597) --> $DIR/feature-gate-plugin_registrar.rs:16:1 | 16 | pub fn registrar() {} diff --git a/src/test/ui/feature-gate-prelude_import.stderr b/src/test/ui/feature-gate-prelude_import.stderr index df44dfff40b..5487ae21f3b 100644 --- a/src/test/ui/feature-gate-prelude_import.stderr +++ b/src/test/ui/feature-gate-prelude_import.stderr @@ -1,4 +1,4 @@ -error: `#[prelude_import]` is for use by rustc only +error[E0658]: `#[prelude_import]` is for use by rustc only --> $DIR/feature-gate-prelude_import.rs:11:1 | 11 | #[prelude_import] //~ ERROR `#[prelude_import]` is for use by rustc only diff --git a/src/test/ui/feature-gate-profiler-runtime.stderr b/src/test/ui/feature-gate-profiler-runtime.stderr index c3165438cdb..f2893cbb97d 100644 --- a/src/test/ui/feature-gate-profiler-runtime.stderr +++ b/src/test/ui/feature-gate-profiler-runtime.stderr @@ -1,4 +1,4 @@ -error: the `#[profiler_runtime]` attribute is used to identify the `profiler_builtins` crate which contains the profiler runtime and will never be stable +error[E0658]: the `#[profiler_runtime]` attribute is used to identify the `profiler_builtins` crate which contains the profiler runtime and will never be stable --> $DIR/feature-gate-profiler-runtime.rs:11:1 | 11 | #![profiler_runtime] //~ ERROR the `#[profiler_runtime]` attribute is diff --git a/src/test/ui/feature-gate-repr-simd.stderr b/src/test/ui/feature-gate-repr-simd.stderr index a2ff06dd59f..e430a04a3e8 100644 --- a/src/test/ui/feature-gate-repr-simd.stderr +++ b/src/test/ui/feature-gate-repr-simd.stderr @@ -1,4 +1,4 @@ -error: SIMD types are experimental and possibly buggy (see issue #27731) +error[E0658]: SIMD types are experimental and possibly buggy (see issue #27731) --> $DIR/feature-gate-repr-simd.rs:11:1 | 11 | #[repr(simd)] //~ error: SIMD types are experimental diff --git a/src/test/ui/feature-gate-repr128.stderr b/src/test/ui/feature-gate-repr128.stderr index c59964887b5..982ebb01016 100644 --- a/src/test/ui/feature-gate-repr128.stderr +++ b/src/test/ui/feature-gate-repr128.stderr @@ -1,4 +1,4 @@ -error: repr with 128-bit type is unstable (see issue #35118) +error[E0658]: repr with 128-bit type is unstable (see issue #35118) --> $DIR/feature-gate-repr128.rs:12:1 | 12 | / enum A { //~ ERROR repr with 128-bit type is unstable diff --git a/src/test/ui/feature-gate-repr_align.stderr b/src/test/ui/feature-gate-repr_align.stderr index 16fdc135a5f..dd88067d58f 100644 --- a/src/test/ui/feature-gate-repr_align.stderr +++ b/src/test/ui/feature-gate-repr_align.stderr @@ -1,4 +1,4 @@ -error: the struct `#[repr(align(u16))]` attribute is experimental (see issue #33626) +error[E0658]: the struct `#[repr(align(u16))]` attribute is experimental (see issue #33626) --> $DIR/feature-gate-repr_align.rs:12:1 | 12 | #[repr(align(64))] //~ error: the struct `#[repr(align(u16))]` attribute is experimental diff --git a/src/test/ui/feature-gate-repr_transparent.rs b/src/test/ui/feature-gate-repr_transparent.rs new file mode 100644 index 00000000000..deadf2e535d --- /dev/null +++ b/src/test/ui/feature-gate-repr_transparent.rs @@ -0,0 +1,14 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[repr(transparent)] //~ error: the `#[repr(transparent)]` attribute is experimental +struct Foo(u64); + +fn main() {} diff --git a/src/test/ui/feature-gate-repr_transparent.stderr b/src/test/ui/feature-gate-repr_transparent.stderr new file mode 100644 index 00000000000..d1292e95491 --- /dev/null +++ b/src/test/ui/feature-gate-repr_transparent.stderr @@ -0,0 +1,10 @@ +error[E0658]: the `#[repr(transparent)]` attribute is experimental (see issue #43036) + --> $DIR/feature-gate-repr_transparent.rs:11:1 + | +11 | #[repr(transparent)] //~ error: the `#[repr(transparent)]` attribute is experimental + | ^^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(repr_transparent)] to the crate attributes to enable + +error: aborting due to previous error + diff --git a/src/test/ui/feature-gate-rustc-attrs.stderr b/src/test/ui/feature-gate-rustc-attrs.stderr index c818b57ef12..f47588c3a7d 100644 --- a/src/test/ui/feature-gate-rustc-attrs.stderr +++ b/src/test/ui/feature-gate-rustc-attrs.stderr @@ -1,4 +1,4 @@ -error: the `#[rustc_variance]` attribute is just used for rustc unit tests and will never be stable (see issue #29642) +error[E0658]: the `#[rustc_variance]` attribute is just used for rustc unit tests and will never be stable (see issue #29642) --> $DIR/feature-gate-rustc-attrs.rs:15:1 | 15 | #[rustc_variance] //~ ERROR the `#[rustc_variance]` attribute is just used for rustc unit tests and will never be stable @@ -6,7 +6,7 @@ error: the `#[rustc_variance]` attribute is just used for rustc unit tests and w | = help: add #![feature(rustc_attrs)] to the crate attributes to enable -error: the `#[rustc_error]` attribute is just used for rustc unit tests and will never be stable (see issue #29642) +error[E0658]: the `#[rustc_error]` attribute is just used for rustc unit tests and will never be stable (see issue #29642) --> $DIR/feature-gate-rustc-attrs.rs:16:1 | 16 | #[rustc_error] //~ ERROR the `#[rustc_error]` attribute is just used for rustc unit tests and will never be stable @@ -14,7 +14,7 @@ error: the `#[rustc_error]` attribute is just used for rustc unit tests and will | = help: add #![feature(rustc_attrs)] to the crate attributes to enable -error: unless otherwise specified, attributes with the prefix `rustc_` are reserved for internal compiler diagnostics (see issue #29642) +error[E0658]: unless otherwise specified, attributes with the prefix `rustc_` are reserved for internal compiler diagnostics (see issue #29642) --> $DIR/feature-gate-rustc-attrs.rs:17:1 | 17 | #[rustc_foo] diff --git a/src/test/ui/feature-gate-rustc_const_unstable.stderr b/src/test/ui/feature-gate-rustc_const_unstable.stderr index c32abb8b857..922898b7d36 100644 --- a/src/test/ui/feature-gate-rustc_const_unstable.stderr +++ b/src/test/ui/feature-gate-rustc_const_unstable.stderr @@ -1,4 +1,4 @@ -error: the `#[rustc_const_unstable]` attribute is an internal feature +error[E0658]: the `#[rustc_const_unstable]` attribute is an internal feature --> $DIR/feature-gate-rustc_const_unstable.rs:18:1 | 18 | #[rustc_const_unstable(feature="fzzzzzt")] //~ERROR internal feature diff --git a/src/test/ui/feature-gate-sanitizer-runtime.stderr b/src/test/ui/feature-gate-sanitizer-runtime.stderr index b9a43f8098d..6d77161864f 100644 --- a/src/test/ui/feature-gate-sanitizer-runtime.stderr +++ b/src/test/ui/feature-gate-sanitizer-runtime.stderr @@ -1,4 +1,4 @@ -error: the `#[sanitizer_runtime]` attribute is used to identify crates that contain the runtime of a sanitizer and will never be stable +error[E0658]: the `#[sanitizer_runtime]` attribute is used to identify crates that contain the runtime of a sanitizer and will never be stable --> $DIR/feature-gate-sanitizer-runtime.rs:11:1 | 11 | #![sanitizer_runtime] //~ ERROR the `#[sanitizer_runtime]` attribute is diff --git a/src/test/ui/feature-gate-simd.stderr b/src/test/ui/feature-gate-simd.stderr index b3225d580bf..447706ab858 100644 --- a/src/test/ui/feature-gate-simd.stderr +++ b/src/test/ui/feature-gate-simd.stderr @@ -1,4 +1,4 @@ -error: SIMD types are experimental and possibly buggy (see issue #27731) +error[E0658]: SIMD types are experimental and possibly buggy (see issue #27731) --> $DIR/feature-gate-simd.rs:14:1 | 14 | #[repr(simd)] //~ ERROR SIMD types are experimental diff --git a/src/test/ui/feature-gate-slice-patterns.stderr b/src/test/ui/feature-gate-slice-patterns.stderr index e5ba318b336..7a2e67c8982 100644 --- a/src/test/ui/feature-gate-slice-patterns.stderr +++ b/src/test/ui/feature-gate-slice-patterns.stderr @@ -1,4 +1,4 @@ -error: slice pattern syntax is experimental (see issue #23121) +error[E0658]: slice pattern syntax is experimental (see issue #23121) --> $DIR/feature-gate-slice-patterns.rs:16:9 | 16 | [1, 2, xs..] => {} //~ ERROR slice pattern syntax is experimental diff --git a/src/test/ui/feature-gate-start.stderr b/src/test/ui/feature-gate-start.stderr index b36fae2aacf..61cbe42d0fb 100644 --- a/src/test/ui/feature-gate-start.stderr +++ b/src/test/ui/feature-gate-start.stderr @@ -1,4 +1,4 @@ -error: a #[start] function is an experimental feature whose signature may change over time (see issue #29633) +error[E0658]: a #[start] function is an experimental feature whose signature may change over time (see issue #29633) --> $DIR/feature-gate-start.rs:12:1 | 12 | fn foo() {} //~ ERROR: a #[start] function is an experimental feature diff --git a/src/test/ui/feature-gate-static-nobundle.stderr b/src/test/ui/feature-gate-static-nobundle.stderr index 052516fad76..9ec4f6480b1 100644 --- a/src/test/ui/feature-gate-static-nobundle.stderr +++ b/src/test/ui/feature-gate-static-nobundle.stderr @@ -1,4 +1,4 @@ -error: kind="static-nobundle" is feature gated (see issue #37403) +error[E0658]: kind="static-nobundle" is feature gated (see issue #37403) --> $DIR/feature-gate-static-nobundle.rs:11:1 | 11 | #[link(name="foo", kind="static-nobundle")] diff --git a/src/test/ui/feature-gate-stmt_expr_attributes.stderr b/src/test/ui/feature-gate-stmt_expr_attributes.stderr index 80910594d1c..4d2e2f671c5 100644 --- a/src/test/ui/feature-gate-stmt_expr_attributes.stderr +++ b/src/test/ui/feature-gate-stmt_expr_attributes.stderr @@ -1,4 +1,4 @@ -error: attributes on non-item statements and expressions are experimental. (see issue #15701) +error[E0658]: attributes on non-item statements and expressions are experimental. (see issue #15701) --> $DIR/feature-gate-stmt_expr_attributes.rs:11:16 | 11 | const X: i32 = #[allow(dead_code)] 8; diff --git a/src/test/ui/feature-gate-target_feature.stderr b/src/test/ui/feature-gate-target_feature.stderr index 8c89eabf753..b6ad1b65691 100644 --- a/src/test/ui/feature-gate-target_feature.stderr +++ b/src/test/ui/feature-gate-target_feature.stderr @@ -1,4 +1,4 @@ -error: the `#[target_feature]` attribute is an experimental feature +error[E0658]: the `#[target_feature]` attribute is an experimental feature --> $DIR/feature-gate-target_feature.rs:11:1 | 11 | #[target_feature = "+sse2"] diff --git a/src/test/ui/feature-gate-thread_local.stderr b/src/test/ui/feature-gate-thread_local.stderr index 2608018528c..0f932abe4ee 100644 --- a/src/test/ui/feature-gate-thread_local.stderr +++ b/src/test/ui/feature-gate-thread_local.stderr @@ -1,4 +1,4 @@ -error: `#[thread_local]` is an experimental feature, and does not currently handle destructors. There is no corresponding `#[task_local]` mapping to the task model (see issue #29594) +error[E0658]: `#[thread_local]` is an experimental feature, and does not currently handle destructors. There is no corresponding `#[task_local]` mapping to the task model (see issue #29594) --> $DIR/feature-gate-thread_local.rs:18:1 | 18 | #[thread_local] //~ ERROR `#[thread_local]` is an experimental feature diff --git a/src/test/ui/feature-gate-trace_macros.stderr b/src/test/ui/feature-gate-trace_macros.stderr index aca74099b7d..eae3baa7e4d 100644 --- a/src/test/ui/feature-gate-trace_macros.stderr +++ b/src/test/ui/feature-gate-trace_macros.stderr @@ -1,4 +1,4 @@ -error: `trace_macros` is not stable enough for use and is subject to change (see issue #29598) +error[E0658]: `trace_macros` is not stable enough for use and is subject to change (see issue #29598) --> $DIR/feature-gate-trace_macros.rs:12:5 | 12 | trace_macros!(true); //~ ERROR: `trace_macros` is not stable diff --git a/src/test/ui/feature-gate-type_ascription.stderr b/src/test/ui/feature-gate-type_ascription.stderr index d2a3ee2cf8f..fa6ef84a7f5 100644 --- a/src/test/ui/feature-gate-type_ascription.stderr +++ b/src/test/ui/feature-gate-type_ascription.stderr @@ -1,4 +1,4 @@ -error: type ascription is experimental (see issue #23416) +error[E0658]: type ascription is experimental (see issue #23416) --> $DIR/feature-gate-type_ascription.rs:14:13 | 14 | let a = 10: u8; //~ ERROR type ascription is experimental diff --git a/src/test/ui/feature-gate-unboxed-closures-manual-impls.stderr b/src/test/ui/feature-gate-unboxed-closures-manual-impls.stderr index 280fc12f1a6..ae14054b6e3 100644 --- a/src/test/ui/feature-gate-unboxed-closures-manual-impls.stderr +++ b/src/test/ui/feature-gate-unboxed-closures-manual-impls.stderr @@ -1,4 +1,4 @@ -error: rust-call ABI is subject to change (see issue #29625) +error[E0658]: rust-call ABI is subject to change (see issue #29625) --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:20:5 | 20 | extern "rust-call" fn call(self, args: ()) -> () {} @@ -6,7 +6,7 @@ error: rust-call ABI is subject to change (see issue #29625) | = help: add #![feature(unboxed_closures)] to the crate attributes to enable -error: rust-call ABI is subject to change (see issue #29625) +error[E0658]: rust-call ABI is subject to change (see issue #29625) --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:25:5 | 25 | extern "rust-call" fn call_once(self, args: ()) -> () {} @@ -14,7 +14,7 @@ error: rust-call ABI is subject to change (see issue #29625) | = help: add #![feature(unboxed_closures)] to the crate attributes to enable -error: rust-call ABI is subject to change (see issue #29625) +error[E0658]: rust-call ABI is subject to change (see issue #29625) --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:30:5 | 30 | extern "rust-call" fn call_mut(&self, args: ()) -> () {} @@ -22,7 +22,7 @@ error: rust-call ABI is subject to change (see issue #29625) | = help: add #![feature(unboxed_closures)] to the crate attributes to enable -error: rust-call ABI is subject to change (see issue #29625) +error[E0658]: rust-call ABI is subject to change (see issue #29625) --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:35:5 | 35 | extern "rust-call" fn call_once(&self, args: ()) -> () {} diff --git a/src/test/ui/feature-gate-unboxed-closures-method-calls.stderr b/src/test/ui/feature-gate-unboxed-closures-method-calls.stderr index 1167bf0a696..a27b00aaac0 100644 --- a/src/test/ui/feature-gate-unboxed-closures-method-calls.stderr +++ b/src/test/ui/feature-gate-unboxed-closures-method-calls.stderr @@ -1,4 +1,4 @@ -error: use of unstable library feature 'fn_traits' (see issue #29625) +error[E0658]: use of unstable library feature 'fn_traits' (see issue #29625) --> $DIR/feature-gate-unboxed-closures-method-calls.rs:14:7 | 14 | f.call(()); //~ ERROR use of unstable library feature 'fn_traits' @@ -6,7 +6,7 @@ error: use of unstable library feature 'fn_traits' (see issue #29625) | = help: add #![feature(fn_traits)] to the crate attributes to enable -error: use of unstable library feature 'fn_traits' (see issue #29625) +error[E0658]: use of unstable library feature 'fn_traits' (see issue #29625) --> $DIR/feature-gate-unboxed-closures-method-calls.rs:15:7 | 15 | f.call_mut(()); //~ ERROR use of unstable library feature 'fn_traits' @@ -14,7 +14,7 @@ error: use of unstable library feature 'fn_traits' (see issue #29625) | = help: add #![feature(fn_traits)] to the crate attributes to enable -error: use of unstable library feature 'fn_traits' (see issue #29625) +error[E0658]: use of unstable library feature 'fn_traits' (see issue #29625) --> $DIR/feature-gate-unboxed-closures-method-calls.rs:16:7 | 16 | f.call_once(()); //~ ERROR use of unstable library feature 'fn_traits' diff --git a/src/test/ui/feature-gate-unboxed-closures-ufcs-calls.stderr b/src/test/ui/feature-gate-unboxed-closures-ufcs-calls.stderr index 7eb491cebfe..3d0dd15b07f 100644 --- a/src/test/ui/feature-gate-unboxed-closures-ufcs-calls.stderr +++ b/src/test/ui/feature-gate-unboxed-closures-ufcs-calls.stderr @@ -1,4 +1,4 @@ -error: use of unstable library feature 'fn_traits' (see issue #29625) +error[E0658]: use of unstable library feature 'fn_traits' (see issue #29625) --> $DIR/feature-gate-unboxed-closures-ufcs-calls.rs:14:5 | 14 | Fn::call(&f, ()); //~ ERROR use of unstable library feature 'fn_traits' @@ -6,7 +6,7 @@ error: use of unstable library feature 'fn_traits' (see issue #29625) | = help: add #![feature(fn_traits)] to the crate attributes to enable -error: use of unstable library feature 'fn_traits' (see issue #29625) +error[E0658]: use of unstable library feature 'fn_traits' (see issue #29625) --> $DIR/feature-gate-unboxed-closures-ufcs-calls.rs:15:5 | 15 | FnMut::call_mut(&mut f, ()); //~ ERROR use of unstable library feature 'fn_traits' @@ -14,7 +14,7 @@ error: use of unstable library feature 'fn_traits' (see issue #29625) | = help: add #![feature(fn_traits)] to the crate attributes to enable -error: use of unstable library feature 'fn_traits' (see issue #29625) +error[E0658]: use of unstable library feature 'fn_traits' (see issue #29625) --> $DIR/feature-gate-unboxed-closures-ufcs-calls.rs:16:5 | 16 | FnOnce::call_once(f, ()); //~ ERROR use of unstable library feature 'fn_traits' diff --git a/src/test/ui/feature-gate-unboxed-closures.stderr b/src/test/ui/feature-gate-unboxed-closures.stderr index b79165147e5..ca8a5924946 100644 --- a/src/test/ui/feature-gate-unboxed-closures.stderr +++ b/src/test/ui/feature-gate-unboxed-closures.stderr @@ -1,4 +1,4 @@ -error: rust-call ABI is subject to change (see issue #29625) +error[E0658]: rust-call ABI is subject to change (see issue #29625) --> $DIR/feature-gate-unboxed-closures.rs:16:5 | 16 | / extern "rust-call" fn call_once(self, (a, b): (u32, u32)) -> u32 { diff --git a/src/test/ui/feature-gate-underscore-lifetimes.stderr b/src/test/ui/feature-gate-underscore-lifetimes.stderr index 875b958aa88..07c5e1ad640 100644 --- a/src/test/ui/feature-gate-underscore-lifetimes.stderr +++ b/src/test/ui/feature-gate-underscore-lifetimes.stderr @@ -1,4 +1,4 @@ -error: underscore lifetimes are unstable (see issue #44524) +error[E0658]: underscore lifetimes are unstable (see issue #44524) --> $DIR/feature-gate-underscore-lifetimes.rs:13:23 | 13 | fn foo(x: &u8) -> Foo<'_> { //~ ERROR underscore lifetimes are unstable diff --git a/src/test/ui/feature-gate-universal.stderr b/src/test/ui/feature-gate-universal.stderr index 7f889f96224..978ce5982ba 100644 --- a/src/test/ui/feature-gate-universal.stderr +++ b/src/test/ui/feature-gate-universal.stderr @@ -1,4 +1,4 @@ -error: `impl Trait` in argument position is experimental (see issue #34511) +error[E0658]: `impl Trait` in argument position is experimental (see issue #34511) --> $DIR/feature-gate-universal.rs:13:11 | 13 | fn foo(x: impl std::fmt::Debug) { print!("{:?}", x); } diff --git a/src/test/ui/feature-gate-unsized_tuple_coercion.stderr b/src/test/ui/feature-gate-unsized_tuple_coercion.stderr index f166b10613a..4714df9e96c 100644 --- a/src/test/ui/feature-gate-unsized_tuple_coercion.stderr +++ b/src/test/ui/feature-gate-unsized_tuple_coercion.stderr @@ -1,4 +1,4 @@ -error: Unsized tuple coercion is not stable enough for use and is subject to change (see issue #42877) +error[E0658]: Unsized tuple coercion is not stable enough for use and is subject to change (see issue #42877) --> $DIR/feature-gate-unsized_tuple_coercion.rs:12:24 | 12 | let _ : &(Send,) = &((),); diff --git a/src/test/ui/feature-gate-untagged_unions.stderr b/src/test/ui/feature-gate-untagged_unions.stderr index 26b698912bc..14b66cb5c81 100644 --- a/src/test/ui/feature-gate-untagged_unions.stderr +++ b/src/test/ui/feature-gate-untagged_unions.stderr @@ -1,4 +1,4 @@ -error: unions with non-`Copy` fields are unstable (see issue #32836) +error[E0658]: unions with non-`Copy` fields are unstable (see issue #32836) --> $DIR/feature-gate-untagged_unions.rs:19:1 | 19 | / union U3 { //~ ERROR unions with non-`Copy` fields are unstable @@ -8,7 +8,7 @@ error: unions with non-`Copy` fields are unstable (see issue #32836) | = help: add #![feature(untagged_unions)] to the crate attributes to enable -error: unions with non-`Copy` fields are unstable (see issue #32836) +error[E0658]: unions with non-`Copy` fields are unstable (see issue #32836) --> $DIR/feature-gate-untagged_unions.rs:23:1 | 23 | / union U4<T> { //~ ERROR unions with non-`Copy` fields are unstable @@ -18,7 +18,7 @@ error: unions with non-`Copy` fields are unstable (see issue #32836) | = help: add #![feature(untagged_unions)] to the crate attributes to enable -error: unions with `Drop` implementations are unstable (see issue #32836) +error[E0658]: unions with `Drop` implementations are unstable (see issue #32836) --> $DIR/feature-gate-untagged_unions.rs:27:1 | 27 | / union U5 { //~ ERROR unions with `Drop` implementations are unstable diff --git a/src/test/ui/feature-gate-unwind-attributes.stderr b/src/test/ui/feature-gate-unwind-attributes.stderr index 02d8bf914eb..d9b555e2634 100644 --- a/src/test/ui/feature-gate-unwind-attributes.stderr +++ b/src/test/ui/feature-gate-unwind-attributes.stderr @@ -1,4 +1,4 @@ -error: #[unwind] is experimental +error[E0658]: #[unwind] is experimental --> $DIR/feature-gate-unwind-attributes.rs:21:5 | 21 | #[unwind] //~ ERROR #[unwind] is experimental diff --git a/src/test/ui/feature-gate-use_nested_groups.stderr b/src/test/ui/feature-gate-use_nested_groups.stderr index 79f1d1a168f..6ae691c384b 100644 --- a/src/test/ui/feature-gate-use_nested_groups.stderr +++ b/src/test/ui/feature-gate-use_nested_groups.stderr @@ -1,4 +1,4 @@ -error: nested groups in `use` are experimental (see issue #44494) +error[E0658]: nested groups in `use` are experimental (see issue #44494) --> $DIR/feature-gate-use_nested_groups.rs:27:12 | 27 | use a::{B, d::{*, g::H}}; //~ ERROR glob imports in `use` groups are experimental @@ -6,7 +6,7 @@ error: nested groups in `use` are experimental (see issue #44494) | = help: add #![feature(use_nested_groups)] to the crate attributes to enable -error: glob imports in `use` groups are experimental (see issue #44494) +error[E0658]: glob imports in `use` groups are experimental (see issue #44494) --> $DIR/feature-gate-use_nested_groups.rs:27:16 | 27 | use a::{B, d::{*, g::H}}; //~ ERROR glob imports in `use` groups are experimental @@ -14,7 +14,7 @@ error: glob imports in `use` groups are experimental (see issue #44494) | = help: add #![feature(use_nested_groups)] to the crate attributes to enable -error: paths in `use` groups are experimental (see issue #44494) +error[E0658]: paths in `use` groups are experimental (see issue #44494) --> $DIR/feature-gate-use_nested_groups.rs:27:19 | 27 | use a::{B, d::{*, g::H}}; //~ ERROR glob imports in `use` groups are experimental diff --git a/src/test/ui/feature-gate-used.stderr b/src/test/ui/feature-gate-used.stderr index 228cf12a08b..6d5ab1fd2c5 100644 --- a/src/test/ui/feature-gate-used.stderr +++ b/src/test/ui/feature-gate-used.stderr @@ -1,4 +1,4 @@ -error: the `#[used]` attribute is an experimental feature (see issue #40289) +error[E0658]: the `#[used]` attribute is an experimental feature (see issue #40289) --> $DIR/feature-gate-used.rs:11:1 | 11 | #[used] diff --git a/src/test/ui/feature-gate-wasm_import_memory.stderr b/src/test/ui/feature-gate-wasm_import_memory.stderr index c0486d0d5f5..10190ef93f0 100644 --- a/src/test/ui/feature-gate-wasm_import_memory.stderr +++ b/src/test/ui/feature-gate-wasm_import_memory.stderr @@ -1,4 +1,4 @@ -error: wasm_import_memory attribute is currently unstable +error[E0658]: wasm_import_memory attribute is currently unstable --> $DIR/feature-gate-wasm_import_memory.rs:11:1 | 11 | #![wasm_import_memory] //~ ERROR: currently unstable diff --git a/src/test/ui/fmt/send-sync.stderr b/src/test/ui/fmt/send-sync.stderr index 9e0e563c35f..4ec5c9ebd27 100644 --- a/src/test/ui/fmt/send-sync.stderr +++ b/src/test/ui/fmt/send-sync.stderr @@ -12,7 +12,11 @@ error[E0277]: the trait bound `*mut std::ops::Fn() + 'static: std::marker::Sync` = note: required because it appears within the type `[std::fmt::ArgumentV1<'_>]` = note: required because of the requirements on the impl of `std::marker::Send` for `&[std::fmt::ArgumentV1<'_>]` = note: required because it appears within the type `std::fmt::Arguments<'_>` - = note: required by `send` +note: required by `send` + --> $DIR/send-sync.rs:11:1 + | +11 | fn send<T: Send>(_: T) {} + | ^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `*mut std::ops::Fn() + 'static: std::marker::Sync` is not satisfied in `std::fmt::Arguments<'_>` --> $DIR/send-sync.rs:19:5 @@ -28,7 +32,11 @@ error[E0277]: the trait bound `*mut std::ops::Fn() + 'static: std::marker::Sync` = note: required because it appears within the type `[std::fmt::ArgumentV1<'_>]` = note: required because it appears within the type `&[std::fmt::ArgumentV1<'_>]` = note: required because it appears within the type `std::fmt::Arguments<'_>` - = note: required by `sync` +note: required by `sync` + --> $DIR/send-sync.rs:12:1 + | +12 | fn sync<T: Sync>(_: T) {} + | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/generator/not-send-sync.stderr b/src/test/ui/generator/not-send-sync.stderr index a1f110accc1..d30255335a6 100644 --- a/src/test/ui/generator/not-send-sync.stderr +++ b/src/test/ui/generator/not-send-sync.stderr @@ -7,7 +7,11 @@ error[E0277]: the trait bound `std::cell::Cell<i32>: std::marker::Sync` is not s = help: the trait `std::marker::Sync` is not implemented for `std::cell::Cell<i32>` = note: required because of the requirements on the impl of `std::marker::Send` for `&std::cell::Cell<i32>` = note: required because it appears within the type `[generator@$DIR/not-send-sync.rs:26:17: 30:6 a:&std::cell::Cell<i32> _]` - = note: required by `main::assert_send` +note: required by `main::assert_send` + --> $DIR/not-send-sync.rs:17:5 + | +17 | fn assert_send<T: Send>(_: T) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `std::cell::Cell<i32>: std::marker::Sync` is not satisfied in `[generator@$DIR/not-send-sync.rs:19:17: 23:6 (std::cell::Cell<i32>, ())]` --> $DIR/not-send-sync.rs:19:5 @@ -18,7 +22,11 @@ error[E0277]: the trait bound `std::cell::Cell<i32>: std::marker::Sync` is not s = help: within `[generator@$DIR/not-send-sync.rs:19:17: 23:6 (std::cell::Cell<i32>, ())]`, the trait `std::marker::Sync` is not implemented for `std::cell::Cell<i32>` = note: required because it appears within the type `(std::cell::Cell<i32>, ())` = note: required because it appears within the type `[generator@$DIR/not-send-sync.rs:19:17: 23:6 (std::cell::Cell<i32>, ())]` - = note: required by `main::assert_sync` +note: required by `main::assert_sync` + --> $DIR/not-send-sync.rs:16:5 + | +16 | fn assert_sync<T: Sync>(_: T) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/impl-trait/auto-trait-leak.stderr b/src/test/ui/impl-trait/auto-trait-leak.stderr index ffd6a3fe4ff..838a3002e3a 100644 --- a/src/test/ui/impl-trait/auto-trait-leak.stderr +++ b/src/test/ui/impl-trait/auto-trait-leak.stderr @@ -7,7 +7,11 @@ error[E0277]: the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::S = help: within `impl std::ops::Fn<(i32,)>`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<std::cell::Cell<i32>>` = note: required because it appears within the type `[closure@$DIR/auto-trait-leak.rs:21:5: 21:22 p:std::rc::Rc<std::cell::Cell<i32>>]` = note: required because it appears within the type `impl std::ops::Fn<(i32,)>` - = note: required by `send` +note: required by `send` + --> $DIR/auto-trait-leak.rs:24:1 + | +24 | fn send<T: Send>(_: T) {} + | ^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::Send` is not satisfied in `impl std::ops::Fn<(i32,)>` --> $DIR/auto-trait-leak.rs:30:5 @@ -18,7 +22,11 @@ error[E0277]: the trait bound `std::rc::Rc<std::cell::Cell<i32>>: std::marker::S = help: within `impl std::ops::Fn<(i32,)>`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<std::cell::Cell<i32>>` = note: required because it appears within the type `[closure@$DIR/auto-trait-leak.rs:38:5: 38:22 p:std::rc::Rc<std::cell::Cell<i32>>]` = note: required because it appears within the type `impl std::ops::Fn<(i32,)>` - = note: required by `send` +note: required by `send` + --> $DIR/auto-trait-leak.rs:24:1 + | +24 | fn send<T: Send>(_: T) {} + | ^^^^^^^^^^^^^^^^^^^^^^ error[E0391]: unsupported cyclic reference between types/traits detected --> $DIR/auto-trait-leak.rs:44:1 diff --git a/src/test/ui/imports/duplicate.stderr b/src/test/ui/imports/duplicate.stderr index 30f2f517115..a74401314a1 100644 --- a/src/test/ui/imports/duplicate.stderr +++ b/src/test/ui/imports/duplicate.stderr @@ -12,7 +12,7 @@ help: You can use `as` to change the binding name of the import 25 | use a::foo as Otherfoo; //~ ERROR the name `foo` is defined multiple times | ^^^^^^^^^^^^^^^^^^ -error: `foo` is ambiguous +error[E0659]: `foo` is ambiguous --> $DIR/duplicate.rs:56:9 | 56 | use self::foo::bar; //~ ERROR `foo` is ambiguous @@ -30,7 +30,7 @@ note: `foo` could also refer to the name imported here | ^^^^^^^^^^^ = note: consider adding an explicit import of `foo` to disambiguate -error: `foo` is ambiguous +error[E0659]: `foo` is ambiguous --> $DIR/duplicate.rs:45:5 | 45 | f::foo(); //~ ERROR `foo` is ambiguous @@ -48,7 +48,7 @@ note: `foo` could also refer to the name imported here | ^^^^ = note: consider adding an explicit import of `foo` to disambiguate -error: `foo` is ambiguous +error[E0659]: `foo` is ambiguous --> $DIR/duplicate.rs:46:5 | 46 | g::foo(); //~ ERROR `foo` is ambiguous @@ -66,7 +66,7 @@ note: `foo` could also refer to the name imported here | ^^^^ = note: consider adding an explicit import of `foo` to disambiguate -error: `foo` is ambiguous +error[E0659]: `foo` is ambiguous --> $DIR/duplicate.rs:59:9 | 59 | foo::bar(); //~ ERROR `foo` is ambiguous diff --git a/src/test/ui/imports/macro-paths.stderr b/src/test/ui/imports/macro-paths.stderr index 91b0b9756da..32d78666004 100644 --- a/src/test/ui/imports/macro-paths.stderr +++ b/src/test/ui/imports/macro-paths.stderr @@ -1,4 +1,4 @@ -error: `bar` is ambiguous +error[E0659]: `bar` is ambiguous --> $DIR/macro-paths.rs:25:5 | 25 | bar::m! { //~ ERROR ambiguous @@ -16,7 +16,7 @@ note: `bar` could also refer to the name imported here | ^^^^^^ = note: macro-expanded items do not shadow when used in a macro invocation path -error: `baz` is ambiguous +error[E0659]: `baz` is ambiguous --> $DIR/macro-paths.rs:35:5 | 35 | baz::m! { //~ ERROR ambiguous diff --git a/src/test/ui/imports/macros.stderr b/src/test/ui/imports/macros.stderr index 0b67613eb14..75294f7bf12 100644 --- a/src/test/ui/imports/macros.stderr +++ b/src/test/ui/imports/macros.stderr @@ -15,7 +15,7 @@ note: `m` could also refer to the macro imported here 49 | use two_macros::m; | ^^^^^^^^^^^^^ -error: `m` is ambiguous +error[E0659]: `m` is ambiguous --> $DIR/macros.rs:28:5 | 28 | m! { //~ ERROR ambiguous @@ -33,7 +33,7 @@ note: `m` could also refer to the name imported here | ^^^^^^^^^^^^^ = note: macro-expanded macro imports do not shadow -error: `m` is ambiguous +error[E0659]: `m` is ambiguous --> $DIR/macros.rs:41:9 | 41 | m! { //~ ERROR ambiguous diff --git a/src/test/ui/imports/shadow_builtin_macros.stderr b/src/test/ui/imports/shadow_builtin_macros.stderr index 853ed98c30d..8f4325fa12c 100644 --- a/src/test/ui/imports/shadow_builtin_macros.stderr +++ b/src/test/ui/imports/shadow_builtin_macros.stderr @@ -9,7 +9,7 @@ error: `panic` is already in scope | = note: macro-expanded `macro_rules!`s may not shadow existing macros (see RFC 1560) -error: `panic` is ambiguous +error[E0659]: `panic` is ambiguous --> $DIR/shadow_builtin_macros.rs:27:14 | 27 | fn f() { panic!(); } //~ ERROR ambiguous @@ -23,7 +23,7 @@ note: `panic` could refer to the name imported here = note: `panic` is also a builtin macro = note: consider adding an explicit import of `panic` to disambiguate -error: `panic` is ambiguous +error[E0659]: `panic` is ambiguous --> $DIR/shadow_builtin_macros.rs:32:14 | 32 | fn f() { panic!(); } //~ ERROR ambiguous @@ -37,7 +37,7 @@ note: `panic` could refer to the name imported here = note: `panic` is also a builtin macro = note: macro-expanded macro imports do not shadow -error: `n` is ambiguous +error[E0659]: `n` is ambiguous --> $DIR/shadow_builtin_macros.rs:61:5 | 61 | n!(); //~ ERROR ambiguous diff --git a/src/test/ui/issue-10969.stderr b/src/test/ui/issue-10969.stderr index 8aea63e0bbd..68127b282ed 100644 --- a/src/test/ui/issue-10969.stderr +++ b/src/test/ui/issue-10969.stderr @@ -1,26 +1,18 @@ error[E0618]: expected function, found `i32` --> $DIR/issue-10969.rs:12:5 | -12 | i(); //~ERROR expected function, found `i32` - | ^^^ - | -note: defined here - --> $DIR/issue-10969.rs:11:9 - | 11 | fn func(i: i32) { - | ^ + | - `i32` defined here +12 | i(); //~ERROR expected function, found `i32` + | ^^^ not a function error[E0618]: expected function, found `i32` --> $DIR/issue-10969.rs:16:5 | -16 | i(); //~ERROR expected function, found `i32` - | ^^^ - | -note: defined here - --> $DIR/issue-10969.rs:15:9 - | 15 | let i = 0i32; - | ^ + | - `i32` defined here +16 | i(); //~ERROR expected function, found `i32` + | ^^^ not a function error: aborting due to 2 previous errors diff --git a/src/test/ui/issue-24424.stderr b/src/test/ui/issue-24424.stderr index acdf348791b..55af26dd91e 100644 --- a/src/test/ui/issue-24424.stderr +++ b/src/test/ui/issue-24424.stderr @@ -4,7 +4,11 @@ error[E0283]: type annotations required: cannot resolve `T0: Trait0<'l0>` 14 | impl <'l0, 'l1, T0> Trait1<'l0, T0> for bool where T0 : Trait0<'l0>, T0 : Trait0<'l1> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: required by `Trait0` +note: required by `Trait0` + --> $DIR/issue-24424.rs:12:1 + | +12 | trait Trait0<'l0> {} + | ^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issue-46112.rs b/src/test/ui/issue-46112.rs index c292f73bf0b..698005b5d30 100644 --- a/src/test/ui/issue-46112.rs +++ b/src/test/ui/issue-46112.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// Issue 46112: An extern crate pub reexporting libcore was causing +// Issue 46112: An extern crate pub re-exporting libcore was causing // paths rooted from `std` to be misrendered in the diagnostic output. // ignore-windows diff --git a/src/test/ui/issue-46983.rs b/src/test/ui/issue-46983.rs new file mode 100644 index 00000000000..ebbd474b1c2 --- /dev/null +++ b/src/test/ui/issue-46983.rs @@ -0,0 +1,18 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(nll)] + +fn foo(x: &u32) -> &'static u32 { + &*x + //~^ ERROR explicit lifetime required in the type of `x` [E0621] +} + +fn main() {} diff --git a/src/test/ui/issue-46983.stderr b/src/test/ui/issue-46983.stderr new file mode 100644 index 00000000000..ac8417a7a24 --- /dev/null +++ b/src/test/ui/issue-46983.stderr @@ -0,0 +1,10 @@ +error[E0621]: explicit lifetime required in the type of `x` + --> $DIR/issue-46983.rs:14:5 + | +13 | fn foo(x: &u32) -> &'static u32 { + | - consider changing the type of `x` to `&'static u32` +14 | &*x + | ^^^ lifetime `'static` required + +error: aborting due to previous error + diff --git a/src/test/ui/issue-47377.rs b/src/test/ui/issue-47377.rs new file mode 100644 index 00000000000..f294008cfd0 --- /dev/null +++ b/src/test/ui/issue-47377.rs @@ -0,0 +1,15 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +// ignore-tidy-tab +fn main() { + let b = "hello"; + let _a = b + ", World!"; + //~^ ERROR E0369 +} diff --git a/src/test/ui/issue-47377.stderr b/src/test/ui/issue-47377.stderr new file mode 100644 index 00000000000..13b3ff58697 --- /dev/null +++ b/src/test/ui/issue-47377.stderr @@ -0,0 +1,12 @@ +error[E0369]: binary operation `+` cannot be applied to type `&str` + --> $DIR/issue-47377.rs:13:12 + | +13 | let _a = b + ", World!"; + | ^^^^^^^^^^^^^^ `+` can't be used to concatenate two `&str` strings +help: `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left + | +13 | let _a = b.to_owned() + ", World!"; + | ^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/issue-47380.rs b/src/test/ui/issue-47380.rs new file mode 100644 index 00000000000..e43a967253c --- /dev/null +++ b/src/test/ui/issue-47380.rs @@ -0,0 +1,14 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +fn main() { + let b = "hello"; + println!("🦀🦀🦀🦀🦀"); let _a = b + ", World!"; + //~^ ERROR E0369 +} diff --git a/src/test/ui/issue-47380.stderr b/src/test/ui/issue-47380.stderr new file mode 100644 index 00000000000..6c9f79b5a94 --- /dev/null +++ b/src/test/ui/issue-47380.stderr @@ -0,0 +1,12 @@ +error[E0369]: binary operation `+` cannot be applied to type `&str` + --> $DIR/issue-47380.rs:12:33 + | +12 | println!("🦀🦀🦀🦀🦀"); let _a = b + ", World!"; + | ^^^^^^^^^^^^^^ `+` can't be used to concatenate two `&str` strings +help: `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left + | +12 | println!("🦀🦀🦀🦀🦀"); let _a = b.to_owned() + ", World!"; + | ^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/issue-47623.rs b/src/test/ui/issue-47623.rs new file mode 100644 index 00000000000..0c886fdb52f --- /dev/null +++ b/src/test/ui/issue-47623.rs @@ -0,0 +1,13 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use self; //~ERROR `self` imports are only allowed within a { } list + +fn main() {} diff --git a/src/test/ui/issue-47623.stderr b/src/test/ui/issue-47623.stderr new file mode 100644 index 00000000000..c5a42d4d846 --- /dev/null +++ b/src/test/ui/issue-47623.stderr @@ -0,0 +1,8 @@ +error[E0429]: `self` imports are only allowed within a { } list + --> $DIR/issue-47623.rs:11:5 + | +11 | use self; //~ERROR `self` imports are only allowed within a { } list + | ^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/lint/suggestions.rs b/src/test/ui/lint/suggestions.rs index 3789b6dfc8b..dfcaede1402 100644 --- a/src/test/ui/lint/suggestions.rs +++ b/src/test/ui/lint/suggestions.rs @@ -24,6 +24,16 @@ pub fn defiant<T>(_t: T) {} fn rio_grande() {} // should suggest `pub` //~^ WARN function is marked +mod badlands { + // The private-no-mangle lints shouldn't suggest inserting `pub` when the + // item is already `pub` (but triggered the lint because, e.g., it's in a + // private module). (Issue #47383) + #[no_mangle] pub static DAUNTLESS: bool = true; + //~^ WARN static is marked + #[no_mangle] pub fn val_jean() {} + //~^ WARN function is marked +} + struct Equinox { warp_factor: f32, } diff --git a/src/test/ui/lint/suggestions.stderr b/src/test/ui/lint/suggestions.stderr index 701a9522218..8b30f552d37 100644 --- a/src/test/ui/lint/suggestions.stderr +++ b/src/test/ui/lint/suggestions.stderr @@ -1,7 +1,7 @@ warning: unnecessary parentheses around assigned value - --> $DIR/suggestions.rs:36:21 + --> $DIR/suggestions.rs:46:21 | -36 | let mut a = (1); // should suggest no `mut`, no parens +46 | let mut a = (1); // should suggest no `mut`, no parens | ^^^ help: remove these parentheses | note: lint level defined here @@ -11,17 +11,17 @@ note: lint level defined here | ^^^^^^^^^^^^^ warning: use of deprecated attribute `no_debug`: the `#[no_debug]` attribute was an experimental feature that has been deprecated due to lack of demand. See https://github.com/rust-lang/rust/issues/29721 - --> $DIR/suggestions.rs:31:1 + --> $DIR/suggestions.rs:41:1 | -31 | #[no_debug] // should suggest removal of deprecated attribute +41 | #[no_debug] // should suggest removal of deprecated attribute | ^^^^^^^^^^^ help: remove this attribute | = note: #[warn(deprecated)] on by default warning: variable does not need to be mutable - --> $DIR/suggestions.rs:36:13 + --> $DIR/suggestions.rs:46:13 | -36 | let mut a = (1); // should suggest no `mut`, no parens +46 | let mut a = (1); // should suggest no `mut`, no parens | ---^^ | | | help: remove this `mut` @@ -72,18 +72,30 @@ warning: function is marked #[no_mangle], but not exported | = note: #[warn(private_no_mangle_fns)] on by default +warning: static is marked #[no_mangle], but not exported + --> $DIR/suggestions.rs:31:18 + | +31 | #[no_mangle] pub static DAUNTLESS: bool = true; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: function is marked #[no_mangle], but not exported + --> $DIR/suggestions.rs:33:18 + | +33 | #[no_mangle] pub fn val_jean() {} + | ^^^^^^^^^^^^^^^^^^^^ + warning: denote infinite loops with `loop { ... }` - --> $DIR/suggestions.rs:34:5 + --> $DIR/suggestions.rs:44:5 | -34 | while true { // should suggest `loop` +44 | while true { // should suggest `loop` | ^^^^^^^^^^ help: use `loop` | = note: #[warn(while_true)] on by default warning: the `warp_factor:` in this pattern is redundant - --> $DIR/suggestions.rs:41:23 + --> $DIR/suggestions.rs:51:23 | -41 | Equinox { warp_factor: warp_factor } => {} // should suggest shorthand +51 | Equinox { warp_factor: warp_factor } => {} // should suggest shorthand | ------------^^^^^^^^^^^^ | | | help: remove this diff --git a/src/test/ui/macros/format-foreign.rs b/src/test/ui/macros/format-foreign.rs index 91ca8f5ff76..ec0eaed43ae 100644 --- a/src/test/ui/macros/format-foreign.rs +++ b/src/test/ui/macros/format-foreign.rs @@ -9,7 +9,7 @@ // except according to those terms. fn main() { - println!("%.*3$s %s!\n", "Hello,", "World", 4); + println!("%.*3$s %s!\n", "Hello,", "World", 4); //~ ERROR multiple unused formatting arguments println!("%1$*2$.*3$f", 123.456); //~ ERROR never used // This should *not* produce hints, on the basis that there's equally as diff --git a/src/test/ui/macros/format-foreign.stderr b/src/test/ui/macros/format-foreign.stderr index d0229957b68..f9852c54773 100644 --- a/src/test/ui/macros/format-foreign.stderr +++ b/src/test/ui/macros/format-foreign.stderr @@ -1,12 +1,8 @@ error: multiple unused formatting arguments - --> $DIR/format-foreign.rs:12:5 + --> $DIR/format-foreign.rs:12:30 | -12 | println!("%.*3$s %s!/n", "Hello,", "World", 4); - | ^^^^^^^^^^^^^^^^^^^^^^^^^--------^^-------^^-^^ - | | | | - | | | unused - | | unused - | unused +12 | println!("%.*3$s %s!/n", "Hello,", "World", 4); //~ ERROR multiple unused formatting arguments + | -------------------------^^^^^^^^--^^^^^^^--^-- multiple unused arguments in this statement | = help: `%.*3$s` should be written as `{:.2$}` = help: `%s` should be written as `{}` diff --git a/src/test/ui/macros/format-unused-lables.rs b/src/test/ui/macros/format-unused-lables.rs index 7a32d932ba3..3347a1215ce 100644 --- a/src/test/ui/macros/format-unused-lables.rs +++ b/src/test/ui/macros/format-unused-lables.rs @@ -10,9 +10,10 @@ fn main() { println!("Test", 123, 456, 789); + //~^ ERROR multiple unused formatting arguments println!("Test2", - 123, + 123, //~ ERROR multiple unused formatting arguments 456, 789 ); @@ -20,7 +21,7 @@ fn main() { println!("Some stuff", UNUSED="args"); //~ ERROR named argument never used println!("Some more $STUFF", - "woo!", + "woo!", //~ ERROR multiple unused formatting arguments STUFF= "things" , UNUSED="args"); diff --git a/src/test/ui/macros/format-unused-lables.stderr b/src/test/ui/macros/format-unused-lables.stderr index 9efdca12dea..64ea5626c1d 100644 --- a/src/test/ui/macros/format-unused-lables.stderr +++ b/src/test/ui/macros/format-unused-lables.stderr @@ -1,49 +1,43 @@ error: multiple unused formatting arguments - --> $DIR/format-unused-lables.rs:12:5 + --> $DIR/format-unused-lables.rs:12:22 | 12 | println!("Test", 123, 456, 789); - | ^^^^^^^^^^^^^^^^^---^^---^^---^^ - | | | | - | | | unused - | | unused - | unused + | -----------------^^^--^^^--^^^-- multiple unused arguments in this statement | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: multiple unused formatting arguments - --> $DIR/format-unused-lables.rs:14:5 + --> $DIR/format-unused-lables.rs:16:9 | -14 | / println!("Test2", -15 | | 123, - | | --- unused -16 | | 456, - | | --- unused -17 | | 789 - | | --- unused -18 | | ); - | |______^ +15 | / println!("Test2", +16 | | 123, //~ ERROR multiple unused formatting arguments + | | ^^^ +17 | | 456, + | | ^^^ +18 | | 789 + | | ^^^ +19 | | ); + | |______- multiple unused arguments in this statement | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: named argument never used - --> $DIR/format-unused-lables.rs:20:35 + --> $DIR/format-unused-lables.rs:21:35 | -20 | println!("Some stuff", UNUSED="args"); //~ ERROR named argument never used +21 | println!("Some stuff", UNUSED="args"); //~ ERROR named argument never used | ^^^^^^ error: multiple unused formatting arguments - --> $DIR/format-unused-lables.rs:22:5 + --> $DIR/format-unused-lables.rs:24:9 | -22 | / println!("Some more $STUFF", -23 | | "woo!", - | | ------ unused -24 | | STUFF= -25 | | "things" - | | -------- unused -26 | | , UNUSED="args"); - | |_______________________------_^ - | | - | unused +23 | / println!("Some more $STUFF", +24 | | "woo!", //~ ERROR multiple unused formatting arguments + | | ^^^^^^ +25 | | STUFF= +26 | | "things" + | | ^^^^^^^^ +27 | | , UNUSED="args"); + | |_______________________^^^^^^_- multiple unused arguments in this statement | = help: `$STUFF` should be written as `{STUFF}` = note: shell formatting not supported; see the documentation for `std::fmt` diff --git a/src/test/ui/macros/macro-name-typo.stderr b/src/test/ui/macros/macro-name-typo.stderr index 84851749c70..ebe95356c26 100644 --- a/src/test/ui/macros/macro-name-typo.stderr +++ b/src/test/ui/macros/macro-name-typo.stderr @@ -2,7 +2,7 @@ error: cannot find macro `printlx!` in this scope --> $DIR/macro-name-typo.rs:12:5 | 12 | printlx!("oh noes!"); //~ ERROR cannot find - | ^^^^^^^ help: you could try the macro: `println!` + | ^^^^^^^ help: you could try the macro: `println` error: aborting due to previous error diff --git a/src/test/ui/macros/macro_undefined.stderr b/src/test/ui/macros/macro_undefined.stderr index 6cfb05e7867..8d6da6a4732 100644 --- a/src/test/ui/macros/macro_undefined.stderr +++ b/src/test/ui/macros/macro_undefined.stderr @@ -10,7 +10,7 @@ error: cannot find macro `k!` in this scope --> $DIR/macro_undefined.rs:21:5 | 21 | k!(); //~ ERROR cannot find - | ^ help: you could try the macro: `kl!` + | ^ help: you could try the macro: `kl` error: aborting due to 2 previous errors diff --git a/src/test/ui/mismatched_types/E0631.stderr b/src/test/ui/mismatched_types/E0631.stderr index 442900e0a83..53f2f54325d 100644 --- a/src/test/ui/mismatched_types/E0631.stderr +++ b/src/test/ui/mismatched_types/E0631.stderr @@ -6,7 +6,11 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `fn(usize) -> _` | - = note: required by `foo` +note: required by `foo` + --> $DIR/E0631.rs:13:1 + | +13 | fn foo<F: Fn(usize)>(_: F) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments --> $DIR/E0631.rs:18:5 @@ -16,7 +20,11 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `fn(usize) -> _` | - = note: required by `bar` +note: required by `bar` + --> $DIR/E0631.rs:14:1 + | +14 | fn bar<F: Fn<usize>>(_: F) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in function arguments --> $DIR/E0631.rs:19:5 @@ -27,7 +35,11 @@ error[E0631]: type mismatch in function arguments 19 | foo(f); //~ ERROR type mismatch | ^^^ expected signature of `fn(usize) -> _` | - = note: required by `foo` +note: required by `foo` + --> $DIR/E0631.rs:13:1 + | +13 | fn foo<F: Fn(usize)>(_: F) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in function arguments --> $DIR/E0631.rs:20:5 @@ -38,7 +50,11 @@ error[E0631]: type mismatch in function arguments 20 | bar(f); //~ ERROR type mismatch | ^^^ expected signature of `fn(usize) -> _` | - = note: required by `bar` +note: required by `bar` + --> $DIR/E0631.rs:14:1 + | +14 | fn bar<F: Fn<usize>>(_: F) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 4 previous errors diff --git a/src/test/ui/mismatched_types/closure-arg-count.rs b/src/test/ui/mismatched_types/closure-arg-count.rs index 1ee24e39852..96e5201716c 100644 --- a/src/test/ui/mismatched_types/closure-arg-count.rs +++ b/src/test/ui/mismatched_types/closure-arg-count.rs @@ -18,6 +18,8 @@ fn main() { //~^ ERROR closure is expected to take [1, 2, 3].sort_by(|(tuple, tuple2)| panic!()); //~^ ERROR closure is expected to take + [1, 2, 3].sort_by(|(tuple, tuple2): (usize, _)| panic!()); + //~^ ERROR closure is expected to take f(|| panic!()); //~^ ERROR closure is expected to take @@ -32,6 +34,9 @@ fn main() { let bar = |i, x, y| i; let _it = vec![1, 2, 3].into_iter().enumerate().map(bar); //~^ ERROR closure is expected to take + let _it = vec![1, 2, 3].into_iter().enumerate().map(qux); + //~^ ERROR function is expected to take } fn foo() {} +fn qux(x: usize, y: usize) {} diff --git a/src/test/ui/mismatched_types/closure-arg-count.stderr b/src/test/ui/mismatched_types/closure-arg-count.stderr index 216f39bac54..be00ee4d74e 100644 --- a/src/test/ui/mismatched_types/closure-arg-count.stderr +++ b/src/test/ui/mismatched_types/closure-arg-count.stderr @@ -14,64 +14,101 @@ error[E0593]: closure is expected to take 2 arguments, but it takes 1 argument | | | expected closure that takes 2 arguments -error[E0593]: closure is expected to take 2 arguments, but it takes 1 argument +error[E0593]: closure is expected to take 2 distinct arguments, but it takes a single 2-tuple as argument --> $DIR/closure-arg-count.rs:19:15 | 19 | [1, 2, 3].sort_by(|(tuple, tuple2)| panic!()); - | ^^^^^^^ ----------------- takes 1 argument + | ^^^^^^^ ----------------- takes a single 2-tuple as argument | | - | expected closure that takes 2 arguments + | expected closure that takes 2 distinct arguments +help: change the closure to take multiple arguments instead of a single tuple + | +19 | [1, 2, 3].sort_by(|tuple, tuple2| panic!()); + | ^^^^^^^^^^^^^^^ + +error[E0593]: closure is expected to take 2 distinct arguments, but it takes a single 2-tuple as argument + --> $DIR/closure-arg-count.rs:21:15 + | +21 | [1, 2, 3].sort_by(|(tuple, tuple2): (usize, _)| panic!()); + | ^^^^^^^ ----------------------------- takes a single 2-tuple as argument + | | + | expected closure that takes 2 distinct arguments +help: change the closure to take multiple arguments instead of a single tuple + | +21 | [1, 2, 3].sort_by(|tuple, tuple2| panic!()); + | ^^^^^^^^^^^^^^^ error[E0593]: closure is expected to take 1 argument, but it takes 0 arguments - --> $DIR/closure-arg-count.rs:21:5 + --> $DIR/closure-arg-count.rs:23:5 | -21 | f(|| panic!()); +23 | f(|| panic!()); | ^ -- takes 0 arguments | | | expected closure that takes 1 argument | - = note: required by `f` +note: required by `f` + --> $DIR/closure-arg-count.rs:13:1 + | +13 | fn f<F: Fn<usize>>(_: F) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0593]: closure is expected to take a single tuple as argument, but it takes 2 distinct arguments - --> $DIR/closure-arg-count.rs:24:53 +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 | -24 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x| i); - | ^^^ ------ help: consider changing the closure to accept a tuple: `|(i, x)|` +26 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x| i); + | ^^^ ------ takes 2 distinct arguments | | - | expected closure that takes a single tuple as argument + | expected closure that takes a single 2-tuple as argument +help: change the closure to accept a tuple instead of individual arguments + | +26 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|(i, x)| i); + | ^^^^^^^^ -error[E0593]: closure is expected to take a single tuple as argument, but it takes 2 distinct arguments - --> $DIR/closure-arg-count.rs:26:53 +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 | -26 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i: usize, x| i); - | ^^^ ------------- help: consider changing the closure to accept a tuple: `|(i, x): (usize, _)|` +28 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i: usize, x| i); + | ^^^ ------------- takes 2 distinct arguments | | - | expected closure that takes a single tuple as argument + | expected closure that takes a single 2-tuple as argument +help: change the closure to accept a tuple instead of individual arguments + | +28 | 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:28:53 + --> $DIR/closure-arg-count.rs:30:53 | -28 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x, y| i); +30 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x, y| i); | ^^^ --------- takes 3 distinct arguments | | | 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:30:53 + --> $DIR/closure-arg-count.rs:32:53 | -30 | let _it = vec![1, 2, 3].into_iter().enumerate().map(foo); +32 | let _it = vec![1, 2, 3].into_iter().enumerate().map(foo); | ^^^ expected function that takes a single 2-tuple as argument ... -37 | fn foo() {} +41 | 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:33:53 + --> $DIR/closure-arg-count.rs:35:53 | -32 | let bar = |i, x, y| i; +34 | let bar = |i, x, y| i; | --------- takes 3 distinct arguments -33 | let _it = vec![1, 2, 3].into_iter().enumerate().map(bar); +35 | let _it = vec![1, 2, 3].into_iter().enumerate().map(bar); | ^^^ expected closure that takes a single 2-tuple as argument -error: aborting due to 9 previous errors +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 + | +37 | let _it = vec![1, 2, 3].into_iter().enumerate().map(qux); + | ^^^ expected function that takes a single 2-tuple as argument +... +42 | fn qux(x: usize, y: usize) {} + | -------------------------- takes 2 distinct arguments + +error: aborting due to 11 previous errors diff --git a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr index 77d3a332767..dfd02fe23b6 100644 --- a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr +++ b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr @@ -31,7 +31,11 @@ error[E0631]: type mismatch in function arguments | expected signature of `for<'r> fn(*mut &'r u32) -> _` | found signature of `fn(*mut &'a u32) -> _` | - = note: required by `baz` +note: required by `baz` + --> $DIR/closure-arg-type-mismatch.rs:18:1 + | +18 | fn baz<F: Fn(*mut &u32)>(_: F) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0271]: type mismatch resolving `for<'r> <fn(*mut &'a u32) as std::ops::FnOnce<(*mut &'r u32,)>>::Output == ()` --> $DIR/closure-arg-type-mismatch.rs:20:5 @@ -39,7 +43,11 @@ error[E0271]: type mismatch resolving `for<'r> <fn(*mut &'a u32) as std::ops::Fn 20 | baz(f); //~ ERROR type mismatch | ^^^ expected bound lifetime parameter, found concrete lifetime | - = note: required by `baz` +note: required by `baz` + --> $DIR/closure-arg-type-mismatch.rs:18:1 + | +18 | fn baz<F: Fn(*mut &u32)>(_: F) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 5 previous errors diff --git a/src/test/ui/mismatched_types/closure-mismatch.stderr b/src/test/ui/mismatched_types/closure-mismatch.stderr index 99767ba1afa..01de7e07495 100644 --- a/src/test/ui/mismatched_types/closure-mismatch.stderr +++ b/src/test/ui/mismatched_types/closure-mismatch.stderr @@ -5,7 +5,11 @@ error[E0271]: type mismatch resolving `for<'r> <[closure@$DIR/closure-mismatch.r | ^^^ expected bound lifetime parameter, found concrete lifetime | = note: required because of the requirements on the impl of `Foo` for `[closure@$DIR/closure-mismatch.rs:18:9: 18:15]` - = note: required by `baz` +note: required by `baz` + --> $DIR/closure-mismatch.rs:15:1 + | +15 | fn baz<T: Foo>(_: T) {} + | ^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments --> $DIR/closure-mismatch.rs:18:5 @@ -16,7 +20,11 @@ error[E0631]: type mismatch in closure arguments | expected signature of `for<'r> fn(&'r ()) -> _` | = note: required because of the requirements on the impl of `Foo` for `[closure@$DIR/closure-mismatch.rs:18:9: 18:15]` - = note: required by `baz` +note: required by `baz` + --> $DIR/closure-mismatch.rs:15:1 + | +15 | fn baz<T: Foo>(_: T) {} + | ^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/mismatched_types/fn-variance-1.stderr b/src/test/ui/mismatched_types/fn-variance-1.stderr index 2a27ffd1062..64c260c30ed 100644 --- a/src/test/ui/mismatched_types/fn-variance-1.stderr +++ b/src/test/ui/mismatched_types/fn-variance-1.stderr @@ -7,7 +7,11 @@ error[E0631]: type mismatch in function arguments 21 | apply(&3, takes_mut); | ^^^^^ expected signature of `fn(&{integer}) -> _` | - = note: required by `apply` +note: required by `apply` + --> $DIR/fn-variance-1.rs:15:1 + | +15 | fn apply<T, F>(t: T, f: F) where F: FnOnce(T) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in function arguments --> $DIR/fn-variance-1.rs:25:5 @@ -18,7 +22,11 @@ error[E0631]: type mismatch in function arguments 25 | apply(&mut 3, takes_imm); | ^^^^^ expected signature of `fn(&mut {integer}) -> _` | - = note: required by `apply` +note: required by `apply` + --> $DIR/fn-variance-1.rs:15:1 + | +15 | fn apply<T, F>(t: T, f: F) where F: FnOnce(T) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs index 10f4b3229f0..f2237e495a0 100644 --- a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs +++ b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs @@ -15,13 +15,15 @@ use std::ops::FnMut; fn to_fn_mut<A,F:FnMut<A>>(f: F) -> F { f } fn call_it<F:FnMut(isize,isize)->isize>(y: isize, mut f: F) -> isize { +//~^ NOTE required by `call_it` f(2, y) } pub fn main() { let f = to_fn_mut(|x: usize, y: isize| -> isize { (x as isize) + y }); + //~^ NOTE found signature of `fn(usize, isize) -> _` let z = call_it(3, f); //~^ ERROR type mismatch - //~| required by `call_it` + //~| NOTE expected signature of `fn(isize, isize) -> _` println!("{}", z); } diff --git a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr index 8539c8818c0..9c9bbd19c75 100644 --- a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr +++ b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr @@ -1,12 +1,17 @@ error[E0631]: type mismatch in closure arguments - --> $DIR/unboxed-closures-vtable-mismatch.rs:23:13 + --> $DIR/unboxed-closures-vtable-mismatch.rs:25:13 | -22 | let f = to_fn_mut(|x: usize, y: isize| -> isize { (x as isize) + y }); +23 | let f = to_fn_mut(|x: usize, y: isize| -> isize { (x as isize) + y }); | ----------------------------- found signature of `fn(usize, isize) -> _` -23 | let z = call_it(3, f); +24 | //~^ NOTE found signature of `fn(usize, isize) -> _` +25 | let z = call_it(3, f); | ^^^^^^^ expected signature of `fn(isize, isize) -> _` | - = note: required by `call_it` +note: required by `call_it` + --> $DIR/unboxed-closures-vtable-mismatch.rs:17:1 + | +17 | fn call_it<F:FnMut(isize,isize)->isize>(y: isize, mut f: F) -> isize { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/nll/borrowed-match-issue-45045.rs b/src/test/ui/nll/borrowed-match-issue-45045.rs new file mode 100644 index 00000000000..8688bfa86dc --- /dev/null +++ b/src/test/ui/nll/borrowed-match-issue-45045.rs @@ -0,0 +1,30 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Regression test for issue #45045 + +#![feature(nll)] + +enum Xyz { + A, + B, +} + +fn main() { + let mut e = Xyz::A; + let f = &mut e; + let g = f; + match e { + Xyz::A => println!("a"), + //~^ cannot use `e` because it was mutably borrowed [E0503] + Xyz::B => println!("b"), + }; + *g = Xyz::B; +} diff --git a/src/test/ui/nll/borrowed-match-issue-45045.stderr b/src/test/ui/nll/borrowed-match-issue-45045.stderr new file mode 100644 index 00000000000..15ca30010a5 --- /dev/null +++ b/src/test/ui/nll/borrowed-match-issue-45045.stderr @@ -0,0 +1,11 @@ +error[E0503]: cannot use `e` because it was mutably borrowed + --> $DIR/borrowed-match-issue-45045.rs:25:9 + | +22 | let f = &mut e; + | ------ borrow of `e` occurs here +... +25 | Xyz::A => println!("a"), + | ^^^^^^ use of borrowed `e` + +error: aborting due to previous error + diff --git a/src/test/ui/nll/borrowed-referent-issue-38899.rs b/src/test/ui/nll/borrowed-referent-issue-38899.rs new file mode 100644 index 00000000000..d7c15851418 --- /dev/null +++ b/src/test/ui/nll/borrowed-referent-issue-38899.rs @@ -0,0 +1,30 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Regression test for issue #38899 + +#![feature(nll)] +#![allow(dead_code)] + +pub struct Block<'a> { + current: &'a u8, + unrelated: &'a u8, +} + +fn bump<'a>(mut block: &mut Block<'a>) { + let x = &mut block; + println!("{}", x.current); + let p: &'a u8 = &*block.current; + //~^ ERROR cannot borrow `*block.current` as immutable because it is also borrowed as mutable + drop(x); + drop(p); +} + +fn main() {} diff --git a/src/test/ui/nll/borrowed-referent-issue-38899.stderr b/src/test/ui/nll/borrowed-referent-issue-38899.stderr new file mode 100644 index 00000000000..3031fec2d0b --- /dev/null +++ b/src/test/ui/nll/borrowed-referent-issue-38899.stderr @@ -0,0 +1,11 @@ +error[E0502]: cannot borrow `*block.current` as immutable because it is also borrowed as mutable + --> $DIR/borrowed-referent-issue-38899.rs:24:21 + | +22 | let x = &mut block; + | ---------- mutable borrow occurs here +23 | println!("{}", x.current); +24 | let p: &'a u8 = &*block.current; + | ^^^^^^^^^^^^^^^ immutable borrow occurs here + +error: aborting due to previous error + diff --git a/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.rs b/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.rs index 3f56dfe5af4..ac21fe25bd1 100644 --- a/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.rs +++ b/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.rs @@ -18,7 +18,7 @@ fn foo(x: &u32) -> &'static u32 { &*x //~^ WARN not reporting region error due to -Znll - //~| ERROR does not outlive free region + //~| ERROR explicit lifetime required in the type of `x` } fn main() { } diff --git a/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.stderr b/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.stderr index 6648e38e7de..2a1122cbda7 100644 --- a/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.stderr +++ b/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.stderr @@ -4,11 +4,13 @@ warning: not reporting region error due to -Znll 19 | &*x | ^^^ -error: free region `ReFree(DefId(0/0:3 ~ region_lbr_anon_does_not_outlive_static[317d]::foo[0]), BrAnon(0))` does not outlive free region `ReStatic` +error[E0621]: explicit lifetime required in the type of `x` --> $DIR/region-lbr-anon-does-not-outlive-static.rs:19:5 | +18 | fn foo(x: &u32) -> &'static u32 { + | - consider changing the type of `x` to `&ReStatic u32` 19 | &*x - | ^^^ + | ^^^ lifetime `ReStatic` required error: aborting due to previous error diff --git a/src/test/ui/nll/generator-distinct-lifetime.rs b/src/test/ui/nll/generator-distinct-lifetime.rs new file mode 100644 index 00000000000..60f67b1766c --- /dev/null +++ b/src/test/ui/nll/generator-distinct-lifetime.rs @@ -0,0 +1,35 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(generators, nll)] + +// Test for issue #47189. Here, both `s` and `t` are live for the +// generator's lifetime, but within the generator they have distinct +// lifetimes. We accept this code -- even though the borrow extends +// over a yield -- because the data that is borrowed (`*x`) is not +// stored on the stack. + +// must-compile-successfully + +fn foo(x: &mut u32) { + move || { + let s = &mut *x; + yield; + *s += 1; + + let t = &mut *x; + yield; + *t += 1; + }; +} + +fn main() { + foo(&mut 0); +} diff --git a/src/test/ui/nll/guarantor-issue-46974.rs b/src/test/ui/nll/guarantor-issue-46974.rs index 57ecddb80ab..09ce42ce1b5 100644 --- a/src/test/ui/nll/guarantor-issue-46974.rs +++ b/src/test/ui/nll/guarantor-issue-46974.rs @@ -22,7 +22,7 @@ fn foo(s: &mut (i32,)) -> i32 { fn bar(s: &Box<(i32,)>) -> &'static i32 { // FIXME(#46983): error message should be better - &s.0 //~ ERROR free region `` does not outlive free region `'static` + &s.0 //~ ERROR explicit lifetime required in the type of `s` [E0621] } fn main() { diff --git a/src/test/ui/nll/guarantor-issue-46974.stderr b/src/test/ui/nll/guarantor-issue-46974.stderr index 68cc87ef407..4f0bd88f988 100644 --- a/src/test/ui/nll/guarantor-issue-46974.stderr +++ b/src/test/ui/nll/guarantor-issue-46974.stderr @@ -7,11 +7,14 @@ error[E0506]: cannot assign to `*s` because it is borrowed 19 | *s = (2,); //~ ERROR cannot assign to `*s` | ^^^^^^^^^ assignment to borrowed `*s` occurs here -error: free region `` does not outlive free region `'static` +error[E0621]: explicit lifetime required in the type of `s` --> $DIR/guarantor-issue-46974.rs:25:5 | -25 | &s.0 //~ ERROR free region `` does not outlive free region `'static` - | ^^^^ +23 | fn bar(s: &Box<(i32,)>) -> &'static i32 { + | - consider changing the type of `s` to `&'static std::boxed::Box<(i32,)>` +24 | // FIXME(#46983): error message should be better +25 | &s.0 //~ ERROR explicit lifetime required in the type of `s` [E0621] + | ^^^^ lifetime `'static` required error: aborting due to 2 previous errors diff --git a/src/test/ui/nll/return-ref-mut-issue-46557.rs b/src/test/ui/nll/return-ref-mut-issue-46557.rs new file mode 100644 index 00000000000..79150f340ca --- /dev/null +++ b/src/test/ui/nll/return-ref-mut-issue-46557.rs @@ -0,0 +1,21 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Regression test for issue #46557 + +#![feature(nll)] +#![allow(dead_code)] + +fn gimme_static_mut() -> &'static mut u32 { + let ref mut x = 1234543; //~ ERROR borrowed value does not live long enough [E0597] + x +} + +fn main() {} diff --git a/src/test/ui/nll/return-ref-mut-issue-46557.stderr b/src/test/ui/nll/return-ref-mut-issue-46557.stderr new file mode 100644 index 00000000000..763e2bfd892 --- /dev/null +++ b/src/test/ui/nll/return-ref-mut-issue-46557.stderr @@ -0,0 +1,13 @@ +error[E0597]: borrowed value does not live long enough + --> $DIR/return-ref-mut-issue-46557.rs:17:21 + | +17 | let ref mut x = 1234543; //~ ERROR borrowed value does not live long enough [E0597] + | ^^^^^^^ temporary value does not live long enough +18 | x +19 | } + | - temporary value only lives until here + | + = note: borrowed value must be valid for lifetime '_#2r... + +error: aborting due to previous error + diff --git a/src/test/ui/non_modrs_mods/non_modrs_mods.stderr b/src/test/ui/non_modrs_mods/non_modrs_mods.stderr index 95a2539ed64..f60d2e93e36 100644 --- a/src/test/ui/non_modrs_mods/non_modrs_mods.stderr +++ b/src/test/ui/non_modrs_mods/non_modrs_mods.stderr @@ -1,4 +1,4 @@ -error: mod statements in non-mod.rs files are unstable (see issue #44660) +error[E0658]: mod statements in non-mod.rs files are unstable (see issue #44660) --> $DIR/modrs_mod/inner_foors_mod.rs:11:9 | 11 | pub mod innest; @@ -7,7 +7,7 @@ error: mod statements in non-mod.rs files are unstable (see issue #44660) = help: add #![feature(non_modrs_mods)] to the crate attributes to enable = help: on stable builds, rename this file to inner_foors_mod/mod.rs -error: mod statements in non-mod.rs files are unstable (see issue #44660) +error[E0658]: mod statements in non-mod.rs files are unstable (see issue #44660) --> $DIR/foors_mod.rs:13:9 | 13 | pub mod inner_modrs_mod; @@ -16,7 +16,7 @@ error: mod statements in non-mod.rs files are unstable (see issue #44660) = help: add #![feature(non_modrs_mods)] to the crate attributes to enable = help: on stable builds, rename this file to foors_mod/mod.rs -error: mod statements in non-mod.rs files are unstable (see issue #44660) +error[E0658]: mod statements in non-mod.rs files are unstable (see issue #44660) --> $DIR/foors_mod.rs:14:9 | 14 | pub mod inner_foors_mod; @@ -25,7 +25,7 @@ error: mod statements in non-mod.rs files are unstable (see issue #44660) = help: add #![feature(non_modrs_mods)] to the crate attributes to enable = help: on stable builds, rename this file to foors_mod/mod.rs -error: mod statements in non-mod.rs files are unstable (see issue #44660) +error[E0658]: mod statements in non-mod.rs files are unstable (see issue #44660) --> $DIR/foors_mod/inner_foors_mod.rs:11:9 | 11 | pub mod innest; diff --git a/src/test/ui/on-unimplemented/multiple-impls.stderr b/src/test/ui/on-unimplemented/multiple-impls.stderr index 1f71be446ef..cfac3981be2 100644 --- a/src/test/ui/on-unimplemented/multiple-impls.stderr +++ b/src/test/ui/on-unimplemented/multiple-impls.stderr @@ -5,7 +5,11 @@ error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied | ^^^^^^^^^^^^ trait message | = help: the trait `Index<u32>` is not implemented for `[i32]` - = note: required by `Index::index` +note: required by `Index::index` + --> $DIR/multiple-impls.rs:22:5 + | +22 | fn index(&self, index: Idx) -> &Self::Output; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied --> $DIR/multiple-impls.rs:43:5 @@ -22,7 +26,11 @@ error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied | ^^^^^^^^^^^^ on impl for Foo | = help: the trait `Index<Foo<u32>>` is not implemented for `[i32]` - = note: required by `Index::index` +note: required by `Index::index` + --> $DIR/multiple-impls.rs:22:5 + | +22 | fn index(&self, index: Idx) -> &Self::Output; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied --> $DIR/multiple-impls.rs:46:5 @@ -39,7 +47,11 @@ error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied | ^^^^^^^^^^^^ on impl for Bar | = help: the trait `Index<Bar<u32>>` is not implemented for `[i32]` - = note: required by `Index::index` +note: required by `Index::index` + --> $DIR/multiple-impls.rs:22:5 + | +22 | fn index(&self, index: Idx) -> &Self::Output; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied --> $DIR/multiple-impls.rs:49:5 diff --git a/src/test/ui/on-unimplemented/on-impl.stderr b/src/test/ui/on-unimplemented/on-impl.stderr index c8c06bf44fd..ed2da68f081 100644 --- a/src/test/ui/on-unimplemented/on-impl.stderr +++ b/src/test/ui/on-unimplemented/on-impl.stderr @@ -5,7 +5,11 @@ error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied | ^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice | = help: the trait `Index<u32>` is not implemented for `[i32]` - = note: required by `Index::index` +note: required by `Index::index` + --> $DIR/on-impl.rs:19:5 + | +19 | fn index(&self, index: Idx) -> &Self::Output; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied --> $DIR/on-impl.rs:32:5 diff --git a/src/test/ui/on-unimplemented/on-trait.stderr b/src/test/ui/on-unimplemented/on-trait.stderr index cde56022fae..028200a5558 100644 --- a/src/test/ui/on-unimplemented/on-trait.stderr +++ b/src/test/ui/on-unimplemented/on-trait.stderr @@ -5,7 +5,11 @@ error[E0277]: the trait bound `std::option::Option<std::vec::Vec<u8>>: MyFromIte | ^^^^^^^ a collection of type `std::option::Option<std::vec::Vec<u8>>` cannot be built from an iterator over elements of type `&u8` | = help: the trait `MyFromIterator<&u8>` is not implemented for `std::option::Option<std::vec::Vec<u8>>` - = note: required by `collect` +note: required by `collect` + --> $DIR/on-trait.rs:31:1 + | +31 | fn collect<A, I: Iterator<Item=A>, B: MyFromIterator<A>>(it: I) -> B { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `std::string::String: Bar::Foo<u8, _, u32>` is not satisfied --> $DIR/on-trait.rs:40:21 @@ -14,7 +18,11 @@ error[E0277]: the trait bound `std::string::String: Bar::Foo<u8, _, u32>` is not | ^^^^^^ test error `std::string::String` with `u8` `_` `u32` in `Bar::Foo` | = help: the trait `Bar::Foo<u8, _, u32>` is not implemented for `std::string::String` - = note: required by `foobar` +note: required by `foobar` + --> $DIR/on-trait.rs:21:1 + | +21 | fn foobar<U: Clone, T: Foo<u8, U, u32>>() -> T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/pat-slice-old-style.stderr b/src/test/ui/pat-slice-old-style.stderr index 5e7cd10235d..29c41c49cc4 100644 --- a/src/test/ui/pat-slice-old-style.stderr +++ b/src/test/ui/pat-slice-old-style.stderr @@ -1,4 +1,4 @@ -error: non-reference pattern used to match a reference (see issue #42640) +error[E0658]: non-reference pattern used to match a reference (see issue #42640) --> $DIR/pat-slice-old-style.rs:19:9 | 19 | [a, b..] => {}, diff --git a/src/test/ui/resolve/privacy-enum-ctor.rs b/src/test/ui/resolve/privacy-enum-ctor.rs new file mode 100644 index 00000000000..08480a0e1fa --- /dev/null +++ b/src/test/ui/resolve/privacy-enum-ctor.rs @@ -0,0 +1,81 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +mod m { + pub enum E { + Fn(u8), + Struct { + s: u8, + }, + Unit, + } + + pub mod n { + pub(in m) enum Z { + Fn(u8), + Struct { + s: u8, + }, + Unit, + } + } + + use m::n::Z; // OK, only the type is imported + + fn f() { + n::Z; + //~^ ERROR expected value, found enum `n::Z` + Z; + //~^ ERROR expected value, found enum `Z` + let _: Z = Z::Fn; + //~^ ERROR mismatched types + let _: Z = Z::Struct; + //~^ ERROR expected value, found struct variant `Z::Struct` + let _ = Z::Unit(); + //~^ ERROR expected function, found enum variant `Z::Unit` + let _ = Z::Unit {}; + // This is ok, it is equivalent to not having braces + } +} + +use m::E; // OK, only the type is imported + +fn main() { + let _: E = m::E; + //~^ ERROR expected value, found enum `m::E` + let _: E = m::E::Fn; + //~^ ERROR mismatched types + let _: E = m::E::Struct; + //~^ ERROR expected value, found struct variant `m::E::Struct` + let _: E = m::E::Unit(); + //~^ ERROR expected function, found enum variant `m::E::Unit` + let _: E = E; + //~^ ERROR expected value, found enum `E` + let _: E = E::Fn; + //~^ ERROR mismatched types + let _: E = E::Struct; + //~^ ERROR expected value, found struct variant `E::Struct` + let _: E = E::Unit(); + //~^ ERROR expected function, found enum variant `E::Unit` + let _: Z = m::n::Z; + //~^ ERROR cannot find type `Z` in this scope + //~| ERROR expected value, found enum `m::n::Z` + //~| ERROR enum `Z` is private + let _: Z = m::n::Z::Fn; + //~^ ERROR cannot find type `Z` in this scope + //~| ERROR enum `Z` is private + let _: Z = m::n::Z::Struct; + //~^ ERROR cannot find type `Z` in this scope + //~| ERROR expected value, found struct variant `m::n::Z::Struct` + //~| ERROR enum `Z` is private + let _: Z = m::n::Z::Unit {}; + //~^ ERROR cannot find type `Z` in this scope + //~| ERROR enum `Z` is private +} diff --git a/src/test/ui/resolve/privacy-enum-ctor.stderr b/src/test/ui/resolve/privacy-enum-ctor.stderr new file mode 100644 index 00000000000..c4f6d1f5b74 --- /dev/null +++ b/src/test/ui/resolve/privacy-enum-ctor.stderr @@ -0,0 +1,225 @@ +error[E0423]: expected value, found enum `n::Z` + --> $DIR/privacy-enum-ctor.rs:33:9 + | +33 | n::Z; + | ^^^^ + | + = note: did you mean to use one of the following variants? + - `m::Z::Fn` + - `m::Z::Struct` + - `m::Z::Unit` + +error[E0423]: expected value, found enum `Z` + --> $DIR/privacy-enum-ctor.rs:35:9 + | +35 | Z; + | ^ did you mean `f`? + | + = note: did you mean to use one of the following variants? + - `m::Z::Fn` + - `m::Z::Struct` + - `m::Z::Unit` + +error[E0423]: expected value, found struct variant `Z::Struct` + --> $DIR/privacy-enum-ctor.rs:39:20 + | +39 | let _: Z = Z::Struct; + | ^^^^^^^^^ did you mean `Z::Struct { /* fields */ }`? + +error[E0423]: expected value, found enum `m::E` + --> $DIR/privacy-enum-ctor.rs:51:16 + | +51 | let _: E = m::E; + | ^^^- + | | + | did you mean `f`? + | + = note: did you mean to use one of the following variants? + - `E::Fn` + - `E::Struct` + - `E::Unit` +help: possible better candidates are found in other modules, you can import them into scope + | +48 | use std::f32::consts::E; + | +48 | use std::f64::consts::E; + | + +error[E0423]: expected value, found struct variant `m::E::Struct` + --> $DIR/privacy-enum-ctor.rs:55:16 + | +55 | let _: E = m::E::Struct; + | ^^^^^^^^^^^^ did you mean `m::E::Struct { /* fields */ }`? + +error[E0423]: expected value, found enum `E` + --> $DIR/privacy-enum-ctor.rs:59:16 + | +59 | let _: E = E; + | ^ + | + = note: did you mean to use one of the following variants? + - `E::Fn` + - `E::Struct` + - `E::Unit` +help: possible better candidates are found in other modules, you can import them into scope + | +48 | use std::f32::consts::E; + | +48 | use std::f64::consts::E; + | + +error[E0423]: expected value, found struct variant `E::Struct` + --> $DIR/privacy-enum-ctor.rs:63:16 + | +63 | let _: E = E::Struct; + | ^^^^^^^^^ did you mean `E::Struct { /* fields */ }`? + +error[E0412]: cannot find type `Z` in this scope + --> $DIR/privacy-enum-ctor.rs:67:12 + | +67 | let _: Z = m::n::Z; + | ^ did you mean `E`? +help: possible candidate is found in another module, you can import it into scope + | +48 | use m::n::Z; + | + +error[E0423]: expected value, found enum `m::n::Z` + --> $DIR/privacy-enum-ctor.rs:67:16 + | +67 | let _: Z = m::n::Z; + | ^^^^^^^ + | + = note: did you mean to use one of the following variants? + - `m::Z::Fn` + - `m::Z::Struct` + - `m::Z::Unit` + +error[E0412]: cannot find type `Z` in this scope + --> $DIR/privacy-enum-ctor.rs:71:12 + | +71 | let _: Z = m::n::Z::Fn; + | ^ did you mean `E`? +help: possible candidate is found in another module, you can import it into scope + | +48 | use m::n::Z; + | + +error[E0412]: cannot find type `Z` in this scope + --> $DIR/privacy-enum-ctor.rs:74:12 + | +74 | let _: Z = m::n::Z::Struct; + | ^ did you mean `E`? +help: possible candidate is found in another module, you can import it into scope + | +48 | use m::n::Z; + | + +error[E0423]: expected value, found struct variant `m::n::Z::Struct` + --> $DIR/privacy-enum-ctor.rs:74:16 + | +74 | let _: Z = m::n::Z::Struct; + | ^^^^^^^^^^^^^^^ did you mean `m::n::Z::Struct { /* fields */ }`? + +error[E0412]: cannot find type `Z` in this scope + --> $DIR/privacy-enum-ctor.rs:78:12 + | +78 | let _: Z = m::n::Z::Unit {}; + | ^ did you mean `E`? +help: possible candidate is found in another module, you can import it into scope + | +48 | use m::n::Z; + | + +error[E0603]: enum `Z` is private + --> $DIR/privacy-enum-ctor.rs:67:16 + | +67 | let _: Z = m::n::Z; + | ^^^^^^^ + +error[E0603]: enum `Z` is private + --> $DIR/privacy-enum-ctor.rs:71:16 + | +71 | let _: Z = m::n::Z::Fn; + | ^^^^^^^^^^^ + +error[E0603]: enum `Z` is private + --> $DIR/privacy-enum-ctor.rs:74:16 + | +74 | let _: Z = m::n::Z::Struct; + | ^^^^^^^^^^^^^^^ + +error[E0603]: enum `Z` is private + --> $DIR/privacy-enum-ctor.rs:78:16 + | +78 | let _: Z = m::n::Z::Unit {}; + | ^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/privacy-enum-ctor.rs:37:20 + | +37 | let _: Z = Z::Fn; + | ^^^^^ expected enum `m::n::Z`, found fn item + | + = note: expected type `m::n::Z` + found type `fn(u8) -> m::n::Z {m::n::Z::Fn}` + +error[E0618]: expected function, found enum variant `Z::Unit` + --> $DIR/privacy-enum-ctor.rs:41:17 + | +26 | Unit, + | ---- `Z::Unit` defined here +... +41 | let _ = Z::Unit(); + | ^^^^^^^^^ not a function +help: `Z::Unit` is a unit variant, you need to write it without the parenthesis + | +41 | let _ = Z::Unit; + | ^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/privacy-enum-ctor.rs:53:16 + | +53 | let _: E = m::E::Fn; + | ^^^^^^^^ expected enum `m::E`, found fn item + | + = note: expected type `m::E` + found type `fn(u8) -> m::E {m::E::Fn}` + +error[E0618]: expected function, found enum variant `m::E::Unit` + --> $DIR/privacy-enum-ctor.rs:57:16 + | +17 | Unit, + | ---- `m::E::Unit` defined here +... +57 | let _: E = m::E::Unit(); + | ^^^^^^^^^^^^ not a function +help: `m::E::Unit` is a unit variant, you need to write it without the parenthesis + | +57 | let _: E = m::E::Unit; + | ^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/privacy-enum-ctor.rs:61:16 + | +61 | let _: E = E::Fn; + | ^^^^^ expected enum `m::E`, found fn item + | + = note: expected type `m::E` + found type `fn(u8) -> m::E {m::E::Fn}` + +error[E0618]: expected function, found enum variant `E::Unit` + --> $DIR/privacy-enum-ctor.rs:65:16 + | +17 | Unit, + | ---- `E::Unit` defined here +... +65 | let _: E = E::Unit(); + | ^^^^^^^^^ not a function +help: `E::Unit` is a unit variant, you need to write it without the parenthesis + | +65 | let _: E = E::Unit; + | ^^^^^^^ + +error: aborting due to 23 previous errors + diff --git a/src/test/ui/resolve/privacy-struct-ctor.rs b/src/test/ui/resolve/privacy-struct-ctor.rs index eb6edae7381..9029eeb22cd 100644 --- a/src/test/ui/resolve/privacy-struct-ctor.rs +++ b/src/test/ui/resolve/privacy-struct-ctor.rs @@ -14,6 +14,9 @@ extern crate privacy_struct_ctor as xcrate; mod m { pub struct S(u8); + pub struct S2 { + s: u8 + } pub mod n { pub(in m) struct Z(pub(in m::n) u8); @@ -22,22 +25,33 @@ mod m { use m::n::Z; // OK, only the type is imported fn f() { - n::Z; //~ ERROR tuple struct `Z` is private + n::Z; + //~^ ERROR tuple struct `Z` is private Z; //~^ ERROR expected value, found struct `Z` } } use m::S; // OK, only the type is imported +use m::S2; // OK, only the type is imported fn main() { - m::S; //~ ERROR tuple struct `S` is private + m::S; + //~^ ERROR tuple struct `S` is private + let _: S = m::S(2); + //~^ ERROR tuple struct `S` is private S; //~^ ERROR expected value, found struct `S` - m::n::Z; //~ ERROR tuple struct `Z` is private + m::n::Z; + //~^ ERROR tuple struct `Z` is private + + S2; + //~^ ERROR expected value, found struct `S2` - xcrate::m::S; //~ ERROR tuple struct `S` is private + xcrate::m::S; + //~^ ERROR tuple struct `S` is private xcrate::S; //~^ ERROR expected value, found struct `xcrate::S` - xcrate::m::n::Z; //~ ERROR tuple struct `Z` is private + xcrate::m::n::Z; + //~^ ERROR tuple struct `Z` is private } diff --git a/src/test/ui/resolve/privacy-struct-ctor.stderr b/src/test/ui/resolve/privacy-struct-ctor.stderr index 39bedf59641..e97a4e4143c 100644 --- a/src/test/ui/resolve/privacy-struct-ctor.stderr +++ b/src/test/ui/resolve/privacy-struct-ctor.stderr @@ -1,72 +1,77 @@ error[E0423]: expected value, found struct `Z` - --> $DIR/privacy-struct-ctor.rs:26:9 + --> $DIR/privacy-struct-ctor.rs:30:9 | -26 | Z; +30 | Z; | ^ | | | did you mean `S`? | constructor is not visible here due to private fields - | did you mean `Z { /* fields */ }`? help: possible better candidate is found in another module, you can import it into scope | -22 | use m::n::Z; +25 | use m::n::Z; | error[E0423]: expected value, found struct `S` - --> $DIR/privacy-struct-ctor.rs:35:5 + --> $DIR/privacy-struct-ctor.rs:43:5 | -35 | S; - | ^ - | | - | constructor is not visible here due to private fields - | did you mean `S { /* fields */ }`? +43 | S; + | ^ constructor is not visible here due to private fields help: possible better candidate is found in another module, you can import it into scope | -31 | use m::S; +35 | use m::S; | +error[E0423]: expected value, found struct `S2` + --> $DIR/privacy-struct-ctor.rs:48:5 + | +48 | S2; + | ^^ did you mean `S2 { /* fields */ }`? + error[E0423]: expected value, found struct `xcrate::S` - --> $DIR/privacy-struct-ctor.rs:40:5 + --> $DIR/privacy-struct-ctor.rs:53:5 | -40 | xcrate::S; - | ^^^^^^^^^ - | | - | constructor is not visible here due to private fields - | did you mean `xcrate::S { /* fields */ }`? +53 | xcrate::S; + | ^^^^^^^^^ constructor is not visible here due to private fields help: possible better candidate is found in another module, you can import it into scope | -31 | use m::S; +35 | use m::S; | error[E0603]: tuple struct `Z` is private - --> $DIR/privacy-struct-ctor.rs:25:9 + --> $DIR/privacy-struct-ctor.rs:28:9 | -25 | n::Z; //~ ERROR tuple struct `Z` is private +28 | n::Z; | ^^^^ error[E0603]: tuple struct `S` is private - --> $DIR/privacy-struct-ctor.rs:34:5 + --> $DIR/privacy-struct-ctor.rs:39:5 | -34 | m::S; //~ ERROR tuple struct `S` is private +39 | m::S; | ^^^^ +error[E0603]: tuple struct `S` is private + --> $DIR/privacy-struct-ctor.rs:41:16 + | +41 | let _: S = m::S(2); + | ^^^^ + error[E0603]: tuple struct `Z` is private - --> $DIR/privacy-struct-ctor.rs:37:5 + --> $DIR/privacy-struct-ctor.rs:45:5 | -37 | m::n::Z; //~ ERROR tuple struct `Z` is private +45 | m::n::Z; | ^^^^^^^ error[E0603]: tuple struct `S` is private - --> $DIR/privacy-struct-ctor.rs:39:5 + --> $DIR/privacy-struct-ctor.rs:51:5 | -39 | xcrate::m::S; //~ ERROR tuple struct `S` is private +51 | xcrate::m::S; | ^^^^^^^^^^^^ error[E0603]: tuple struct `Z` is private - --> $DIR/privacy-struct-ctor.rs:42:5 + --> $DIR/privacy-struct-ctor.rs:55:5 | -42 | xcrate::m::n::Z; //~ ERROR tuple struct `Z` is private +55 | xcrate::m::n::Z; | ^^^^^^^^^^^^^^^ -error: aborting due to 8 previous errors +error: aborting due to 10 previous errors diff --git a/src/test/ui/resolve/tuple-struct-alias.stderr b/src/test/ui/resolve/tuple-struct-alias.stderr index aea9fc356bf..843d7c20ffd 100644 --- a/src/test/ui/resolve/tuple-struct-alias.stderr +++ b/src/test/ui/resolve/tuple-struct-alias.stderr @@ -2,31 +2,33 @@ error[E0423]: expected function, found self type `Self` --> $DIR/tuple-struct-alias.rs:16:17 | 16 | let s = Self(0, 1); //~ ERROR expected function - | ^^^^ did you mean `Self { /* fields */ }`? + | ^^^^ not a function + | + = note: can't use `Self` as a constructor, you must use the implemented struct error[E0532]: expected tuple struct/variant, found self type `Self` --> $DIR/tuple-struct-alias.rs:18:13 | 18 | Self(..) => {} //~ ERROR expected tuple struct/variant - | ^^^^ did you mean `Self { /* fields */ }`? + | ^^^^ not a tuple struct/variant + | + = note: can't use `Self` as a constructor, you must use the implemented struct error[E0423]: expected function, found type alias `A` --> $DIR/tuple-struct-alias.rs:24:13 | 24 | let s = A(0, 1); //~ ERROR expected function - | ^ - | | - | did you mean `S`? - | did you mean `A { /* fields */ }`? + | ^ did you mean `S`? + | + = note: can't use a type alias as a constructor error[E0532]: expected tuple struct/variant, found type alias `A` --> $DIR/tuple-struct-alias.rs:26:9 | 26 | A(..) => {} //~ ERROR expected tuple struct/variant - | ^ - | | - | did you mean `S`? - | did you mean `A { /* fields */ }`? + | ^ did you mean `S`? + | + = note: can't use a type alias as a constructor error: aborting due to 4 previous errors diff --git a/src/test/ui/rfc-2005-default-binding-mode/suggestion.stderr b/src/test/ui/rfc-2005-default-binding-mode/suggestion.stderr index ebf9e498ffd..8aa17adbcb3 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/suggestion.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/suggestion.stderr @@ -1,4 +1,4 @@ -error: non-reference pattern used to match a reference (see issue #42640) +error[E0658]: non-reference pattern used to match a reference (see issue #42640) --> $DIR/suggestion.rs:12:12 | 12 | if let Some(y) = &Some(22) { //~ ERROR non-reference pattern diff --git a/src/test/ui/span/gated-features-attr-spans.stderr b/src/test/ui/span/gated-features-attr-spans.stderr index d067470942e..74a2c1d742b 100644 --- a/src/test/ui/span/gated-features-attr-spans.stderr +++ b/src/test/ui/span/gated-features-attr-spans.stderr @@ -1,4 +1,4 @@ -error: the struct `#[repr(align(u16))]` attribute is experimental (see issue #33626) +error[E0658]: the struct `#[repr(align(u16))]` attribute is experimental (see issue #33626) --> $DIR/gated-features-attr-spans.rs:13:1 | 13 | #[repr(align(16))] //~ ERROR is experimental @@ -6,7 +6,7 @@ error: the struct `#[repr(align(u16))]` attribute is experimental (see issue #33 | = help: add #![feature(repr_align)] to the crate attributes to enable -error: SIMD types are experimental and possibly buggy (see issue #27731) +error[E0658]: SIMD types are experimental and possibly buggy (see issue #27731) --> $DIR/gated-features-attr-spans.rs:20:1 | 20 | #[repr(simd)] //~ ERROR are experimental diff --git a/src/test/ui/span/impl-parsing.rs b/src/test/ui/span/impl-parsing.rs new file mode 100644 index 00000000000..064e3c3ac48 --- /dev/null +++ b/src/test/ui/span/impl-parsing.rs @@ -0,0 +1,21 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -Z parse-only -Z continue-parse-after-error + +impl ! {} // OK +impl ! where u8: Copy {} // OK + +impl Trait Type {} //~ ERROR missing `for` in a trait impl +impl Trait .. {} //~ ERROR missing `for` in a trait impl +impl ?Sized for Type {} //~ ERROR expected a trait, found type +impl ?Sized for .. {} //~ ERROR expected a trait, found type + +default unsafe FAIL //~ ERROR expected `impl`, found `FAIL` diff --git a/src/test/ui/span/impl-parsing.stderr b/src/test/ui/span/impl-parsing.stderr new file mode 100644 index 00000000000..912638446b9 --- /dev/null +++ b/src/test/ui/span/impl-parsing.stderr @@ -0,0 +1,32 @@ +error: missing `for` in a trait impl + --> $DIR/impl-parsing.rs:16:11 + | +16 | impl Trait Type {} //~ ERROR missing `for` in a trait impl + | ^ + +error: missing `for` in a trait impl + --> $DIR/impl-parsing.rs:17:11 + | +17 | impl Trait .. {} //~ ERROR missing `for` in a trait impl + | ^ + +error: expected a trait, found type + --> $DIR/impl-parsing.rs:18:6 + | +18 | impl ?Sized for Type {} //~ ERROR expected a trait, found type + | ^^^^^^ + +error: expected a trait, found type + --> $DIR/impl-parsing.rs:19:6 + | +19 | impl ?Sized for .. {} //~ ERROR expected a trait, found type + | ^^^^^^ + +error: expected `impl`, found `FAIL` + --> $DIR/impl-parsing.rs:21:16 + | +21 | default unsafe FAIL //~ ERROR expected `impl`, found `FAIL` + | ^^^^ expected `impl` here + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/span/issue-29595.stderr b/src/test/ui/span/issue-29595.stderr index 81ba0057d71..9046b90f0e9 100644 --- a/src/test/ui/span/issue-29595.stderr +++ b/src/test/ui/span/issue-29595.stderr @@ -4,7 +4,11 @@ error[E0277]: the trait bound `u8: Tr` is not satisfied 17 | let a: u8 = Tr::C; //~ ERROR the trait bound `u8: Tr` is not satisfied | ^^^^^ the trait `Tr` is not implemented for `u8` | - = note: required by `Tr::C` +note: required by `Tr::C` + --> $DIR/issue-29595.rs:13:5 + | +13 | const C: Self; + | ^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/span/issue-36530.stderr b/src/test/ui/span/issue-36530.stderr index 50908b2ca39..7f392104393 100644 --- a/src/test/ui/span/issue-36530.stderr +++ b/src/test/ui/span/issue-36530.stderr @@ -1,4 +1,4 @@ -error: The attribute `foo` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) +error[E0658]: The attribute `foo` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) --> $DIR/issue-36530.rs:11:1 | 11 | #[foo] //~ ERROR is currently unknown to the compiler @@ -6,7 +6,7 @@ error: The attribute `foo` is currently unknown to the compiler and may have mea | = help: add #![feature(custom_attribute)] to the crate attributes to enable -error: The attribute `foo` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) +error[E0658]: The attribute `foo` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) --> $DIR/issue-36530.rs:13:5 | 13 | #![foo] //~ ERROR is currently unknown to the compiler diff --git a/src/test/ui/specialization-feature-gate-default.stderr b/src/test/ui/specialization-feature-gate-default.stderr index e17d1308385..96e0fe13dc9 100644 --- a/src/test/ui/specialization-feature-gate-default.stderr +++ b/src/test/ui/specialization-feature-gate-default.stderr @@ -1,4 +1,4 @@ -error: specialization is unstable (see issue #31844) +error[E0658]: specialization is unstable (see issue #31844) --> $DIR/specialization-feature-gate-default.rs:20:5 | 20 | default fn foo(&self) {} //~ ERROR specialization is unstable diff --git a/src/test/ui/suggestions/dont-suggest-dereference-on-arg.stderr b/src/test/ui/suggestions/dont-suggest-dereference-on-arg.stderr index 799d9080b9d..5413dcddcd7 100644 --- a/src/test/ui/suggestions/dont-suggest-dereference-on-arg.stderr +++ b/src/test/ui/suggestions/dont-suggest-dereference-on-arg.stderr @@ -1,4 +1,4 @@ -error: non-reference pattern used to match a reference (see issue #42640) +error[E0658]: non-reference pattern used to match a reference (see issue #42640) --> $DIR/dont-suggest-dereference-on-arg.rs:16:18 | 16 | .filter(|&(ref a, _)| foo(a)) diff --git a/src/test/ui/suggestions/fn-closure-mutable-capture.rs b/src/test/ui/suggestions/fn-closure-mutable-capture.rs new file mode 100644 index 00000000000..385efebd590 --- /dev/null +++ b/src/test/ui/suggestions/fn-closure-mutable-capture.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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub fn bar<F: Fn()>(_f: F) {} + +pub fn foo() { + let mut x = 0; + bar(move || x = 1); + //~^ ERROR cannot assign to captured outer variable in an `Fn` closure + //~| NOTE `Fn` closures cannot capture their enclosing environment for modifications +} + +fn main() {} diff --git a/src/test/ui/suggestions/fn-closure-mutable-capture.stderr b/src/test/ui/suggestions/fn-closure-mutable-capture.stderr new file mode 100644 index 00000000000..6c79e447a3c --- /dev/null +++ b/src/test/ui/suggestions/fn-closure-mutable-capture.stderr @@ -0,0 +1,15 @@ +error[E0594]: cannot assign to captured outer variable in an `Fn` closure + --> $DIR/fn-closure-mutable-capture.rs:15:17 + | +15 | bar(move || x = 1); + | ^^^^^ + | + = note: `Fn` closures cannot capture their enclosing environment for modifications +help: consider changing this closure to take self by mutable reference + --> $DIR/fn-closure-mutable-capture.rs:15:9 + | +15 | bar(move || x = 1); + | ^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/suggestions/numeric-cast-2.rs b/src/test/ui/suggestions/numeric-cast-2.rs new file mode 100644 index 00000000000..2092b6bce37 --- /dev/null +++ b/src/test/ui/suggestions/numeric-cast-2.rs @@ -0,0 +1,21 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn foo() -> i32 { + 4 +} +fn main() { + let x: u16 = foo(); + //~^ ERROR mismatched types + let y: i64 = x + x; + //~^ ERROR mismatched types + let z: i32 = x + x; + //~^ ERROR mismatched types +} diff --git a/src/test/ui/suggestions/numeric-cast-2.stderr b/src/test/ui/suggestions/numeric-cast-2.stderr new file mode 100644 index 00000000000..90086d247d6 --- /dev/null +++ b/src/test/ui/suggestions/numeric-cast-2.stderr @@ -0,0 +1,20 @@ +error[E0308]: mismatched types + --> $DIR/numeric-cast-2.rs:15:18 + | +15 | let x: u16 = foo(); + | ^^^^^ expected u16, found i32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast-2.rs:17:18 + | +17 | let y: i64 = x + x; + | ^^^^^ expected i64, found u16 + +error[E0308]: mismatched types + --> $DIR/numeric-cast-2.rs:19:18 + | +19 | let z: i32 = x + x; + | ^^^^^ expected i32, found u16 + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/suggestions/numeric-cast.rs b/src/test/ui/suggestions/numeric-cast.rs new file mode 100644 index 00000000000..6e144037ec2 --- /dev/null +++ b/src/test/ui/suggestions/numeric-cast.rs @@ -0,0 +1,315 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + + +fn foo<N>(_x: N) {} + +fn main() { + let x_usize: usize = 1; + let x_u64: u64 = 2; + let x_u32: u32 = 3; + let x_u16: u16 = 4; + let x_u8: u8 = 5; + let x_isize: isize = 6; + let x_i64: i64 = 7; + let x_i32: i32 = 8; + let x_i16: i16 = 9; + let x_i8: i8 = 10; + let x_f64: f64 = 11.0; + let x_f32: f32 = 12.0; + + foo::<usize>(x_usize); + foo::<usize>(x_u64); + //~^ ERROR mismatched types + foo::<usize>(x_u32); + //~^ ERROR mismatched types + foo::<usize>(x_u16); + //~^ ERROR mismatched types + foo::<usize>(x_u8); + //~^ ERROR mismatched types + foo::<usize>(x_isize); + //~^ ERROR mismatched types + foo::<usize>(x_i64); + //~^ ERROR mismatched types + foo::<usize>(x_i32); + //~^ ERROR mismatched types + foo::<usize>(x_i16); + //~^ ERROR mismatched types + foo::<usize>(x_i8); + //~^ ERROR mismatched types + foo::<usize>(x_f64); + //~^ ERROR mismatched types + foo::<usize>(x_f32); + //~^ ERROR mismatched types + + foo::<isize>(x_usize); + //~^ ERROR mismatched types + foo::<isize>(x_u64); + //~^ ERROR mismatched types + foo::<isize>(x_u32); + //~^ ERROR mismatched types + foo::<isize>(x_u16); + //~^ ERROR mismatched types + foo::<isize>(x_u8); + //~^ ERROR mismatched types + foo::<isize>(x_isize); + foo::<isize>(x_i64); + //~^ ERROR mismatched types + foo::<isize>(x_i32); + //~^ ERROR mismatched types + foo::<isize>(x_i16); + //~^ ERROR mismatched types + foo::<isize>(x_i8); + //~^ ERROR mismatched types + foo::<isize>(x_f64); + //~^ ERROR mismatched types + foo::<isize>(x_f32); + //~^ ERROR mismatched types + + foo::<u64>(x_usize); + //~^ ERROR mismatched types + foo::<u64>(x_u64); + foo::<u64>(x_u32); + //~^ ERROR mismatched types + foo::<u64>(x_u16); + //~^ ERROR mismatched types + foo::<u64>(x_u8); + //~^ ERROR mismatched types + foo::<u64>(x_isize); + //~^ ERROR mismatched types + foo::<u64>(x_i64); + //~^ ERROR mismatched types + foo::<u64>(x_i32); + //~^ ERROR mismatched types + foo::<u64>(x_i16); + //~^ ERROR mismatched types + foo::<u64>(x_i8); + //~^ ERROR mismatched types + foo::<u64>(x_f64); + //~^ ERROR mismatched types + foo::<u64>(x_f32); + //~^ ERROR mismatched types + + foo::<i64>(x_usize); + //~^ ERROR mismatched types + foo::<i64>(x_u64); + //~^ ERROR mismatched types + foo::<i64>(x_u32); + //~^ ERROR mismatched types + foo::<i64>(x_u16); + //~^ ERROR mismatched types + foo::<i64>(x_u8); + //~^ ERROR mismatched types + foo::<i64>(x_isize); + //~^ ERROR mismatched types + foo::<i64>(x_i64); + foo::<i64>(x_i32); + //~^ ERROR mismatched types + foo::<i64>(x_i16); + //~^ ERROR mismatched types + foo::<i64>(x_i8); + //~^ ERROR mismatched types + foo::<i64>(x_f64); + //~^ ERROR mismatched types + foo::<i64>(x_f32); + //~^ ERROR mismatched types + + foo::<u32>(x_usize); + //~^ ERROR mismatched types + foo::<u32>(x_u64); + //~^ ERROR mismatched types + foo::<u32>(x_u32); + foo::<u32>(x_u16); + //~^ ERROR mismatched types + foo::<u32>(x_u8); + //~^ ERROR mismatched types + foo::<u32>(x_isize); + //~^ ERROR mismatched types + foo::<u32>(x_i64); + //~^ ERROR mismatched types + foo::<u32>(x_i32); + //~^ ERROR mismatched types + foo::<u32>(x_i16); + //~^ ERROR mismatched types + foo::<u32>(x_i8); + //~^ ERROR mismatched types + foo::<u32>(x_f64); + //~^ ERROR mismatched types + foo::<u32>(x_f32); + //~^ ERROR mismatched types + + foo::<i32>(x_usize); + //~^ ERROR mismatched types + foo::<i32>(x_u64); + //~^ ERROR mismatched types + foo::<i32>(x_u32); + //~^ ERROR mismatched types + foo::<i32>(x_u16); + //~^ ERROR mismatched types + foo::<i32>(x_u8); + //~^ ERROR mismatched types + foo::<i32>(x_isize); + //~^ ERROR mismatched types + foo::<i32>(x_i64); + //~^ ERROR mismatched types + foo::<i32>(x_i32); + foo::<i32>(x_i16); + //~^ ERROR mismatched types + foo::<i32>(x_i8); + //~^ ERROR mismatched types + foo::<i32>(x_f64); + //~^ ERROR mismatched types + foo::<i32>(x_f32); + //~^ ERROR mismatched types + + foo::<u16>(x_usize); + //~^ ERROR mismatched types + foo::<u16>(x_u64); + //~^ ERROR mismatched types + foo::<u16>(x_u32); + //~^ ERROR mismatched types + foo::<u16>(x_u16); + foo::<u16>(x_u8); + //~^ ERROR mismatched types + foo::<u16>(x_isize); + //~^ ERROR mismatched types + foo::<u16>(x_i64); + //~^ ERROR mismatched types + foo::<u16>(x_i32); + //~^ ERROR mismatched types + foo::<u16>(x_i16); + //~^ ERROR mismatched types + foo::<u16>(x_i8); + //~^ ERROR mismatched types + foo::<u16>(x_f64); + //~^ ERROR mismatched types + foo::<u16>(x_f32); + //~^ ERROR mismatched types + + foo::<i16>(x_usize); + //~^ ERROR mismatched types + foo::<i16>(x_u64); + //~^ ERROR mismatched types + foo::<i16>(x_u32); + //~^ ERROR mismatched types + foo::<i16>(x_u16); + //~^ ERROR mismatched types + foo::<i16>(x_u8); + //~^ ERROR mismatched types + foo::<i16>(x_isize); + //~^ ERROR mismatched types + foo::<i16>(x_i64); + //~^ ERROR mismatched types + foo::<i16>(x_i32); + //~^ ERROR mismatched types + foo::<i16>(x_i16); + foo::<i16>(x_i8); + //~^ ERROR mismatched types + foo::<i16>(x_f64); + //~^ ERROR mismatched types + foo::<i16>(x_f32); + //~^ ERROR mismatched types + + foo::<u8>(x_usize); + //~^ ERROR mismatched types + foo::<u8>(x_u64); + //~^ ERROR mismatched types + foo::<u8>(x_u32); + //~^ ERROR mismatched types + foo::<u8>(x_u16); + //~^ ERROR mismatched types + foo::<u8>(x_u8); + foo::<u8>(x_isize); + //~^ ERROR mismatched types + foo::<u8>(x_i64); + //~^ ERROR mismatched types + foo::<u8>(x_i32); + //~^ ERROR mismatched types + foo::<u8>(x_i16); + //~^ ERROR mismatched types + foo::<u8>(x_i8); + //~^ ERROR mismatched types + foo::<u8>(x_f64); + //~^ ERROR mismatched types + foo::<u8>(x_f32); + //~^ ERROR mismatched types + + foo::<i8>(x_usize); + //~^ ERROR mismatched types + foo::<i8>(x_u64); + //~^ ERROR mismatched types + foo::<i8>(x_u32); + //~^ ERROR mismatched types + foo::<i8>(x_u16); + //~^ ERROR mismatched types + foo::<i8>(x_u8); + //~^ ERROR mismatched types + foo::<i8>(x_isize); + //~^ ERROR mismatched types + foo::<i8>(x_i64); + //~^ ERROR mismatched types + foo::<i8>(x_i32); + //~^ ERROR mismatched types + foo::<i8>(x_i16); + //~^ ERROR mismatched types + foo::<i8>(x_i8); + foo::<i8>(x_f64); + //~^ ERROR mismatched types + foo::<i8>(x_f32); + //~^ ERROR mismatched types + + foo::<f64>(x_usize); + //~^ ERROR mismatched types + foo::<f64>(x_u64); + //~^ ERROR mismatched types + foo::<f64>(x_u32); + //~^ ERROR mismatched types + foo::<f64>(x_u16); + //~^ ERROR mismatched types + foo::<f64>(x_u8); + //~^ ERROR mismatched types + foo::<f64>(x_isize); + //~^ ERROR mismatched types + foo::<f64>(x_i64); + //~^ ERROR mismatched types + foo::<f64>(x_i32); + //~^ ERROR mismatched types + foo::<f64>(x_i16); + //~^ ERROR mismatched types + foo::<f64>(x_i8); + //~^ ERROR mismatched types + foo::<f64>(x_f64); + foo::<f64>(x_f32); + //~^ ERROR mismatched types + + foo::<f32>(x_usize); + //~^ ERROR mismatched types + foo::<f32>(x_u64); + //~^ ERROR mismatched types + foo::<f32>(x_u32); + //~^ ERROR mismatched types + foo::<f32>(x_u16); + //~^ ERROR mismatched types + foo::<f32>(x_u8); + //~^ ERROR mismatched types + foo::<f32>(x_isize); + //~^ ERROR mismatched types + foo::<f32>(x_i64); + //~^ ERROR mismatched types + foo::<f32>(x_i32); + //~^ ERROR mismatched types + foo::<f32>(x_i16); + //~^ ERROR mismatched types + foo::<f32>(x_i8); + //~^ ERROR mismatched types + foo::<f32>(x_f64); + //~^ ERROR mismatched types + foo::<f32>(x_f32); +} diff --git a/src/test/ui/suggestions/numeric-cast.stderr b/src/test/ui/suggestions/numeric-cast.stderr new file mode 100644 index 00000000000..0ce3d087f35 --- /dev/null +++ b/src/test/ui/suggestions/numeric-cast.stderr @@ -0,0 +1,886 @@ +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:29:18 + | +29 | foo::<usize>(x_u64); + | ^^^^^ expected usize, found u64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:31:18 + | +31 | foo::<usize>(x_u32); + | ^^^^^ expected usize, found u32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:33:18 + | +33 | foo::<usize>(x_u16); + | ^^^^^ expected usize, found u16 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:35:18 + | +35 | foo::<usize>(x_u8); + | ^^^^ expected usize, found u8 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:37:18 + | +37 | foo::<usize>(x_isize); + | ^^^^^^^ expected usize, found isize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:39:18 + | +39 | foo::<usize>(x_i64); + | ^^^^^ expected usize, found i64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:41:18 + | +41 | foo::<usize>(x_i32); + | ^^^^^ expected usize, found i32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:43:18 + | +43 | foo::<usize>(x_i16); + | ^^^^^ expected usize, found i16 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:45:18 + | +45 | foo::<usize>(x_i8); + | ^^^^ expected usize, found i8 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:47:18 + | +47 | foo::<usize>(x_f64); + | ^^^^^ expected usize, found f64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:49:18 + | +49 | foo::<usize>(x_f32); + | ^^^^^ expected usize, found f32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:52:18 + | +52 | foo::<isize>(x_usize); + | ^^^^^^^ expected isize, found usize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:54:18 + | +54 | foo::<isize>(x_u64); + | ^^^^^ expected isize, found u64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:56:18 + | +56 | foo::<isize>(x_u32); + | ^^^^^ expected isize, found u32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:58:18 + | +58 | foo::<isize>(x_u16); + | ^^^^^ expected isize, found u16 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:60:18 + | +60 | foo::<isize>(x_u8); + | ^^^^ expected isize, found u8 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:63:18 + | +63 | foo::<isize>(x_i64); + | ^^^^^ expected isize, found i64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:65:18 + | +65 | foo::<isize>(x_i32); + | ^^^^^ expected isize, found i32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:67:18 + | +67 | foo::<isize>(x_i16); + | ^^^^^ expected isize, found i16 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:69:18 + | +69 | foo::<isize>(x_i8); + | ^^^^ expected isize, found i8 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:71:18 + | +71 | foo::<isize>(x_f64); + | ^^^^^ expected isize, found f64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:73:18 + | +73 | foo::<isize>(x_f32); + | ^^^^^ expected isize, found f32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:76:16 + | +76 | foo::<u64>(x_usize); + | ^^^^^^^ expected u64, found usize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:79:16 + | +79 | foo::<u64>(x_u32); + | ^^^^^ expected u64, found u32 +help: you can cast an `u32` to `u64`, which will zero-extend the source value + | +79 | foo::<u64>(x_u32.into()); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:81:16 + | +81 | foo::<u64>(x_u16); + | ^^^^^ expected u64, found u16 +help: you can cast an `u16` to `u64`, which will zero-extend the source value + | +81 | foo::<u64>(x_u16.into()); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:83:16 + | +83 | foo::<u64>(x_u8); + | ^^^^ expected u64, found u8 +help: you can cast an `u8` to `u64`, which will zero-extend the source value + | +83 | foo::<u64>(x_u8.into()); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:85:16 + | +85 | foo::<u64>(x_isize); + | ^^^^^^^ expected u64, found isize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:87:16 + | +87 | foo::<u64>(x_i64); + | ^^^^^ expected u64, found i64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:89:16 + | +89 | foo::<u64>(x_i32); + | ^^^^^ expected u64, found i32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:91:16 + | +91 | foo::<u64>(x_i16); + | ^^^^^ expected u64, found i16 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:93:16 + | +93 | foo::<u64>(x_i8); + | ^^^^ expected u64, found i8 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:95:16 + | +95 | foo::<u64>(x_f64); + | ^^^^^ expected u64, found f64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:97:16 + | +97 | foo::<u64>(x_f32); + | ^^^^^ expected u64, found f32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:100:16 + | +100 | foo::<i64>(x_usize); + | ^^^^^^^ expected i64, found usize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:102:16 + | +102 | foo::<i64>(x_u64); + | ^^^^^ expected i64, found u64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:104:16 + | +104 | foo::<i64>(x_u32); + | ^^^^^ expected i64, found u32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:106:16 + | +106 | foo::<i64>(x_u16); + | ^^^^^ expected i64, found u16 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:108:16 + | +108 | foo::<i64>(x_u8); + | ^^^^ expected i64, found u8 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:110:16 + | +110 | foo::<i64>(x_isize); + | ^^^^^^^ expected i64, found isize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:113:16 + | +113 | foo::<i64>(x_i32); + | ^^^^^ expected i64, found i32 +help: you can cast an `i32` to `i64`, which will sign-extend the source value + | +113 | foo::<i64>(x_i32.into()); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:115:16 + | +115 | foo::<i64>(x_i16); + | ^^^^^ expected i64, found i16 +help: you can cast an `i16` to `i64`, which will sign-extend the source value + | +115 | foo::<i64>(x_i16.into()); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:117:16 + | +117 | foo::<i64>(x_i8); + | ^^^^ expected i64, found i8 +help: you can cast an `i8` to `i64`, which will sign-extend the source value + | +117 | foo::<i64>(x_i8.into()); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:119:16 + | +119 | foo::<i64>(x_f64); + | ^^^^^ expected i64, found f64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:121:16 + | +121 | foo::<i64>(x_f32); + | ^^^^^ expected i64, found f32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:124:16 + | +124 | foo::<u32>(x_usize); + | ^^^^^^^ expected u32, found usize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:126:16 + | +126 | foo::<u32>(x_u64); + | ^^^^^ expected u32, found u64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:129:16 + | +129 | foo::<u32>(x_u16); + | ^^^^^ expected u32, found u16 +help: you can cast an `u16` to `u32`, which will zero-extend the source value + | +129 | foo::<u32>(x_u16.into()); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:131:16 + | +131 | foo::<u32>(x_u8); + | ^^^^ expected u32, found u8 +help: you can cast an `u8` to `u32`, which will zero-extend the source value + | +131 | foo::<u32>(x_u8.into()); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:133:16 + | +133 | foo::<u32>(x_isize); + | ^^^^^^^ expected u32, found isize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:135:16 + | +135 | foo::<u32>(x_i64); + | ^^^^^ expected u32, found i64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:137:16 + | +137 | foo::<u32>(x_i32); + | ^^^^^ expected u32, found i32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:139:16 + | +139 | foo::<u32>(x_i16); + | ^^^^^ expected u32, found i16 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:141:16 + | +141 | foo::<u32>(x_i8); + | ^^^^ expected u32, found i8 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:143:16 + | +143 | foo::<u32>(x_f64); + | ^^^^^ expected u32, found f64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:145:16 + | +145 | foo::<u32>(x_f32); + | ^^^^^ expected u32, found f32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:148:16 + | +148 | foo::<i32>(x_usize); + | ^^^^^^^ expected i32, found usize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:150:16 + | +150 | foo::<i32>(x_u64); + | ^^^^^ expected i32, found u64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:152:16 + | +152 | foo::<i32>(x_u32); + | ^^^^^ expected i32, found u32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:154:16 + | +154 | foo::<i32>(x_u16); + | ^^^^^ expected i32, found u16 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:156:16 + | +156 | foo::<i32>(x_u8); + | ^^^^ expected i32, found u8 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:158:16 + | +158 | foo::<i32>(x_isize); + | ^^^^^^^ expected i32, found isize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:160:16 + | +160 | foo::<i32>(x_i64); + | ^^^^^ expected i32, found i64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:163:16 + | +163 | foo::<i32>(x_i16); + | ^^^^^ expected i32, found i16 +help: you can cast an `i16` to `i32`, which will sign-extend the source value + | +163 | foo::<i32>(x_i16.into()); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:165:16 + | +165 | foo::<i32>(x_i8); + | ^^^^ expected i32, found i8 +help: you can cast an `i8` to `i32`, which will sign-extend the source value + | +165 | foo::<i32>(x_i8.into()); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:167:16 + | +167 | foo::<i32>(x_f64); + | ^^^^^ expected i32, found f64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:169:16 + | +169 | foo::<i32>(x_f32); + | ^^^^^ expected i32, found f32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:172:16 + | +172 | foo::<u16>(x_usize); + | ^^^^^^^ expected u16, found usize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:174:16 + | +174 | foo::<u16>(x_u64); + | ^^^^^ expected u16, found u64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:176:16 + | +176 | foo::<u16>(x_u32); + | ^^^^^ expected u16, found u32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:179:16 + | +179 | foo::<u16>(x_u8); + | ^^^^ expected u16, found u8 +help: you can cast an `u8` to `u16`, which will zero-extend the source value + | +179 | foo::<u16>(x_u8.into()); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:181:16 + | +181 | foo::<u16>(x_isize); + | ^^^^^^^ expected u16, found isize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:183:16 + | +183 | foo::<u16>(x_i64); + | ^^^^^ expected u16, found i64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:185:16 + | +185 | foo::<u16>(x_i32); + | ^^^^^ expected u16, found i32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:187:16 + | +187 | foo::<u16>(x_i16); + | ^^^^^ expected u16, found i16 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:189:16 + | +189 | foo::<u16>(x_i8); + | ^^^^ expected u16, found i8 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:191:16 + | +191 | foo::<u16>(x_f64); + | ^^^^^ expected u16, found f64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:193:16 + | +193 | foo::<u16>(x_f32); + | ^^^^^ expected u16, found f32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:196:16 + | +196 | foo::<i16>(x_usize); + | ^^^^^^^ expected i16, found usize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:198:16 + | +198 | foo::<i16>(x_u64); + | ^^^^^ expected i16, found u64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:200:16 + | +200 | foo::<i16>(x_u32); + | ^^^^^ expected i16, found u32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:202:16 + | +202 | foo::<i16>(x_u16); + | ^^^^^ expected i16, found u16 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:204:16 + | +204 | foo::<i16>(x_u8); + | ^^^^ expected i16, found u8 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:206:16 + | +206 | foo::<i16>(x_isize); + | ^^^^^^^ expected i16, found isize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:208:16 + | +208 | foo::<i16>(x_i64); + | ^^^^^ expected i16, found i64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:210:16 + | +210 | foo::<i16>(x_i32); + | ^^^^^ expected i16, found i32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:213:16 + | +213 | foo::<i16>(x_i8); + | ^^^^ expected i16, found i8 +help: you can cast an `i8` to `i16`, which will sign-extend the source value + | +213 | foo::<i16>(x_i8.into()); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:215:16 + | +215 | foo::<i16>(x_f64); + | ^^^^^ expected i16, found f64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:217:16 + | +217 | foo::<i16>(x_f32); + | ^^^^^ expected i16, found f32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:220:15 + | +220 | foo::<u8>(x_usize); + | ^^^^^^^ expected u8, found usize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:222:15 + | +222 | foo::<u8>(x_u64); + | ^^^^^ expected u8, found u64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:224:15 + | +224 | foo::<u8>(x_u32); + | ^^^^^ expected u8, found u32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:226:15 + | +226 | foo::<u8>(x_u16); + | ^^^^^ expected u8, found u16 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:229:15 + | +229 | foo::<u8>(x_isize); + | ^^^^^^^ expected u8, found isize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:231:15 + | +231 | foo::<u8>(x_i64); + | ^^^^^ expected u8, found i64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:233:15 + | +233 | foo::<u8>(x_i32); + | ^^^^^ expected u8, found i32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:235:15 + | +235 | foo::<u8>(x_i16); + | ^^^^^ expected u8, found i16 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:237:15 + | +237 | foo::<u8>(x_i8); + | ^^^^ expected u8, found i8 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:239:15 + | +239 | foo::<u8>(x_f64); + | ^^^^^ expected u8, found f64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:241:15 + | +241 | foo::<u8>(x_f32); + | ^^^^^ expected u8, found f32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:244:15 + | +244 | foo::<i8>(x_usize); + | ^^^^^^^ expected i8, found usize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:246:15 + | +246 | foo::<i8>(x_u64); + | ^^^^^ expected i8, found u64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:248:15 + | +248 | foo::<i8>(x_u32); + | ^^^^^ expected i8, found u32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:250:15 + | +250 | foo::<i8>(x_u16); + | ^^^^^ expected i8, found u16 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:252:15 + | +252 | foo::<i8>(x_u8); + | ^^^^ expected i8, found u8 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:254:15 + | +254 | foo::<i8>(x_isize); + | ^^^^^^^ expected i8, found isize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:256:15 + | +256 | foo::<i8>(x_i64); + | ^^^^^ expected i8, found i64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:258:15 + | +258 | foo::<i8>(x_i32); + | ^^^^^ expected i8, found i32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:260:15 + | +260 | foo::<i8>(x_i16); + | ^^^^^ expected i8, found i16 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:263:15 + | +263 | foo::<i8>(x_f64); + | ^^^^^ expected i8, found f64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:265:15 + | +265 | foo::<i8>(x_f32); + | ^^^^^ expected i8, found f32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:268:16 + | +268 | foo::<f64>(x_usize); + | ^^^^^^^ expected f64, found usize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:270:16 + | +270 | foo::<f64>(x_u64); + | ^^^^^ expected f64, found u64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:272:16 + | +272 | foo::<f64>(x_u32); + | ^^^^^ expected f64, found u32 +help: you can cast an `u32` to `f64`, producing the floating point representation of the integer + | +272 | foo::<f64>(x_u32.into()); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:274:16 + | +274 | foo::<f64>(x_u16); + | ^^^^^ expected f64, found u16 +help: you can cast an `u16` to `f64`, producing the floating point representation of the integer + | +274 | foo::<f64>(x_u16.into()); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:276:16 + | +276 | foo::<f64>(x_u8); + | ^^^^ expected f64, found u8 +help: you can cast an `u8` to `f64`, producing the floating point representation of the integer + | +276 | foo::<f64>(x_u8.into()); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:278:16 + | +278 | foo::<f64>(x_isize); + | ^^^^^^^ expected f64, found isize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:280:16 + | +280 | foo::<f64>(x_i64); + | ^^^^^ expected f64, found i64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:282:16 + | +282 | foo::<f64>(x_i32); + | ^^^^^ expected f64, found i32 +help: you can cast an `i32` to `f64`, producing the floating point representation of the integer + | +282 | foo::<f64>(x_i32.into()); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:284:16 + | +284 | foo::<f64>(x_i16); + | ^^^^^ expected f64, found i16 +help: you can cast an `i16` to `f64`, producing the floating point representation of the integer + | +284 | foo::<f64>(x_i16.into()); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:286:16 + | +286 | foo::<f64>(x_i8); + | ^^^^ expected f64, found i8 +help: you can cast an `i8` to `f64`, producing the floating point representation of the integer + | +286 | foo::<f64>(x_i8.into()); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:289:16 + | +289 | foo::<f64>(x_f32); + | ^^^^^ expected f64, found f32 +help: you can cast an `f32` to `f64` in a lossless way + | +289 | foo::<f64>(x_f32.into()); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:292:16 + | +292 | foo::<f32>(x_usize); + | ^^^^^^^ expected f32, found usize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:294:16 + | +294 | foo::<f32>(x_u64); + | ^^^^^ expected f32, found u64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:296:16 + | +296 | foo::<f32>(x_u32); + | ^^^^^ expected f32, found u32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:298:16 + | +298 | foo::<f32>(x_u16); + | ^^^^^ expected f32, found u16 +help: you can cast an `u16` to `f32`, producing the floating point representation of the integer + | +298 | foo::<f32>(x_u16.into()); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:300:16 + | +300 | foo::<f32>(x_u8); + | ^^^^ expected f32, found u8 +help: you can cast an `u8` to `f32`, producing the floating point representation of the integer + | +300 | foo::<f32>(x_u8.into()); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:302:16 + | +302 | foo::<f32>(x_isize); + | ^^^^^^^ expected f32, found isize + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:304:16 + | +304 | foo::<f32>(x_i64); + | ^^^^^ expected f32, found i64 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:306:16 + | +306 | foo::<f32>(x_i32); + | ^^^^^ expected f32, found i32 + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:308:16 + | +308 | foo::<f32>(x_i16); + | ^^^^^ expected f32, found i16 +help: you can cast an `i16` to `f32`, producing the floating point representation of the integer + | +308 | foo::<f32>(x_i16.into()); + | ^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:310:16 + | +310 | foo::<f32>(x_i8); + | ^^^^ expected f32, found i8 +help: you can cast an `i8` to `f32`, producing the floating point representation of the integer + | +310 | foo::<f32>(x_i8.into()); + | ^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast.rs:312:16 + | +312 | foo::<f32>(x_f64); + | ^^^^^ expected f32, found f64 + +error: aborting due to 132 previous errors + diff --git a/src/test/ui/suggestions/try-operator-on-main.stderr b/src/test/ui/suggestions/try-operator-on-main.stderr index beb627bda6b..3b32b4a9eb7 100644 --- a/src/test/ui/suggestions/try-operator-on-main.stderr +++ b/src/test/ui/suggestions/try-operator-on-main.stderr @@ -28,7 +28,11 @@ error[E0277]: the trait bound `(): std::ops::Try` is not satisfied 25 | try_trait_generic::<()>(); //~ ERROR the trait bound | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::ops::Try` is not implemented for `()` | - = note: required by `try_trait_generic` +note: required by `try_trait_generic` + --> $DIR/try-operator-on-main.rs:30:1 + | +30 | fn try_trait_generic<T: Try>() -> T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try` --> $DIR/try-operator-on-main.rs:32:5 diff --git a/src/test/ui/type-annotation-needed.rs b/src/test/ui/type-annotation-needed.rs new file mode 100644 index 00000000000..3ed6e5daf00 --- /dev/null +++ b/src/test/ui/type-annotation-needed.rs @@ -0,0 +1,17 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn foo<T: Into<String>>(x: i32) {} +//~^ NOTE required by + +fn main() { + foo(42); + //~^ ERROR type annotations required +} diff --git a/src/test/ui/type-annotation-needed.stderr b/src/test/ui/type-annotation-needed.stderr new file mode 100644 index 00000000000..7d49afbaff8 --- /dev/null +++ b/src/test/ui/type-annotation-needed.stderr @@ -0,0 +1,14 @@ +error[E0283]: type annotations required: cannot resolve `_: std::convert::Into<std::string::String>` + --> $DIR/type-annotation-needed.rs:15:5 + | +15 | foo(42); + | ^^^ + | +note: required by `foo` + --> $DIR/type-annotation-needed.rs:11:1 + | +11 | fn foo<T: Into<String>>(x: i32) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/type-check/issue-40294.stderr b/src/test/ui/type-check/issue-40294.stderr index 2ca97aa3ef0..cf270afdeb1 100644 --- a/src/test/ui/type-check/issue-40294.stderr +++ b/src/test/ui/type-check/issue-40294.stderr @@ -10,7 +10,11 @@ error[E0283]: type annotations required: cannot resolve `&'a T: Foo` 21 | | } | |_^ | - = note: required by `Foo` +note: required by `Foo` + --> $DIR/issue-40294.rs:11:1 + | +11 | trait Foo: Sized { + | ^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/typeck-default-trait-impl-outside-crate.stderr b/src/test/ui/typeck-default-trait-impl-outside-crate.stderr deleted file mode 100644 index 6b50fde01d8..00000000000 --- a/src/test/ui/typeck-default-trait-impl-outside-crate.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error[E0318]: cannot create default implementations for traits outside the crate they're defined in; define a new trait instead - --> $DIR/typeck-default-trait-impl-outside-crate.rs:14:6 - | -14 | impl Copy for .. {} //~ ERROR E0318 - | ^^^^ `Copy` trait not defined in this crate - -error: aborting due to previous error - diff --git a/src/tools/cargo b/src/tools/cargo -Subproject a88fbace48ac42ab21e1d8609012480d0aeab98 +Subproject 6a8eb71f6d226f9ac869dbacd5ff6aa76deef1c diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 1f736e33c8b..ff662736bdd 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -41,9 +41,13 @@ impl EarlyProps { iter_header(testfile, None, &mut |ln| { + // we should check if any only-<platform> exists and if it exists + // and does not matches the current platform, skip the test props.ignore = props.ignore || config.parse_cfg_name_directive(ln, "ignore") || + (config.has_cfg_prefix(ln, "only") && + !config.parse_cfg_name_directive(ln, "only")) || ignore_gdb(config, ln) || ignore_lldb(config, ln) || ignore_llvm(config, ln); @@ -564,6 +568,13 @@ impl Config { } } + fn has_cfg_prefix(&self, line: &str, prefix: &str) -> bool { + // returns whether this line contains this prefix or not. For prefix + // "ignore", returns true if line says "ignore-x86_64", "ignore-arch", + // "ignore-andorid" etc. + line.starts_with(prefix) && line.as_bytes().get(prefix.len()) == Some(&b'-') + } + fn parse_name_directive(&self, line: &str, directive: &str) -> bool { // Ensure the directive is a whole word. Do not match "ignore-x86" when // the line says "ignore-x86_64". diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs index 6458ec02669..f6eaa09f55d 100644 --- a/src/tools/linkchecker/main.rs +++ b/src/tools/linkchecker/main.rs @@ -192,7 +192,17 @@ fn check(cache: &mut Cache, for part in Path::new(base).join(url).components() { match part { Component::Prefix(_) | - Component::RootDir => panic!(), + Component::RootDir => { + // Avoid absolute paths as they make the docs not + // relocatable by making assumptions on where the docs + // are hosted relative to the site root. + *errors = true; + println!("{}:{}: absolute path - {}", + pretty_file.display(), + i + 1, + Path::new(base).join(url).display()); + return; + } Component::CurDir => {} Component::ParentDir => { path.pop(); } Component::Normal(s) => { path.push(s); } diff --git a/src/tools/rust-installer b/src/tools/rust-installer -Subproject 745a020e924c0532b01e8f017ed72820913642e +Subproject b55e0fc77590cf5d23a01dedeb2104d8cbb48ef diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js new file mode 100644 index 00000000000..7c9ee2a4943 --- /dev/null +++ b/src/tools/rustdoc-js/tester.js @@ -0,0 +1,210 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +const fs = require('fs'); + +const TEST_FOLDER = 'src/test/rustdoc-js/'; + +// Stupid function extractor based on indent. +function extractFunction(content, functionName) { + var x = content.split('\n'); + var in_func = false; + var indent = 0; + var lines = []; + + for (var i = 0; i < x.length; ++i) { + if (in_func === false) { + var splitter = "function " + functionName + "("; + if (x[i].trim().startsWith(splitter)) { + in_func = true; + indent = x[i].split(splitter)[0].length; + lines.push(x[i]); + } + } else { + lines.push(x[i]); + if (x[i].trim() === "}" && x[i].split("}")[0].length === indent) { + return lines.join("\n"); + } + } + } + return null; +} + +// Stupid function extractor for array. +function extractArrayVariable(content, arrayName) { + var x = content.split('\n'); + var found_var = false; + var lines = []; + + for (var i = 0; i < x.length; ++i) { + if (found_var === false) { + var splitter = "var " + arrayName + " = ["; + if (x[i].trim().startsWith(splitter)) { + found_var = true; + i -= 1; + } + } else { + lines.push(x[i]); + if (x[i].endsWith('];')) { + return lines.join("\n"); + } + } + } + return null; +} + +// Stupid function extractor for variable. +function extractVariable(content, varName) { + var x = content.split('\n'); + var found_var = false; + var lines = []; + + for (var i = 0; i < x.length; ++i) { + if (found_var === false) { + var splitter = "var " + varName + " = "; + if (x[i].trim().startsWith(splitter)) { + found_var = true; + i -= 1; + } + } else { + lines.push(x[i]); + if (x[i].endsWith(';')) { + return lines.join("\n"); + } + } + } + return null; +} + +function loadContent(content) { + var Module = module.constructor; + var m = new Module(); + m._compile(content, "tmp.js"); + return m.exports; +} + +function readFile(filePath) { + return fs.readFileSync(filePath, 'utf8'); +} + +function loadThings(thingsToLoad, kindOfLoad, funcToCall, fileContent) { + var content = ''; + for (var i = 0; i < thingsToLoad.length; ++i) { + var tmp = funcToCall(fileContent, thingsToLoad[i]); + if (tmp === null) { + console.error('enable to find ' + kindOfLoad + ' "' + thingsToLoad[i] + '"'); + process.exit(1); + } + content += tmp; + content += 'exports.' + thingsToLoad[i] + ' = ' + thingsToLoad[i] + ';'; + } + return content; +} + +function lookForEntry(entry, data) { + for (var i = 0; i < data.length; ++i) { + var allGood = true; + for (var key in entry) { + if (!entry.hasOwnProperty(key)) { + continue; + } + var value = data[i][key]; + // To make our life easier, if there is a "parent" type, we add it to the path. + if (key === 'path' && data[i]['parent'] !== undefined) { + if (value.length > 0) { + value += '::' + data[i]['parent']['name']; + } else { + value = data[i]['parent']['name']; + } + } + if (value !== entry[key]) { + allGood = false; + break; + } + } + if (allGood === true) { + return true; + } + } + return false; +} + +function main(argv) { + if (argv.length !== 3) { + console.error("Expected toolchain to check as argument (for example 'x86_64-apple-darwin'"); + return 1; + } + var toolchain = argv[2]; + + var mainJs = readFile("build/" + toolchain + "/doc/main.js"); + var searchIndex = readFile("build/" + toolchain + "/doc/search-index.js").split("\n"); + if (searchIndex[searchIndex.length - 1].length === 0) { + searchIndex.pop(); + } + searchIndex.pop(); + searchIndex = loadContent(searchIndex.join("\n") + '\nexports.searchIndex = searchIndex;'); + finalJS = ""; + + var arraysToLoad = ["itemTypes"]; + var variablesToLoad = ["MAX_LEV_DISTANCE", "MAX_RESULTS", "TY_PRIMITIVE", "levenshtein_row2"]; + // execQuery first parameter is built in getQuery (which takes in the search input). + // execQuery last parameter is built in buildIndex. + // buildIndex requires the hashmap from search-index. + var functionsToLoad = ["levenshtein", "validateResult", "getQuery", "buildIndex", "execQuery"]; + + finalJS += 'window = { "currentCrate": "std" };\n'; + finalJS += loadThings(arraysToLoad, 'array', extractArrayVariable, mainJs); + finalJS += loadThings(variablesToLoad, 'variable', extractVariable, mainJs); + finalJS += loadThings(functionsToLoad, 'function', extractFunction, mainJs); + + var loaded = loadContent(finalJS); + var index = loaded.buildIndex(searchIndex.searchIndex); + + var errors = 0; + + fs.readdirSync(TEST_FOLDER).forEach(function(file) { + var loadedFile = loadContent(readFile(TEST_FOLDER + file) + + 'exports.QUERY = QUERY;exports.EXPECTED = EXPECTED;'); + const expected = loadedFile.EXPECTED; + const query = loadedFile.QUERY; + var results = loaded.execQuery(loaded.getQuery(query), index); + process.stdout.write('Checking "' + file + '" ... '); + var error_text = []; + for (var key in expected) { + if (!expected.hasOwnProperty(key)) { + continue; + } + if (!results.hasOwnProperty(key)) { + error_text.push('==> Unknown key "' + key + '"'); + break; + } + var entry = expected[key]; + var found = false; + for (var i = 0; i < entry.length; ++i) { + if (lookForEntry(entry[i], results[key]) === true) { + found = true; + } else { + error_text.push("==> Result not found in '" + key + "': '" + + JSON.stringify(entry[i]) + "'"); + } + } + } + if (error_text.length !== 0) { + errors += 1; + console.error("FAILED"); + console.error(error_text.join("\n")); + } else { + console.log("OK"); + } + }); + return errors; +} + +process.exit(main(process.argv)); diff --git a/src/tools/rustfmt b/src/tools/rustfmt -Subproject 6714a447d063b079de8fb2884ded2c8c3e96bc1 +Subproject e0e3e22248cd14ebbe0253e9720261a0328bfc5 diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index 61d71986b03..eee2902bfb6 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -69,6 +69,7 @@ fn filter_dirs(path: &Path) -> bool { "src/tools/miri", "src/librustc/mir/interpret", "src/librustc_mir/interpret", + "src/target", ]; skip.iter().any(|p| path.ends_with(p)) } diff --git a/src/tools/tidy/src/unstable_book.rs b/src/tools/tidy/src/unstable_book.rs index a4a35a706fd..6ffe78eab41 100644 --- a/src/tools/tidy/src/unstable_book.rs +++ b/src/tools/tidy/src/unstable_book.rs @@ -49,7 +49,7 @@ pub fn collect_unstable_feature_names(features: &Features) -> BTreeSet<String> { features .iter() .filter(|&(_, ref f)| f.level == Status::Unstable) - .map(|(name, _)| name.to_owned()) + .map(|(name, _)| name.replace('_', "-")) .collect() } @@ -60,7 +60,7 @@ pub fn collect_unstable_book_section_file_names(dir: &path::Path) -> BTreeSet<St .map(|entry| entry.expect("could not read directory entry")) .filter(dir_entry_is_file) .map(|entry| entry.file_name().into_string().unwrap()) - .map(|n| n.trim_right_matches(".md").replace('-', "_")) + .map(|n| n.trim_right_matches(".md").to_owned()) .collect() } diff --git a/src/tools/unstable-book-gen/src/main.rs b/src/tools/unstable-book-gen/src/main.rs index f66a18547c3..f66144fde01 100644 --- a/src/tools/unstable-book-gen/src/main.rs +++ b/src/tools/unstable-book-gen/src/main.rs @@ -53,9 +53,9 @@ fn set_to_summary_str(set: &BTreeSet<String>, dir: &str set .iter() .map(|ref n| format!(" - [{}]({}/{}.md)", - n, + n.replace('-', "_"), dir, - n.replace('_', "-"))) + n)) .fold("".to_owned(), |s, a| s + &a + "\n") } @@ -96,14 +96,17 @@ fn generate_unstable_book_files(src :&Path, out: &Path, features :&Features) { let unstable_section_file_names = collect_unstable_book_section_file_names(src); t!(fs::create_dir_all(&out)); for feature_name in &unstable_features - &unstable_section_file_names { - let file_name = format!("{}.md", feature_name.replace('_', "-")); + let feature_name_underscore = feature_name.replace('-', "_"); + let file_name = format!("{}.md", feature_name); let out_file_path = out.join(&file_name); - let feature = &features[&feature_name]; + let feature = &features[&feature_name_underscore]; if has_valid_tracking_issue(&feature) { - generate_stub_issue(&out_file_path, &feature_name, feature.tracking_issue.unwrap()); + generate_stub_issue(&out_file_path, + &feature_name_underscore, + feature.tracking_issue.unwrap()); } else { - generate_stub_no_issue(&out_file_path, &feature_name); + generate_stub_no_issue(&out_file_path, &feature_name_underscore); } } } |
