Auto merge of #58929 - estebank:elide-object, r=zackmdavis
Elide object safety errors on non-existent trait function
Fix #58734.
r? @zackmdavis
diff --git a/.mailmap b/.mailmap
index 07330862..120d1f1 100644
--- a/.mailmap
+++ b/.mailmap
@@ -29,6 +29,7 @@
Ariel Ben-Yehuda <arielb1@mail.tau.ac.il> arielb1 <arielb1@mail.tau.ac.il>
Austin Seipp <mad.one@gmail.com> <as@hacks.yi.org>
Aydin Kim <ladinjin@hanmail.net> aydin.kim <aydin.kim@samsung.com>
+Bastian Kauschke <bastian_kauschke@hotmail.de>
Barosl Lee <vcs@barosl.com> Barosl LEE <github@barosl.com>
Ben Alpert <ben@benalpert.com> <spicyjalapeno@gmail.com>
Ben Sago <ogham@users.noreply.github.com> Ben S <ogham@bsago.me>
diff --git a/.travis.yml b/.travis.yml
index 7985b6c..7a8772d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -12,20 +12,27 @@
depth: 2
submodules: false
+env:
+ global:
+ - CI_JOB_NAME=$TRAVIS_JOB_NAME
+
matrix:
fast_finish: true
include:
# Images used in testing PR and try-build should be run first.
- env: IMAGE=x86_64-gnu-llvm-6.0 RUST_BACKTRACE=1
+ name: x86_64-gnu-llvm-6.0
if: type = pull_request OR branch = auto
- env: IMAGE=dist-x86_64-linux DEPLOY=1
+ name: dist-x86_64-linux
if: branch = try OR branch = auto
# "alternate" deployments, these are "nightlies" but have LLVM assertions
# turned on, they're deployed to a different location primarily for
# additional testing.
- - env: IMAGE=dist-x86_64-linux DEPLOY_ALT=1 CI_JOB_NAME=dist-x86_64-linux-alt
+ - env: IMAGE=dist-x86_64-linux DEPLOY_ALT=1
+ name: dist-x86_64-linux-alt
if: branch = try OR branch = auto
- env: >
@@ -37,9 +44,9 @@
MACOSX_DEPLOYMENT_TARGET=10.7
NO_LLVM_ASSERTIONS=1
NO_DEBUG_ASSERTIONS=1
- CI_JOB_NAME=dist-x86_64-apple-alt
os: osx
osx_image: xcode9.3-moar
+ name: dist-x86_64-apple-alt
if: branch = auto
# macOS builders. These are placed near the beginning because they are very
@@ -60,9 +67,9 @@
MACOSX_STD_DEPLOYMENT_TARGET=10.7
NO_LLVM_ASSERTIONS=1
NO_DEBUG_ASSERTIONS=1
- CI_JOB_NAME=x86_64-apple
os: osx
osx_image: xcode9.3-moar
+ name: x86_64-apple
if: branch = auto
- env: >
@@ -74,9 +81,9 @@
MACOSX_STD_DEPLOYMENT_TARGET=10.7
NO_LLVM_ASSERTIONS=1
NO_DEBUG_ASSERTIONS=1
- CI_JOB_NAME=i686-apple
os: osx
osx_image: xcode9.3-moar
+ name: i686-apple
if: branch = auto
# OSX builders producing releases. These do not run the full test suite and
@@ -95,9 +102,9 @@
NO_LLVM_ASSERTIONS=1
NO_DEBUG_ASSERTIONS=1
DIST_REQUIRE_ALL_TOOLS=1
- CI_JOB_NAME=dist-i686-apple
os: osx
osx_image: xcode9.3-moar
+ name: dist-i686-apple
if: branch = auto
- env: >
@@ -110,81 +117,116 @@
NO_LLVM_ASSERTIONS=1
NO_DEBUG_ASSERTIONS=1
DIST_REQUIRE_ALL_TOOLS=1
- CI_JOB_NAME=dist-x86_64-apple
os: osx
osx_image: xcode9.3-moar
+ name: dist-x86_64-apple
if: branch = auto
# Linux builders, remaining docker images
- env: IMAGE=arm-android
+ name: arm-android
if: branch = auto
- env: IMAGE=armhf-gnu
+ name: armhf-gnu
if: branch = auto
- env: IMAGE=dist-various-1 DEPLOY=1
+ name: dist-various-1
if: branch = auto
- env: IMAGE=dist-various-2 DEPLOY=1
+ name: dist-various-2
if: branch = auto
- env: IMAGE=dist-aarch64-linux DEPLOY=1
+ name: dist-aarch64-linux
if: branch = auto
- env: IMAGE=dist-android DEPLOY=1
+ name: dist-android
if: branch = auto
- env: IMAGE=dist-arm-linux DEPLOY=1
+ name: dist-arm-linux
if: branch = auto
- env: IMAGE=dist-armhf-linux DEPLOY=1
+ name: dist-armhf-linux
if: branch = auto
- env: IMAGE=dist-armv7-linux DEPLOY=1
+ name: dist-armv7-linux
if: branch = auto
- env: IMAGE=dist-i586-gnu-i586-i686-musl DEPLOY=1
+ name: dist-i586-gnu-i586-i686-musl
if: branch = auto
- env: IMAGE=dist-i686-freebsd DEPLOY=1
+ name: dist-i686-freebsd
if: branch = auto
- env: IMAGE=dist-i686-linux DEPLOY=1
+ name: dist-i686-linux
if: branch = auto
- env: IMAGE=dist-mips-linux DEPLOY=1
+ name: dist-mips-linux
if: branch = auto
- env: IMAGE=dist-mips64-linux DEPLOY=1
+ name: dist-mips64-linux
if: branch = auto
- env: IMAGE=dist-mips64el-linux DEPLOY=1
+ name: dist-mips64el-linux
if: branch = auto
- env: IMAGE=dist-mipsel-linux DEPLOY=1
+ name: dist-mipsel-linux
if: branch = auto
- env: IMAGE=dist-powerpc-linux DEPLOY=1
+ name: dist-powerpc-linux
if: branch = auto
- env: IMAGE=dist-powerpc64-linux DEPLOY=1
+ name: dist-powerpc64-linux
if: branch = auto
- env: IMAGE=dist-powerpc64le-linux DEPLOY=1
+ name: dist-powerpc64le-linux
if: branch = auto
- env: IMAGE=dist-s390x-linux DEPLOY=1
+ name: dist-s390x-linux
if: branch = auto
- env: IMAGE=dist-x86_64-freebsd DEPLOY=1
+ name: dist-x86_64-freebsd
if: branch = auto
- env: IMAGE=dist-x86_64-musl DEPLOY=1
+ name: dist-x86_64-musl
if: branch = auto
- env: IMAGE=dist-x86_64-netbsd DEPLOY=1
+ name: dist-x86_64-netbsd
if: branch = auto
- env: IMAGE=asmjs
+ name: asmjs
if: branch = auto
- env: IMAGE=i686-gnu
+ name: i686-gnu
if: branch = auto
- env: IMAGE=i686-gnu-nopt
+ name: i686-gnu-nopt
if: branch = auto
- env: IMAGE=test-various
+ name: test-various
if: branch = auto
- env: IMAGE=x86_64-gnu
+ name: x86_64-gnu
if: branch = auto
- env: IMAGE=x86_64-gnu-full-bootstrap
+ name: x86_64-gnu-full-bootstrap
if: branch = auto
- env: IMAGE=x86_64-gnu-aux
+ name: x86_64-gnu-aux
if: branch = auto
- env: IMAGE=x86_64-gnu-tools
+ name: x86_64-gnu-tools
if: branch = auto OR (type = pull_request AND commit_message =~ /(?i:^update.*\b(rls|rustfmt|clippy|miri|cargo)\b)/)
- env: IMAGE=x86_64-gnu-debug
+ name: x86_64-gnu-debug
if: branch = auto
- env: IMAGE=x86_64-gnu-nopt
+ name: x86_64-gnu-nopt
if: branch = auto
- env: IMAGE=x86_64-gnu-distcheck
+ name: x86_64-gnu-distcheck
if: branch = auto
- env: IMAGE=mingw-check
+ name: mingw-check
if: type = pull_request OR branch = auto
- stage: publish toolstate
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index e785f03..fa40893 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -15,7 +15,7 @@
* [Helpful Links and Information](#helpful-links-and-information)
If you have questions, please make a post on [internals.rust-lang.org][internals] or
-hop on [#rust-internals][pound-rust-internals].
+hop on the [Rust Discord server][rust-discord], [Rust Zulip server][rust-zulip] or [#rust-internals][pound-rust-internals].
As a reminder, all contributors are expected to follow our [Code of Conduct][coc].
@@ -27,14 +27,17 @@
[pound-rust-internals]: https://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust-internals
[internals]: https://internals.rust-lang.org
+[rust-discord]: http://discord.gg/rust-lang
+[rust-zulip]: https://rust-lang.zulipchat.com
[coc]: https://www.rust-lang.org/conduct.html
+[rustc-guide]: https://rust-lang.github.io/rustc-guide/
[walkthrough]: https://rust-lang.github.io/rustc-guide/walkthrough.html
## Feature Requests
[feature-requests]: #feature-requests
To request a change to the way the Rust language works, please head over
-to the [RFCs repository](https://github.com/rust-lang/rfcs) and view the
+to the [RFCs repository](https://github.com/rust-lang/rfcs) and view the
[README](https://github.com/rust-lang/rfcs/blob/master/README.md)
for instructions.
@@ -129,28 +132,40 @@
before every push to make sure you never forget to make this check.
All pull requests are reviewed by another person. We have a bot,
-@rust-highfive, that will automatically assign a random person to review your
+[@rust-highfive][rust-highfive], that will automatically assign a random person to review your
request.
If you want to request that a specific person reviews your pull request,
-you can add an `r?` to the message. For example, Steve usually reviews
+you can add an `r?` to the message. For example, [Steve][steveklabnik] usually reviews
documentation changes. So if you were to make a documentation change, add
r? @steveklabnik
-to the end of the message, and @rust-highfive will assign @steveklabnik instead
+to the end of the message, and @rust-highfive will assign [@steveklabnik][steveklabnik] instead
of a random person. This is entirely optional.
After someone has reviewed your pull request, they will leave an annotation
on the pull request with an `r+`. It will look something like this:
- @bors: r+ 38fe8d2
+ @bors r+
-This tells @bors, our lovable integration bot, that your pull request has
-been approved. The PR then enters the [merge queue][merge-queue], where @bors
+This tells [@bors][bors], our lovable integration bot, that your pull request has
+been approved. The PR then enters the [merge queue][merge-queue], where [@bors][bors]
will run all the tests on every platform we support. If it all works out,
-@bors will merge your code into `master` and close the pull request.
+[@bors][bors] will merge your code into `master` and close the pull request.
+Depending on the scale of the change, you may see a slightly different form of `r+`:
+
+ @bors r+ rollup
+
+The additional `rollup` tells [@bors][bors] that this change is eligible for to be
+"rolled up". Changes that are rolled up are tested and merged at the same time, to
+speed the process up. Typically only small changes that are expected not to conflict
+with one another are rolled up.
+
+[rust-highfive]: https://github.com/rust-highfive
+[steveklabnik]: https://github.com/steveklabnik
+[bors]: https://github.com/bors
[merge-queue]: https://buildbot2.rust-lang.org/homu/queue/rust
Speaking of tests, Rust has a comprehensive test suite. More information about
@@ -190,7 +205,7 @@
[breaking-tools-built-with-the-compiler]: #breaking-tools-built-with-the-compiler
Rust's build system builds a number of tools that make use of the
-internals of the compiler. This includes
+internals of the compiler. This includes
[Clippy](https://github.com/rust-lang/rust-clippy),
[RLS](https://github.com/rust-lang/rls) and
[rustfmt](https://github.com/rust-lang/rustfmt). If these tools
@@ -292,18 +307,8 @@
Documentation improvements are very welcome. The source of `doc.rust-lang.org`
is located in `src/doc` in the tree, and standard API documentation is generated
-from the source code itself.
-
-Documentation pull requests function in the same way as other pull requests,
-though you may see a slightly different form of `r+`:
-
- @bors: r+ 38fe8d2 rollup
-
-That additional `rollup` tells @bors that this change is eligible for a 'rollup'.
-To save @bors some work, and to get small changes through more quickly, when
-@bors attempts to merge a commit that's rollup-eligible, it will also merge
-the other rollup-eligible patches too, and they'll get tested and merged at
-the same time.
+from the source code itself. Documentation pull requests function in the same way
+as other pull requests.
To find documentation-related issues, sort by the [T-doc label][tdoc].
@@ -428,7 +433,8 @@
* Although out of date, [Tom Lee's great blog article][tlgba] is very helpful
* [rustaceans.org][ro] is helpful, but mostly dedicated to IRC
* The [Rust Compiler Testing Docs][rctd]
-* For @bors, [this cheat sheet][cheatsheet] is helpful (Remember to replace `@homu` with `@bors` in the commands that you use.)
+* For [@bors][bors], [this cheat sheet][cheatsheet] is helpful
+(though you'll need to replace `@homu` with `@bors` in any commands)
* **Google!** ([search only in Rust Documentation][gsearchdocs] to find types, traits, etc. quickly)
* Don't be afraid to ask! The Rust community is friendly and helpful.
diff --git a/Cargo.lock b/Cargo.lock
index 27f7f59..ec1cda9 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -83,7 +83,7 @@
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -95,7 +95,7 @@
dependencies = [
"backtrace-sys 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-demangle 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -107,7 +107,7 @@
dependencies = [
"cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
"compiler_builtins 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-std-workspace-core 1.0.0",
]
@@ -162,7 +162,7 @@
"filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"getopts 0.2.17 (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.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)",
"pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -259,7 +259,7 @@
"jobserver 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"libgit2-sys 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -458,7 +458,7 @@
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -479,7 +479,7 @@
"filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -499,7 +499,7 @@
"diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -530,7 +530,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -657,7 +657,7 @@
dependencies = [
"curl-sys 0.4.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.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (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.40 (registry+https://github.com/rust-lang/crates.io-index)",
"schannel 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -671,7 +671,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"libnghttp2-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.40 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -729,7 +729,7 @@
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -738,7 +738,7 @@
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_users 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -749,7 +749,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"compiler_builtins 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-std-workspace-core 1.0.0",
]
@@ -858,7 +858,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -873,7 +873,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crc32fast 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"miniz-sys 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"miniz_oxide_c_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -915,7 +915,7 @@
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -988,7 +988,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"libgit2-sys 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1163,7 +1163,7 @@
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1200,7 +1200,7 @@
dependencies = [
"cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
"fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1208,7 +1208,7 @@
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1256,7 +1256,7 @@
[[package]]
name = "libc"
-version = "0.2.46"
+version = "0.2.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rustc-std-workspace-core 1.0.0",
@@ -1269,7 +1269,7 @@
dependencies = [
"cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
"curl-sys 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"libssh2-sys 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.40 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1282,7 +1282,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1291,7 +1291,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.40 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1299,12 +1299,21 @@
]
[[package]]
+name = "libtest"
+version = "0.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc_term 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "libz-sys"
version = "1.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1370,7 +1379,7 @@
dependencies = [
"cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
"filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1471,7 +1480,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1480,7 +1489,7 @@
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1503,7 +1512,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1521,7 +1530,7 @@
dependencies = [
"cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
"crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"miniz_oxide 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1535,7 +1544,7 @@
"iovec 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)",
"lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1560,7 +1569,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1607,7 +1616,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1653,7 +1662,7 @@
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1680,7 +1689,7 @@
"cfg-if 0.1.6 (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.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.40 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1703,7 +1712,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-src 111.1.0+1.1.1a (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1741,7 +1750,7 @@
dependencies = [
"compiler_builtins 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"core 0.0.0",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1751,21 +1760,12 @@
"alloc 0.0.0",
"compiler_builtins 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"core 0.0.0",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"unwind 0.0.0",
]
[[package]]
name = "parking_lot"
-version = "0.6.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "parking_lot_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "parking_lot"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
@@ -1775,21 +1775,10 @@
[[package]]
name = "parking_lot_core"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "parking_lot_core"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2018,7 +2007,7 @@
[[package]]
name = "racer"
-version = "2.1.19"
+version = "2.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2029,7 +2018,7 @@
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rls-span 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-syntax 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-syntax 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -2038,7 +2027,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2049,7 +2038,7 @@
dependencies = [
"cloudabi 0.0.3 (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.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2061,7 +2050,7 @@
dependencies = [
"cloudabi 0.0.3 (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.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_chacha 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2077,7 +2066,7 @@
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2099,7 +2088,7 @@
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -2124,7 +2113,7 @@
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -2143,7 +2132,7 @@
dependencies = [
"crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2230,7 +2219,7 @@
[[package]]
name = "rls"
-version = "1.34.0"
+version = "1.35.0"
dependencies = [
"cargo 0.36.0",
"cargo_metadata 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2250,7 +2239,7 @@
"lsp-types 0.55.4 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ordslice 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "racer 2.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
+ "racer 2.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2263,7 +2252,7 @@
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-workspace-hack 1.0.0",
"rustc_tools_util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustfmt-nightly 1.0.3",
+ "rustfmt-nightly 1.1.0",
"serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2376,20 +2365,20 @@
[[package]]
name = "rustc-ap-arena"
-version = "373.0.0"
+version = "407.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "rustc-ap-rustc_data_structures 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rustc-ap-graphviz"
-version = "373.0.0"
+version = "407.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rustc-ap-rustc_cratesio_shim"
-version = "373.0.0"
+version = "407.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2399,16 +2388,18 @@
[[package]]
name = "rustc-ap-rustc_data_structures"
-version = "373.0.0"
+version = "407.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"ena 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "jobserver 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-graphviz 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_cratesio_shim 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-graphviz 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_cratesio_shim 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-rayon 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-rayon-core 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2418,34 +2409,34 @@
[[package]]
name = "rustc-ap-rustc_errors"
-version = "373.0.0"
+version = "407.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_cratesio_shim 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_data_structures 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-syntax_pos 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_cratesio_shim 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-syntax_pos 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rustc-ap-rustc_target"
-version = "373.0.0"
+version = "407.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_cratesio_shim 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_data_structures 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_cratesio_shim 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rustc-ap-serialize"
-version = "373.0.0"
+version = "407.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2453,30 +2444,30 @@
[[package]]
name = "rustc-ap-syntax"
-version = "373.0.0"
+version = "407.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_data_structures 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_errors 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_target 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-syntax_pos 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_errors 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_target 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-syntax_pos 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rustc-ap-syntax_pos"
-version = "373.0.0"
+version = "407.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-arena 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_data_structures 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-arena 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2524,7 +2515,7 @@
dependencies = [
"crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2621,7 +2612,7 @@
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
"jobserver 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2650,7 +2641,6 @@
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc 0.0.0",
"rustc_data_structures 0.0.0",
- "rustc_incremental 0.0.0",
"rustc_metadata 0.0.0",
"rustc_mir 0.0.0",
"rustc_target 0.0.0",
@@ -2959,6 +2949,11 @@
]
[[package]]
+name = "rustc_term"
+version = "0.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "rustc_tools_util"
version = "0.1.1"
@@ -3052,7 +3047,7 @@
[[package]]
name = "rustfmt-nightly"
-version = "1.0.3"
+version = "1.1.0"
dependencies = [
"atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"bytecount 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3067,9 +3062,9 @@
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_target 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-syntax 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-syntax_pos 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_target 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-syntax 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-syntax_pos 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-workspace-hack 1.0.0",
"serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.81 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3116,11 +3111,6 @@
[[package]]
name = "scoped-tls"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "scoped-tls"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3218,7 +3208,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"arc-swap 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -3245,7 +3235,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -3266,7 +3256,7 @@
"core 0.0.0",
"dlmalloc 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"fortanix-sgx-abi 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"panic_abort 0.0.0",
"panic_unwind 0.0.0",
"profiler_builtins 0.0.0",
@@ -3417,7 +3407,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
"xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -3428,7 +3418,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
"remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3447,10 +3437,6 @@
[[package]]
name = "term"
-version = "0.0.0"
-
-[[package]]
-name = "term"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
@@ -3480,7 +3466,7 @@
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -3489,9 +3475,8 @@
name = "test"
version = "0.0.0"
dependencies = [
- "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libtest 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"proc_macro 0.0.0",
- "term 0.0.0",
]
[[package]]
@@ -3500,7 +3485,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -3534,7 +3519,7 @@
version = "0.1.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -3615,7 +3600,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
"mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3647,7 +3632,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
"mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
"signal-hook 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3718,7 +3703,7 @@
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
"mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3834,7 +3819,7 @@
dependencies = [
"compiler_builtins 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"core 0.0.0",
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -3901,7 +3886,7 @@
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -3974,7 +3959,7 @@
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -4109,10 +4094,11 @@
"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1"
"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
-"checksum libc 0.2.46 (registry+https://github.com/rust-lang/crates.io-index)" = "023a4cd09b2ff695f9734c1934145a315594b7986398496841c7031a5a1bbdbd"
+"checksum libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "aab692d7759f5cd8c859e169db98ae5b52c924add2af5fbbca11d12fefb567c1"
"checksum libgit2-sys 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)" = "48441cb35dc255da8ae72825689a95368bf510659ae1ad55dc4aa88cb1789bf1"
"checksum libnghttp2-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d75d7966bda4730b722d1eab8e668df445368a24394bae9fc1e8dc0ab3dbe4f4"
"checksum libssh2-sys 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "126a1f4078368b163bfdee65fbab072af08a1b374a5551b21e87ade27b1fbf9d"
+"checksum libtest 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1a51ac59582b915cdfc426dada72c6d9eba95818a6b481ca340f5c7152166837"
"checksum libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe"
"checksum lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "949826a5ccf18c1b3a7c3d57692778d21768b79e46eb9dd07bfc4c2160036c54"
"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
@@ -4156,9 +4142,7 @@
"checksum ordslice 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dd20eec3dbe4376829cb7d80ae6ac45e0a766831dca50202ff2d40db46a8a024"
"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
"checksum packed_simd 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "25d36de864f7218ec5633572a800109bbe5a1cc8d9d95a967f3daf93ea7e6ddc"
-"checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5"
"checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337"
-"checksum parking_lot_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "06a2b6aae052309c2fd2161ef58f5067bc17bb758377a0de9d4b279d603fdd8a"
"checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9"
"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
"checksum pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0fce5d8b5cc33983fc74f78ad552b5522ab41442c4ca91606e4236eb4b5ceefc"
@@ -4185,7 +4169,7 @@
"checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45"
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
"checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c"
-"checksum racer 2.1.19 (registry+https://github.com/rust-lang/crates.io-index)" = "d634483bed41bb116122b84ffe0ef8740345c2ceb2784ce86c33499700eb13a7"
+"checksum racer 2.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "37c88638777cc178684cf648ca0e1dad56646ce105b8593dfe665c436300adc3"
"checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd"
"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c"
"checksum rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ae9d223d52ae411a33cf7e54ec6034ec165df296ccd23533d671a28252b6f66a"
@@ -4211,20 +4195,21 @@
"checksum rls-data 0.18.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5f80b84551b32e26affaf7f12374913b5061730c0dcd185d9e8fa5a15e36e65c"
"checksum rls-span 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "33d66f1d6c6ccd5c98029f162544131698f6ebb61d8c697681cac409dcd08805"
"checksum rls-vfs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "72d56425bd5aa86d9d4372b76f0381d3b4bda9c0220e71956c9fcc929f45c1f1"
-"checksum rustc-ap-arena 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8be999235b541fc8eb54901b66e899a06076709ac5f53d6b2c5c59d29ad54780"
-"checksum rustc-ap-graphviz 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "532b5df15ca1a19a42815e37e521a20a7632b86b36868d1447932f8476f8f789"
-"checksum rustc-ap-rustc_cratesio_shim 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c388afe1ef810013c878bdf9073ab1ae28dc49e9325863b351afb10acf4cc46e"
-"checksum rustc-ap-rustc_data_structures 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "63a8f08b9fb6d607afb842ee7206273d09d69c9201bfc1c479a726093251a24e"
-"checksum rustc-ap-rustc_errors 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6dc0df7bf31588ea67e6386f6ad19f6b9a37ba7d5726ecad1cacce22e231bd98"
-"checksum rustc-ap-rustc_target 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8fb4623a6f6c65b928cbe8d9c52b38cf57ba1722677645dc53fb1bdadfd0e127"
-"checksum rustc-ap-serialize 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0c290b148c9e4e08bbcb8a313393e257c1103cedf6a038aefc9f957c8a77c755"
-"checksum rustc-ap-syntax 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "526fdc5bdbaaeae3b2a9ba42e5f5f7f29cda6ce8971b607a2955b1cb4ca339b5"
-"checksum rustc-ap-syntax_pos 373.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8e4f88a1213562373cee9de5a1d77bbf16dd706030304af041c9733492fcc952"
+"checksum rustc-ap-arena 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5aab2fb5e5becf1c9183f6c63b8714817a3e780a20b4fe6b3920751c98a18225"
+"checksum rustc-ap-graphviz 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0235ff613d4f96176ea56748010b5d8e978605cc47856ba9bb5372f4f38e9c03"
+"checksum rustc-ap-rustc_cratesio_shim 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "63e04a90b0dd8597da83633961698c61a2948f50c9d4b9a71e8afafc0ba0f158"
+"checksum rustc-ap-rustc_data_structures 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c03988d65fc5130787df32e8ea91738f78a8ed62b7a5bdd77f10e5cceb531d8e"
+"checksum rustc-ap-rustc_errors 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8b33b9dc34f9fa50bf7e6fd14f2f3c1adc69833acf43c10f3e9795bd4d613712"
+"checksum rustc-ap-rustc_target 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e6de75caef2c7acba11994614266d60238653657677934817ab368d169333cba"
+"checksum rustc-ap-serialize 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cf09c60aaee892b0fd107544cfe607d8d463e7f33da34aa823566b8fd2b17f53"
+"checksum rustc-ap-syntax 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "69f38cc120ff317678bbda8c4f58c1bbc1de64b615383ab01480482dde5e95a1"
+"checksum rustc-ap-syntax_pos 407.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "20a0a201141c5c416b1924b079eeefc7b013e34ece0740ce4997f358b3684a7f"
"checksum rustc-demangle 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "82ae957aa1b3055d8e086486723c0ccd3d7b8fa190ae8fa2e35543b6171c810e"
"checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8"
"checksum rustc-rayon 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8d98c51d9cbbe810c8b6693236d3412d8cd60513ff27a3e1b6af483dca0af544"
"checksum rustc-rayon-core 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "526e7b6d2707a5b9bec3927d424ad70fa3cfc68e0ac1b75e46cdbbc95adc5108"
"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
+"checksum rustc_term 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9c69abe7f181d2ea8d2f7b44a4aa86f4b4a567444bcfcf51ed45ede957fbf064"
"checksum rustc_tools_util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c5a95edfa0c893236ae4778bb7c4752760e4c0d245e19b5eff33c5aa5eb9dc"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
"checksum rustfix 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "af7c21531a91512a4a51b490be6ba1c8eff34fdda0dc5bf87dc28d86748aac56"
@@ -4232,7 +4217,6 @@
"checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7"
"checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267"
"checksum schannel 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "0e1a231dc10abf6749cfa5d7767f25888d484201accbd919b66ab5413c502d56"
-"checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28"
"checksum scoped-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
"checksum scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
diff --git a/RELEASES.md b/RELEASES.md
index 4cda02c..a49e072 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -110,8 +110,11 @@
methods instead.
- The `Error::cause` method has been deprecated in favor of `Error::source` which supports
downcasting.
+- [Libtest no longer creates a new thread for each test when
+ `--test-threads=1`. It also runs the tests in deterministic order][56243]
[55982]: https://github.com/rust-lang/rust/pull/55982/
+[56243]: https://github.com/rust-lang/rust/pull/56243
[56303]: https://github.com/rust-lang/rust/pull/56303/
[56351]: https://github.com/rust-lang/rust/pull/56351/
[56362]: https://github.com/rust-lang/rust/pull/56362
diff --git a/appveyor.yml b/appveyor.yml
index d70ad54..ab0a29d 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,4 +1,7 @@
environment:
+ # This is required for at least an AArch64 compiler in one image, and is also
+ # going to soon be required for compiling LLVM.
+ APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 Preview
# By default schannel checks revocation of certificates unlike some other SSL
# backends, but we've historically had problems on CI where a revocation
@@ -7,34 +10,34 @@
matrix:
# 32/64 bit MSVC tests
- - MSYS_BITS: 64
+ - CI_JOB_NAME: x86_64-msvc
+ MSYS_BITS: 64
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-profiler
SCRIPT: python x.py test
- CI_JOB_NAME: x86_64-msvc
- - MSYS_BITS: 32
+ - CI_JOB_NAME: i686-msvc-1
+ MSYS_BITS: 32
RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc
SCRIPT: make appveyor-subset-1
- CI_JOB_NAME: i686-msvc-1
- - MSYS_BITS: 32
+ - CI_JOB_NAME: i686-msvc-2
+ MSYS_BITS: 32
RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc
SCRIPT: make appveyor-subset-2
- CI_JOB_NAME: i686-msvc-2
# MSVC aux tests
- - MSYS_BITS: 64
+ - CI_JOB_NAME: x86_64-msvc-aux
+ MSYS_BITS: 64
RUST_CHECK_TARGET: check-aux EXCLUDE_CARGO=1
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc
- CI_JOB_NAME: x86_64-msvc-aux
- - MSYS_BITS: 64
+ - CI_JOB_NAME: x86_64-msvc-cargo
+ MSYS_BITS: 64
SCRIPT: python x.py test src/tools/cargotest src/tools/cargo
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc
- CI_JOB_NAME: x86_64-msvc-cargo
# MSVC tools tests
- - MSYS_BITS: 64
+ - CI_JOB_NAME: x86_64-msvc-tools
+ MSYS_BITS: 64
SCRIPT: src/ci/docker/x86_64-gnu-tools/checktools.sh x.py /tmp/toolstates.json windows
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --save-toolstates=/tmp/toolstates.json --enable-test-miri
- CI_JOB_NAME: x86_64-msvc-tools
# 32/64-bit MinGW builds.
#
@@ -49,30 +52,31 @@
# bucket, but they cleraly didn't originate there! The downloads originally
# came from the mingw-w64 SourceForge download site. Unfortunately
# SourceForge is notoriously flaky, so we mirror it on our own infrastructure.
- - MSYS_BITS: 32
+ - CI_JOB_NAME: i686-mingw-1
+ MSYS_BITS: 32
RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu
SCRIPT: make appveyor-subset-1
MINGW_URL: https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror
MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z
MINGW_DIR: mingw32
- CI_JOB_NAME: i686-mingw-1
- - MSYS_BITS: 32
+ - CI_JOB_NAME: i686-mingw-2
+ MSYS_BITS: 32
RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu
SCRIPT: make appveyor-subset-2
MINGW_URL: https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror
MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z
MINGW_DIR: mingw32
- CI_JOB_NAME: i686-mingw-2
- - MSYS_BITS: 64
+ - CI_JOB_NAME: x86_64-mingw
+ MSYS_BITS: 64
SCRIPT: python x.py test
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu
MINGW_URL: https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror
MINGW_ARCHIVE: x86_64-6.3.0-release-posix-seh-rt_v5-rev2.7z
MINGW_DIR: mingw64
- CI_JOB_NAME: x86_64-mingw
# 32/64 bit MSVC and GNU deployment
- - RUST_CONFIGURE_ARGS: >
+ - CI_JOB_NAME: dist-x86_64-msvc
+ RUST_CONFIGURE_ARGS: >
--build=x86_64-pc-windows-msvc
--target=x86_64-pc-windows-msvc,aarch64-pc-windows-msvc
--enable-full-tools
@@ -80,9 +84,8 @@
SCRIPT: python x.py dist
DIST_REQUIRE_ALL_TOOLS: 1
DEPLOY: 1
- CI_JOB_NAME: dist-x86_64-msvc
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 Preview
- - RUST_CONFIGURE_ARGS: >
+ - CI_JOB_NAME: dist-i686-msvc
+ RUST_CONFIGURE_ARGS: >
--build=i686-pc-windows-msvc
--target=i586-pc-windows-msvc
--enable-full-tools
@@ -90,8 +93,8 @@
SCRIPT: python x.py dist
DIST_REQUIRE_ALL_TOOLS: 1
DEPLOY: 1
- CI_JOB_NAME: dist-i686-msvc
- - MSYS_BITS: 32
+ - CI_JOB_NAME: dist-i686-mingw
+ MSYS_BITS: 32
RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu --enable-full-tools
SCRIPT: python x.py dist
MINGW_URL: https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror
@@ -99,8 +102,8 @@
MINGW_DIR: mingw32
DIST_REQUIRE_ALL_TOOLS: 1
DEPLOY: 1
- CI_JOB_NAME: dist-i686-mingw
- - MSYS_BITS: 64
+ - CI_JOB_NAME: dist-x86_64-mingw
+ MSYS_BITS: 64
SCRIPT: python x.py dist
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu --enable-full-tools
MINGW_URL: https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror
@@ -108,14 +111,13 @@
MINGW_DIR: mingw64
DIST_REQUIRE_ALL_TOOLS: 1
DEPLOY: 1
- CI_JOB_NAME: dist-x86_64-mingw
# "alternate" deployment, see .travis.yml for more info
- - MSYS_BITS: 64
+ - CI_JOB_NAME: dist-x86_64-msvc-alt
+ MSYS_BITS: 64
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-extended --enable-profiler
SCRIPT: python x.py dist
DEPLOY_ALT: 1
- CI_JOB_NAME: dist-x86_64-msvc-alt
matrix:
fast_finish: true
diff --git a/config.toml.example b/config.toml.example
index 9afbd93..8c1049f 100644
--- a/config.toml.example
+++ b/config.toml.example
@@ -14,10 +14,6 @@
# =============================================================================
[llvm]
-# Indicates whether rustc will support compilation with LLVM
-# note: rustc does not compile without LLVM at the moment
-#enabled = true
-
# Indicates whether the LLVM build is a Release or Debug build
#optimize = true
diff --git a/src/bootstrap/bin/rustdoc.rs b/src/bootstrap/bin/rustdoc.rs
index 36beec3..085f243 100644
--- a/src/bootstrap/bin/rustdoc.rs
+++ b/src/bootstrap/bin/rustdoc.rs
@@ -35,7 +35,7 @@
.arg("--cfg")
.arg("dox")
.arg("--sysroot")
- .arg(sysroot)
+ .arg(&sysroot)
.env(bootstrap::util::dylib_path_var(),
env::join_paths(&dylib_path).unwrap());
@@ -72,7 +72,13 @@
}
if verbose > 1 {
- eprintln!("rustdoc command: {:?}", cmd);
+ eprintln!(
+ "rustdoc command: {:?}={:?} {:?}",
+ bootstrap::util::dylib_path_var(),
+ env::join_paths(&dylib_path).unwrap(),
+ cmd,
+ );
+ eprintln!("sysroot: {:?}", sysroot);
eprintln!("libdir: {:?}", libdir);
}
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index ffd23e7..f93f3e7 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -374,6 +374,7 @@
test::MirOpt,
test::Codegen,
test::CodegenUnits,
+ test::Assembly,
test::Incremental,
test::Debuginfo,
test::UiFullDeps,
@@ -408,11 +409,11 @@
test::RustdocJSStd,
test::RustdocJSNotStd,
test::RustdocTheme,
+ test::RustdocUi,
// Run bootstrap close to the end as it's unlikely to fail
test::Bootstrap,
// Run run-make last, since these won't pass without make on Windows
test::RunMake,
- test::RustdocUi
),
Kind::Bench => describe!(test::Crate, test::CrateLibrustc),
Kind::Doc => describe!(
@@ -669,20 +670,19 @@
.map(|entry| entry.path())
}
- pub fn rustdoc(&self, host: Interned<String>) -> PathBuf {
- self.ensure(tool::Rustdoc { host })
+ pub fn rustdoc(&self, compiler: Compiler) -> PathBuf {
+ self.ensure(tool::Rustdoc { compiler })
}
- pub fn rustdoc_cmd(&self, host: Interned<String>) -> Command {
+ pub fn rustdoc_cmd(&self, compiler: Compiler) -> Command {
let mut cmd = Command::new(&self.out.join("bootstrap/debug/rustdoc"));
- let compiler = self.compiler(self.top_stage, host);
cmd.env("RUSTC_STAGE", compiler.stage.to_string())
.env("RUSTC_SYSROOT", self.sysroot(compiler))
// Note that this is *not* the sysroot_libdir because rustdoc must be linked
// equivalently to rustc.
.env("RUSTDOC_LIBDIR", self.rustc_libdir(compiler))
.env("CFG_RELEASE_CHANNEL", &self.config.channel)
- .env("RUSTDOC_REAL", self.rustdoc(host))
+ .env("RUSTDOC_REAL", self.rustdoc(compiler))
.env("RUSTDOC_CRATE_VERSION", self.rust_version())
.env("RUSTC_BOOTSTRAP", "1");
@@ -690,7 +690,7 @@
cmd.env_remove("MAKEFLAGS");
cmd.env_remove("MFLAGS");
- if let Some(linker) = self.linker(host) {
+ if let Some(linker) = self.linker(compiler.host) {
cmd.env("RUSTC_TARGET_LINKER", linker);
}
cmd
@@ -752,7 +752,7 @@
// This is the intended out directory for compiler documentation.
my_out = self.compiler_doc_out(target);
}
- let rustdoc = self.rustdoc(compiler.host);
+ let rustdoc = self.rustdoc(compiler);
self.clear_if_dirty(&my_out, &rustdoc);
} else if cmd != "test" {
match mode {
@@ -909,7 +909,7 @@
.env(
"RUSTDOC_REAL",
if cmd == "doc" || cmd == "rustdoc" || (cmd == "test" && want_rustdoc) {
- self.rustdoc(compiler.host)
+ self.rustdoc(compiler)
} else {
PathBuf::from("/path/to/nowhere/rustdoc/not/required")
},
@@ -996,10 +996,7 @@
// For other crates, however, we know that we've already got a standard
// library up and running, so we can use the normal compiler to compile
// build scripts in that situation.
- //
- // If LLVM support is disabled we need to use the snapshot compiler to compile
- // build scripts, as the new compiler doesn't support executables.
- if mode == Mode::Std || !self.config.llvm_enabled {
+ if mode == Mode::Std {
cargo
.env("RUSTC_SNAPSHOT", &self.initial_rustc)
.env("RUSTC_SNAPSHOT_LIBDIR", self.rustc_snapshot_libdir());
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index d209588..6162c7e 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -64,7 +64,6 @@
pub backtrace_on_ice: bool,
// llvm codegen options
- pub llvm_enabled: bool,
pub llvm_assertions: bool,
pub llvm_optimize: bool,
pub llvm_thin_lto: bool,
@@ -244,7 +243,6 @@
#[derive(Deserialize, Default)]
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
struct Llvm {
- enabled: Option<bool>,
ccache: Option<StringOrBool>,
ninja: Option<bool>,
assertions: Option<bool>,
@@ -360,7 +358,6 @@
pub fn default_opts() -> Config {
let mut config = Config::default();
- config.llvm_enabled = true;
config.llvm_optimize = true;
config.llvm_version_check = true;
config.backtrace = true;
@@ -512,7 +509,6 @@
Some(StringOrBool::Bool(false)) | None => {}
}
set(&mut config.ninja, llvm.ninja);
- set(&mut config.llvm_enabled, llvm.enabled);
llvm_assertions = llvm.assertions;
set(&mut config.llvm_optimize, llvm.optimize);
set(&mut config.llvm_thin_lto, llvm.thin_lto);
@@ -671,6 +667,11 @@
pub fn very_verbose(&self) -> bool {
self.verbose > 1
}
+
+ pub fn llvm_enabled(&self) -> bool {
+ self.rust_codegen_backends.contains(&INTERNER.intern_str("llvm"))
+ || self.rust_codegen_backends.contains(&INTERNER.intern_str("emscripten"))
+ }
}
fn set<T>(field: &mut T, val: Option<T>) {
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 2c40dd6..d982330 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -479,7 +479,7 @@
t!(fs::create_dir_all(image.join("bin")));
builder.cp_r(&src.join("bin"), &image.join("bin"));
- builder.install(&builder.rustdoc(compiler.host), &image.join("bin"), 0o755);
+ builder.install(&builder.rustdoc(compiler), &image.join("bin"), 0o755);
// Copy runtime DLLs needed by the compiler
if libdir != "bin" {
@@ -899,7 +899,6 @@
"src/libstd",
"src/libunwind",
"src/libtest",
- "src/libterm",
"src/libprofiler_builtins",
"src/stdsimd",
"src/libproc_macro",
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index e0ad042..ae32928 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -335,7 +335,7 @@
let footer = builder.src.join("src/doc/footer.inc");
let version_info = out.join("version_info.html");
- let mut cmd = builder.rustdoc_cmd(compiler.host);
+ let mut cmd = builder.rustdoc_cmd(compiler);
let out = out.join("book");
@@ -415,7 +415,7 @@
}
let html = out.join(filename).with_extension("html");
- let rustdoc = builder.rustdoc(compiler.host);
+ let rustdoc = builder.rustdoc(compiler);
if up_to_date(&path, &html) &&
up_to_date(&footer, &html) &&
up_to_date(&favicon, &html) &&
@@ -425,7 +425,7 @@
continue
}
- let mut cmd = builder.rustdoc_cmd(compiler.host);
+ let mut cmd = builder.rustdoc_cmd(compiler);
cmd.arg("--html-after-content").arg(&footer)
.arg("--html-before-content").arg(&version_info)
.arg("--html-in-header").arg(&favicon)
@@ -824,7 +824,7 @@
builder.ensure(Rustc { stage, target });
// Build rustdoc.
- builder.ensure(tool::Rustdoc { host: compiler.host });
+ builder.ensure(tool::Rustdoc { compiler: compiler });
// Symlink compiler docs to the output directory of rustdoc documentation.
let out_dir = builder.stage_out(compiler, Mode::ToolRustc)
@@ -883,7 +883,11 @@
builder.info(&format!("Documenting error index ({})", target));
let out = builder.doc_out(target);
t!(fs::create_dir_all(&out));
- let mut index = builder.tool_cmd(Tool::ErrorIndex);
+ let compiler = builder.compiler(2, builder.config.build);
+ let mut index = tool::ErrorIndex::command(
+ builder,
+ compiler,
+ );
index.arg("html");
index.arg(out.join("error-index.html"));
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 9317a40..0c3daea 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -241,6 +241,8 @@
clippy_info: channel::GitInfo,
miri_info: channel::GitInfo,
rustfmt_info: channel::GitInfo,
+ in_tree_llvm_info: channel::GitInfo,
+ emscripten_llvm_info: channel::GitInfo,
local_rebuild: bool,
fail_fast: bool,
doc_tests: DocTests,
@@ -363,6 +365,8 @@
let clippy_info = channel::GitInfo::new(&config, &src.join("src/tools/clippy"));
let miri_info = channel::GitInfo::new(&config, &src.join("src/tools/miri"));
let rustfmt_info = channel::GitInfo::new(&config, &src.join("src/tools/rustfmt"));
+ let in_tree_llvm_info = channel::GitInfo::new(&config, &src.join("src/llvm-project"));
+ let emscripten_llvm_info = channel::GitInfo::new(&config, &src.join("src/llvm-emscripten"));
let mut build = Build {
initial_rustc: config.initial_rustc.clone(),
@@ -386,6 +390,8 @@
clippy_info,
miri_info,
rustfmt_info,
+ in_tree_llvm_info,
+ emscripten_llvm_info,
cc: HashMap::new(),
cxx: HashMap::new(),
ar: HashMap::new(),
@@ -720,6 +726,17 @@
}
}
+ pub fn is_verbose_than(&self, level: usize) -> bool {
+ self.verbosity > level
+ }
+
+ /// Prints a message if this build is configured in more verbose mode than `level`.
+ fn verbose_than(&self, level: usize, msg: &str) {
+ if self.is_verbose_than(level) {
+ println!("{}", msg);
+ }
+ }
+
fn info(&self, msg: &str) {
if self.config.dry_run { return; }
println!("{}", msg);
@@ -1152,6 +1169,7 @@
/// Copies a file from `src` to `dst`
pub fn copy(&self, src: &Path, dst: &Path) {
if self.config.dry_run { return; }
+ self.verbose_than(1, &format!("Copy {:?} to {:?}", src, dst));
let _ = fs::remove_file(&dst);
let metadata = t!(src.symlink_metadata());
if metadata.file_type().is_symlink() {
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index d78670c..3babbc9 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -18,6 +18,7 @@
use cmake;
use cc;
+use crate::channel;
use crate::util::{self, exe};
use build_helper::up_to_date;
use crate::builder::{Builder, RunConfig, ShouldRun, Step};
@@ -231,7 +232,26 @@
}
if let Some(ref suffix) = builder.config.llvm_version_suffix {
- cfg.define("LLVM_VERSION_SUFFIX", suffix);
+ // Allow version-suffix="" to not define a version suffix at all.
+ if !suffix.is_empty() {
+ cfg.define("LLVM_VERSION_SUFFIX", suffix);
+ }
+ } else {
+ let mut default_suffix = format!(
+ "-rust-{}-{}",
+ channel::CFG_RELEASE_NUM,
+ builder.config.channel,
+ );
+ let llvm_info = if self.emscripten {
+ &builder.emscripten_llvm_info
+ } else {
+ &builder.in_tree_llvm_info
+ };
+ if let Some(sha) = llvm_info.sha_short() {
+ default_suffix.push_str("-");
+ default_suffix.push_str(sha);
+ }
+ cfg.define("LLVM_VERSION_SUFFIX", default_suffix);
}
if let Some(ref linker) = builder.config.llvm_use_linker {
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 81e09bc..bbe1872 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -177,7 +177,7 @@
cmd.arg(&builder.initial_cargo)
.arg(&out_dir)
.env("RUSTC", builder.rustc(compiler))
- .env("RUSTDOC", builder.rustdoc(compiler.host)),
+ .env("RUSTDOC", builder.rustdoc(compiler)),
);
}
}
@@ -414,7 +414,6 @@
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct CompiletestTest {
- stage: u32,
host: Interned<String>,
}
@@ -427,16 +426,14 @@
fn make_run(run: RunConfig<'_>) {
run.builder.ensure(CompiletestTest {
- stage: run.builder.top_stage,
host: run.target,
});
}
/// Runs `cargo test` for compiletest.
fn run(self, builder: &Builder<'_>) {
- let stage = self.stage;
let host = self.host;
- let compiler = builder.compiler(stage, host);
+ let compiler = builder.compiler(0, host);
let mut cargo = tool::prepare_tool_cargo(builder,
compiler,
@@ -563,7 +560,7 @@
builder.sysroot_libdir(self.compiler, self.compiler.host),
)
.env("CFG_RELEASE_CHANNEL", &builder.config.channel)
- .env("RUSTDOC_REAL", builder.rustdoc(self.compiler.host))
+ .env("RUSTDOC_REAL", builder.rustdoc(self.compiler))
.env("RUSTDOC_CRATE_VERSION", builder.rust_version())
.env("RUSTC_BOOTSTRAP", "1");
if let Some(linker) = builder.linker(self.compiler.host) {
@@ -936,6 +933,12 @@
suite: "run-make-fulldeps"
});
+default_test!(Assembly {
+ path: "src/test/assembly",
+ mode: "assembly",
+ suite: "assembly"
+});
+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
struct Compiletest {
compiler: Compiler,
@@ -1036,7 +1039,7 @@
|| mode == "js-doc-test"
{
cmd.arg("--rustdoc-path")
- .arg(builder.rustdoc(compiler.host));
+ .arg(builder.rustdoc(compiler));
}
cmd.arg("--src-base")
@@ -1194,7 +1197,7 @@
cmd.arg("--quiet");
}
- if builder.config.llvm_enabled {
+ if builder.config.llvm_enabled() {
let llvm_config = builder.ensure(native::Llvm {
target: builder.config.build,
emscripten: false,
@@ -1227,12 +1230,6 @@
}
}
}
- if suite == "run-make-fulldeps" && !builder.config.llvm_enabled {
- builder.info(
- "Ignoring run-make test suite as they generally don't work without LLVM"
- );
- return;
- }
if suite != "run-make-fulldeps" {
cmd.arg("--cc")
@@ -1464,7 +1461,10 @@
t!(fs::create_dir_all(&dir));
let output = dir.join("error-index.md");
- let mut tool = builder.tool_cmd(Tool::ErrorIndex);
+ let mut tool = tool::ErrorIndex::command(
+ builder,
+ builder.compiler(compiler.stage, builder.config.build),
+ );
tool.arg("markdown")
.arg(&output)
.env("CFG_BUILD", &builder.config.build)
@@ -1489,7 +1489,7 @@
}
builder.info(&format!("doc tests for: {}", markdown.display()));
- let mut cmd = builder.rustdoc_cmd(compiler.host);
+ let mut cmd = builder.rustdoc_cmd(compiler);
builder.add_rust_test_threads(&mut cmd);
cmd.arg("--test");
cmd.arg(markdown);
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index 9dbcacf..35e0e24 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -251,9 +251,9 @@
cargo
}
-macro_rules! tool {
+macro_rules! bootstrap_tool {
($(
- $name:ident, $path:expr, $tool_name:expr, $mode:expr
+ $name:ident, $path:expr, $tool_name:expr
$(,llvm_tools = $llvm:expr)*
$(,is_external_tool = $external:expr)*
;
@@ -267,10 +267,7 @@
impl Tool {
pub fn get_mode(&self) -> Mode {
- let mode = match self {
- $(Tool::$name => $mode,)+
- };
- mode
+ Mode::ToolBootstrap
}
/// Whether this tool requires LLVM to run
@@ -283,27 +280,15 @@
impl<'a> Builder<'a> {
pub fn tool_exe(&self, tool: Tool) -> PathBuf {
- let stage = self.tool_default_stage(tool);
match tool {
$(Tool::$name =>
self.ensure($name {
- compiler: self.compiler(stage, self.config.build),
+ compiler: self.compiler(0, self.config.build),
target: self.config.build,
}),
)+
}
}
-
- pub fn tool_default_stage(&self, tool: Tool) -> u32 {
- // Compile the error-index in the same stage as rustdoc to avoid
- // recompiling rustdoc twice if we can. Otherwise compile
- // everything else in stage0 as there's no need to rebootstrap
- // everything.
- match tool {
- Tool::ErrorIndex if self.top_stage >= 2 => self.top_stage,
- _ => 0,
- }
- }
}
$(
@@ -322,7 +307,8 @@
fn make_run(run: RunConfig<'_>) {
run.builder.ensure($name {
- compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build),
+ // snapshot compiler
+ compiler: run.builder.compiler(0, run.builder.config.build),
target: run.target,
});
}
@@ -332,7 +318,7 @@
compiler: self.compiler,
target: self.target,
tool: $tool_name,
- mode: $mode,
+ mode: Mode::ToolBootstrap,
path: $path,
is_optional_tool: false,
source_type: if false $(|| $external)* {
@@ -348,22 +334,68 @@
}
}
-tool!(
- Rustbook, "src/tools/rustbook", "rustbook", Mode::ToolBootstrap;
- ErrorIndex, "src/tools/error_index_generator", "error_index_generator", Mode::ToolRustc;
- UnstableBookGen, "src/tools/unstable-book-gen", "unstable-book-gen", Mode::ToolBootstrap;
- Tidy, "src/tools/tidy", "tidy", Mode::ToolBootstrap;
- Linkchecker, "src/tools/linkchecker", "linkchecker", Mode::ToolBootstrap;
- CargoTest, "src/tools/cargotest", "cargotest", Mode::ToolBootstrap;
- Compiletest, "src/tools/compiletest", "compiletest", Mode::ToolBootstrap, llvm_tools = true;
- BuildManifest, "src/tools/build-manifest", "build-manifest", Mode::ToolBootstrap;
- RemoteTestClient, "src/tools/remote-test-client", "remote-test-client", Mode::ToolBootstrap;
- RustInstaller, "src/tools/rust-installer", "fabricate", Mode::ToolBootstrap,
- is_external_tool = true;
- RustdocTheme, "src/tools/rustdoc-themes", "rustdoc-themes", Mode::ToolBootstrap;
+bootstrap_tool!(
+ Rustbook, "src/tools/rustbook", "rustbook";
+ UnstableBookGen, "src/tools/unstable-book-gen", "unstable-book-gen";
+ Tidy, "src/tools/tidy", "tidy";
+ Linkchecker, "src/tools/linkchecker", "linkchecker";
+ CargoTest, "src/tools/cargotest", "cargotest";
+ Compiletest, "src/tools/compiletest", "compiletest", llvm_tools = true;
+ BuildManifest, "src/tools/build-manifest", "build-manifest";
+ RemoteTestClient, "src/tools/remote-test-client", "remote-test-client";
+ RustInstaller, "src/tools/rust-installer", "fabricate", is_external_tool = true;
+ RustdocTheme, "src/tools/rustdoc-themes", "rustdoc-themes";
);
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
+pub struct ErrorIndex {
+ pub compiler: Compiler,
+}
+
+impl ErrorIndex {
+ pub fn command(builder: &Builder<'_>, compiler: Compiler) -> Command {
+ let mut cmd = Command::new(builder.ensure(ErrorIndex {
+ compiler
+ }));
+ add_lib_path(
+ vec![PathBuf::from(&builder.sysroot_libdir(compiler, compiler.host))],
+ &mut cmd,
+ );
+ cmd
+ }
+}
+
+impl Step for ErrorIndex {
+ type Output = PathBuf;
+
+ fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+ run.path("src/tools/error_index_generator")
+ }
+
+ fn make_run(run: RunConfig<'_>) {
+ // Compile the error-index in the same stage as rustdoc to avoid
+ // recompiling rustdoc twice if we can.
+ let stage = if run.builder.top_stage >= 2 { run.builder.top_stage } else { 0 };
+ run.builder.ensure(ErrorIndex {
+ compiler: run.builder.compiler(stage, run.builder.config.build),
+ });
+ }
+
+ fn run(self, builder: &Builder<'_>) -> PathBuf {
+ builder.ensure(ToolBuild {
+ compiler: self.compiler,
+ target: self.compiler.host,
+ tool: "error_index_generator",
+ mode: Mode::ToolRustc,
+ path: "src/tools/error_index_generator",
+ is_optional_tool: false,
+ source_type: SourceType::InTree,
+ extra_features: Vec::new(),
+ }).expect("expected to build -- essential tool")
+ }
+}
+
+#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct RemoteTestServer {
pub compiler: Compiler,
pub target: Interned<String>,
@@ -399,7 +431,9 @@
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct Rustdoc {
- pub host: Interned<String>,
+ /// This should only ever be 0 or 2.
+ /// We sometimes want to reference the "bootstrap" rustdoc, which is why this option is here.
+ pub compiler: Compiler,
}
impl Step for Rustdoc {
@@ -413,12 +447,12 @@
fn make_run(run: RunConfig<'_>) {
run.builder.ensure(Rustdoc {
- host: run.host,
+ compiler: run.builder.compiler(run.builder.top_stage, run.host),
});
}
fn run(self, builder: &Builder<'_>) -> PathBuf {
- let target_compiler = builder.compiler(builder.top_stage, self.host);
+ let target_compiler = self.compiler;
if target_compiler.stage == 0 {
if !target_compiler.is_snapshot(builder) {
panic!("rustdoc in stage 0 must be snapshot rustdoc");
@@ -626,7 +660,7 @@
/// `host`.
pub fn tool_cmd(&self, tool: Tool) -> Command {
let mut cmd = Command::new(self.tool_exe(tool));
- let compiler = self.compiler(self.tool_default_stage(tool), self.config.build);
+ let compiler = self.compiler(0, self.config.build);
self.prepare_tool_cmd(compiler, tool, &mut cmd);
cmd
}
@@ -638,7 +672,7 @@
fn prepare_tool_cmd(&self, compiler: Compiler, tool: Tool, cmd: &mut Command) {
let host = &compiler.host;
let mut lib_paths: Vec<PathBuf> = vec![
- if compiler.stage == 0 && tool != Tool::ErrorIndex {
+ if compiler.stage == 0 {
self.build.rustc_snapshot_libdir()
} else {
PathBuf::from(&self.sysroot_libdir(compiler, compiler.host))
@@ -700,7 +734,7 @@
}
fn llvm_bin_path(&self) -> Option<PathBuf> {
- if self.config.llvm_enabled {
+ if self.config.llvm_enabled() {
let llvm_config = self.ensure(native::Llvm {
target: self.config.build,
emscripten: false,
diff --git a/src/ci/docker/disabled/dist-x86_64-redox/Dockerfile b/src/ci/docker/disabled/dist-x86_64-redox/Dockerfile
index f4c25f7..11a3acd 100644
--- a/src/ci/docker/disabled/dist-x86_64-redox/Dockerfile
+++ b/src/ci/docker/disabled/dist-x86_64-redox/Dockerfile
@@ -7,8 +7,8 @@
RUN sh /scripts/crosstool-ng.sh
WORKDIR /tmp
-COPY cross/install-x86_64-redox.sh /tmp/
-RUN ./install-x86_64-redox.sh
+COPY dist-various-1/install-x86_64-redox.sh /scripts/
+RUN sh /scripts/install-x86_64-redox.sh
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh
diff --git a/src/ci/docker/dist-powerpc64-linux/build-powerpc64-toolchain.sh b/src/ci/docker/dist-powerpc64-linux/build-powerpc64-toolchain.sh
index f7aa2cd..fc53849 100755
--- a/src/ci/docker/dist-powerpc64-linux/build-powerpc64-toolchain.sh
+++ b/src/ci/docker/dist-powerpc64-linux/build-powerpc64-toolchain.sh
@@ -3,9 +3,29 @@
source shared.sh
+BINUTILS=2.32
+TARGET=powerpc64-unknown-linux-gnu
+PREFIX=/x-tools/$TARGET
+SYSROOT=$PREFIX/$TARGET/sysroot
+
mkdir build
cd build
cp ../powerpc64-linux-gnu.config .config
hide_output ct-ng build
cd ..
rm -rf build
+
+chmod -R u+w $PREFIX
+
+# Next, download and build newer binutils.
+mkdir binutils-$TARGET
+pushd binutils-$TARGET
+curl https://ftp.gnu.org/gnu/binutils/binutils-$BINUTILS.tar.bz2 | tar xjf -
+mkdir binutils-build
+cd binutils-build
+hide_output ../binutils-$BINUTILS/configure --target=$TARGET \
+ --prefix=$PREFIX --with-sysroot=$SYSROOT
+hide_output make -j10
+hide_output make install
+popd
+rm -rf binutils-$TARGET
diff --git a/src/ci/docker/dist-powerpc64le-linux/build-powerpc64le-toolchain.sh b/src/ci/docker/dist-powerpc64le-linux/build-powerpc64le-toolchain.sh
index a01803d..f866a24 100755
--- a/src/ci/docker/dist-powerpc64le-linux/build-powerpc64le-toolchain.sh
+++ b/src/ci/docker/dist-powerpc64le-linux/build-powerpc64le-toolchain.sh
@@ -4,7 +4,7 @@
source shared.sh
-BINUTILS=2.25.1
+BINUTILS=2.32
GCC=5.3.0
TARGET=powerpc64le-linux-gnu
SYSROOT=/usr/local/$TARGET/sysroot
diff --git a/src/ci/docker/dist-various-1/install-x86_64-redox.sh b/src/ci/docker/dist-various-1/install-x86_64-redox.sh
index c39be14..339042b 100755
--- a/src/ci/docker/dist-various-1/install-x86_64-redox.sh
+++ b/src/ci/docker/dist-various-1/install-x86_64-redox.sh
@@ -3,11 +3,5 @@
set -ex
-apt-get update
-apt-get install -y --no-install-recommends software-properties-common apt-transport-https
-
-apt-key adv --batch --yes --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys AA12E97F0881517F
-add-apt-repository -y 'deb https://static.redox-os.org/toolchain/apt /'
-
-apt-get update
-apt-get install -y x86-64-unknown-redox-gcc
+curl https://static.redox-os.org/toolchain/x86_64-unknown-redox/relibc-install.tar.gz | \
+tar --extract --gzip --directory /usr/local
diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh
index b4426bb..ef15175 100755
--- a/src/ci/docker/run.sh
+++ b/src/ci/docker/run.sh
@@ -22,7 +22,18 @@
hash_key=/tmp/.docker-hash-key.txt
rm -f "${hash_key}"
echo $image >> $hash_key
- find $docker_dir -type f | sort | xargs cat >> $hash_key
+
+ cat "$docker_dir/$image/Dockerfile" >> $hash_key
+ # Look for all source files involves in the COPY command
+ copied_files=/tmp/.docker-copied-files.txt
+ rm -f "$copied_files"
+ for i in $(sed -n -e 's/^COPY \(.*\) .*$/\1/p' "$docker_dir/$image/Dockerfile"); do
+ # List the file names
+ find "$docker_dir/$i" -type f >> $copied_files
+ done
+ # Sort the file names and cat the content into the hash key
+ sort $copied_files | xargs cat >> $hash_key
+
docker --version >> $hash_key
cksum=$(sha512sum $hash_key | \
awk '{print $1}')
diff --git a/src/ci/docker/test-various/Dockerfile b/src/ci/docker/test-various/Dockerfile
index 60b431a..611a24a 100644
--- a/src/ci/docker/test-various/Dockerfile
+++ b/src/ci/docker/test-various/Dockerfile
@@ -53,7 +53,8 @@
ENV NVPTX_TARGETS=nvptx64-nvidia-cuda
ENV NVPTX_SCRIPT python2.7 /checkout/x.py test --target $NVPTX_TARGETS \
- src/test/run-make
+ src/test/run-make \
+ src/test/assembly
ENV MUSL_TARGETS=x86_64-unknown-linux-musl \
CC_x86_64_unknown_linux_musl=x86_64-linux-musl-gcc \
diff --git a/src/ci/docker/x86_64-gnu-tools/checktools.sh b/src/ci/docker/x86_64-gnu-tools/checktools.sh
index 3343716..97e6ee2 100755
--- a/src/ci/docker/x86_64-gnu-tools/checktools.sh
+++ b/src/ci/docker/x86_64-gnu-tools/checktools.sh
@@ -78,6 +78,7 @@
check_dispatch $1 beta clippy-driver src/tools/clippy
# these tools are not required for beta to successfully branch
check_dispatch $1 nightly miri src/tools/miri
+ check_dispatch $1 nightly embedded-book src/doc/embedded-book
}
# If this PR is intended to update one of these tools, do not let the build pass
diff --git a/src/liballoc/prelude.rs b/src/liballoc/prelude.rs
deleted file mode 100644
index 6767cf8..0000000
--- a/src/liballoc/prelude.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-//! The alloc Prelude
-//!
-//! The purpose of this module is to alleviate imports of commonly-used
-//! items of the `alloc` crate by adding a glob import to the top of modules:
-//!
-//! ```
-//! # #![allow(unused_imports)]
-//! # #![feature(alloc)]
-//! extern crate alloc;
-//! use alloc::prelude::*;
-//! ```
-
-#![unstable(feature = "alloc", issue = "27783")]
-
-#[unstable(feature = "alloc", issue = "27783")] pub use crate::borrow::ToOwned;
-#[unstable(feature = "alloc", issue = "27783")] pub use crate::boxed::Box;
-#[unstable(feature = "alloc", issue = "27783")] pub use crate::slice::SliceConcatExt;
-#[unstable(feature = "alloc", issue = "27783")] pub use crate::string::{String, ToString};
-#[unstable(feature = "alloc", issue = "27783")] pub use crate::vec::Vec;
diff --git a/src/liballoc/prelude/mod.rs b/src/liballoc/prelude/mod.rs
new file mode 100644
index 0000000..33cc51d
--- /dev/null
+++ b/src/liballoc/prelude/mod.rs
@@ -0,0 +1,16 @@
+//! The alloc Prelude
+//!
+//! The purpose of this module is to alleviate imports of commonly-used
+//! items of the `alloc` crate by adding a glob import to the top of modules:
+//!
+//! ```
+//! # #![allow(unused_imports)]
+//! # #![feature(alloc)]
+//! #![feature(alloc_prelude)]
+//! extern crate alloc;
+//! use alloc::prelude::v1::*;
+//! ```
+
+#![unstable(feature = "alloc_prelude", issue = "58935")]
+
+pub mod v1;
diff --git a/src/liballoc/prelude/v1.rs b/src/liballoc/prelude/v1.rs
new file mode 100644
index 0000000..b6b0139
--- /dev/null
+++ b/src/liballoc/prelude/v1.rs
@@ -0,0 +1,11 @@
+//! The first version of the prelude of `alloc` crate.
+//!
+//! See the [module-level documentation](../index.html) for more.
+
+#![unstable(feature = "alloc_prelude", issue = "58935")]
+
+#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::borrow::ToOwned;
+#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::boxed::Box;
+#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::slice::SliceConcatExt;
+#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::string::{String, ToString};
+#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::vec::Vec;
diff --git a/src/liballoc/tests/binary_heap.rs b/src/liballoc/tests/binary_heap.rs
index 1d4a3ed..0930f8d 100644
--- a/src/liballoc/tests/binary_heap.rs
+++ b/src/liballoc/tests/binary_heap.rs
@@ -282,7 +282,7 @@
//
// Destructors must be called exactly once per element.
#[test]
-#[cfg(not(miri))] // Miri does not support panics
+#[cfg(not(miri))] // Miri does not support panics nor entropy
fn panic_safe() {
static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0);
diff --git a/src/liballoc/tests/btree/map.rs b/src/liballoc/tests/btree/map.rs
index f147500..844afe8 100644
--- a/src/liballoc/tests/btree/map.rs
+++ b/src/liballoc/tests/btree/map.rs
@@ -226,7 +226,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_range_equal_excluded() {
let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
map.range((Excluded(2), Excluded(2)));
@@ -234,7 +233,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_range_backwards_1() {
let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
map.range((Included(3), Included(2)));
@@ -242,7 +240,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_range_backwards_2() {
let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
map.range((Included(3), Excluded(2)));
@@ -250,7 +247,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_range_backwards_3() {
let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
map.range((Excluded(3), Included(2)));
@@ -258,7 +254,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_range_backwards_4() {
let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
map.range((Excluded(3), Excluded(2)));
diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs
index feba46b..b54c128 100644
--- a/src/liballoc/tests/slice.rs
+++ b/src/liballoc/tests/slice.rs
@@ -258,7 +258,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_swap_remove_fail() {
let mut v = vec![1];
let _ = v.swap_remove(0);
@@ -632,7 +631,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_insert_oob() {
let mut a = vec![1, 2, 3];
a.insert(4, 5);
@@ -657,7 +655,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_remove_fail() {
let mut a = vec![1];
let _ = a.remove(0);
@@ -939,7 +936,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_windowsator_0() {
let v = &[1, 2, 3, 4];
let _it = v.windows(0);
@@ -964,7 +960,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_chunksator_0() {
let v = &[1, 2, 3, 4];
let _it = v.chunks(0);
@@ -989,7 +984,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_chunks_exactator_0() {
let v = &[1, 2, 3, 4];
let _it = v.chunks_exact(0);
@@ -1014,7 +1008,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_rchunksator_0() {
let v = &[1, 2, 3, 4];
let _it = v.rchunks(0);
@@ -1039,7 +1032,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_rchunks_exactator_0() {
let v = &[1, 2, 3, 4];
let _it = v.rchunks_exact(0);
@@ -1092,7 +1084,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_overflow_does_not_cause_segfault() {
let mut v = vec![];
v.reserve_exact(!0);
@@ -1102,7 +1093,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_overflow_does_not_cause_segfault_managed() {
let mut v = vec![Rc::new(1)];
v.reserve_exact(!0);
@@ -1278,7 +1268,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_mut_chunks_0() {
let mut v = [1, 2, 3, 4];
let _it = v.chunks_mut(0);
@@ -1311,7 +1300,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_mut_chunks_exact_0() {
let mut v = [1, 2, 3, 4];
let _it = v.chunks_exact_mut(0);
@@ -1344,7 +1332,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_mut_rchunks_0() {
let mut v = [1, 2, 3, 4];
let _it = v.rchunks_mut(0);
@@ -1377,7 +1364,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_mut_rchunks_exact_0() {
let mut v = [1, 2, 3, 4];
let _it = v.rchunks_exact_mut(0);
@@ -1411,7 +1397,7 @@
#[test]
#[allow(unused_must_use)] // here, we care about the side effects of `.clone()`
#[cfg_attr(target_os = "emscripten", ignore)]
-#[cfg(not(miri))] // Miri does not support panics
+#[cfg(not(miri))] // Miri does not support threads nor entropy
fn test_box_slice_clone_panics() {
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
@@ -1476,7 +1462,6 @@
#[test]
#[should_panic(expected = "destination and source slices have different lengths")]
-#[cfg(not(miri))] // Miri does not support panics
fn test_copy_from_slice_dst_longer() {
let src = [0, 1, 2, 3];
let mut dst = [0; 5];
@@ -1485,7 +1470,6 @@
#[test]
#[should_panic(expected = "destination and source slices have different lengths")]
-#[cfg(not(miri))] // Miri does not support panics
fn test_copy_from_slice_dst_shorter() {
let src = [0, 1, 2, 3];
let mut dst = [0; 3];
@@ -1605,7 +1589,7 @@
#[test]
#[cfg_attr(target_os = "emscripten", ignore)] // no threads
-#[cfg(not(miri))] // Miri does not support panics
+#[cfg(not(miri))] // Miri does not support threads nor entropy
fn panic_safe() {
let prev = panic::take_hook();
panic::set_hook(Box::new(move |info| {
diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs
index b33a564..b197516 100644
--- a/src/liballoc/tests/str.rs
+++ b/src/liballoc/tests/str.rs
@@ -7,7 +7,7 @@
assert!("" <= "");
assert!("" <= "foo");
assert!("foo" <= "foo");
- assert!("foo" != "bar");
+ assert_ne!("foo", "bar");
}
#[test]
@@ -351,7 +351,6 @@
// to be used in `should_panic`)
#[test]
#[should_panic(expected = "out of bounds")]
- #[cfg(not(miri))] // Miri does not support panics
fn assert_range_eq_can_fail_by_panic() {
assert_range_eq!("abc", 0..5, "abc");
}
@@ -361,7 +360,6 @@
// to be used in `should_panic`)
#[test]
#[should_panic(expected = "==")]
- #[cfg(not(miri))] // Miri does not support panics
fn assert_range_eq_can_fail_by_inequality() {
assert_range_eq!("abc", 0..2, "abc");
}
@@ -409,7 +407,6 @@
#[test]
#[should_panic(expected = $expect_msg)]
- #[cfg(not(miri))] // Miri does not support panics
fn index_fail() {
let v: String = $data.into();
let v: &str = &v;
@@ -418,7 +415,6 @@
#[test]
#[should_panic(expected = $expect_msg)]
- #[cfg(not(miri))] // Miri does not support panics
fn index_mut_fail() {
let mut v: String = $data.into();
let v: &mut str = &mut v;
@@ -514,7 +510,6 @@
#[test]
#[should_panic]
- #[cfg(not(miri))] // Miri does not support panics
fn test_slice_fail() {
&"中华Việt Nam"[0..2];
}
@@ -666,14 +661,12 @@
// check the panic includes the prefix of the sliced string
#[test]
#[should_panic(expected="byte index 1024 is out of bounds of `Lorem ipsum dolor sit amet")]
- #[cfg(not(miri))] // Miri does not support panics
fn test_slice_fail_truncated_1() {
&LOREM_PARAGRAPH[..1024];
}
// check the truncation in the panic message
#[test]
#[should_panic(expected="luctus, im`[...]")]
- #[cfg(not(miri))] // Miri does not support panics
fn test_slice_fail_truncated_2() {
&LOREM_PARAGRAPH[..1024];
}
@@ -688,7 +681,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_str_slice_rangetoinclusive_notok() {
let s = "abcαβγ";
&s[..=3];
@@ -704,7 +696,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_str_slicemut_rangetoinclusive_notok() {
let mut s = "abcαβγ".to_owned();
let s: &mut str = &mut s;
@@ -894,7 +885,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_as_bytes_fail() {
// Don't double free. (I'm not sure if this exercises the
// original problem code path anymore.)
@@ -984,7 +974,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_split_at_boundscheck() {
let s = "ศไทย中华Việt Nam";
s.split_at(1);
diff --git a/src/liballoc/tests/string.rs b/src/liballoc/tests/string.rs
index 7e93d84..7e75b8c 100644
--- a/src/liballoc/tests/string.rs
+++ b/src/liballoc/tests/string.rs
@@ -231,7 +231,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_split_off_past_end() {
let orig = "Hello, world!";
let mut split = String::from(orig);
@@ -240,7 +239,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_split_off_mid_char() {
let mut orig = String::from("山");
orig.split_off(1);
@@ -289,7 +287,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_str_truncate_split_codepoint() {
let mut s = String::from("\u{FC}"); // ü
s.truncate(1);
@@ -324,7 +321,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn remove_bad() {
"ศ".to_string().remove(1);
}
@@ -360,13 +356,11 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn insert_bad1() {
"".to_string().insert(1, 't');
}
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn insert_bad2() {
"ệ".to_string().insert(1, 't');
}
@@ -447,7 +441,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_replace_range_char_boundary() {
let mut s = "Hello, 世界!".to_owned();
s.replace_range(..8, "");
@@ -464,7 +457,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_replace_range_out_of_bounds() {
let mut s = String::from("12345");
s.replace_range(5..6, "789");
@@ -472,7 +464,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_replace_range_inclusive_out_of_bounds() {
let mut s = String::from("12345");
s.replace_range(5..=5, "789");
diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs
index 6e4ca1d..545332b 100644
--- a/src/liballoc/tests/vec.rs
+++ b/src/liballoc/tests/vec.rs
@@ -368,7 +368,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_vec_truncate_fail() {
struct BadElem(i32);
impl Drop for BadElem {
@@ -392,7 +391,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_index_out_of_bounds() {
let vec = vec![1, 2, 3];
let _ = vec[3];
@@ -400,7 +398,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_slice_out_of_bounds_1() {
let x = vec![1, 2, 3, 4, 5];
&x[!0..];
@@ -408,7 +405,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_slice_out_of_bounds_2() {
let x = vec![1, 2, 3, 4, 5];
&x[..6];
@@ -416,7 +412,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_slice_out_of_bounds_3() {
let x = vec![1, 2, 3, 4, 5];
&x[!0..4];
@@ -424,7 +419,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_slice_out_of_bounds_4() {
let x = vec![1, 2, 3, 4, 5];
&x[1..6];
@@ -432,7 +426,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_slice_out_of_bounds_5() {
let x = vec![1, 2, 3, 4, 5];
&x[3..2];
@@ -440,7 +433,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_swap_remove_empty() {
let mut vec = Vec::<i32>::new();
vec.swap_remove(0);
@@ -511,7 +503,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_drain_out_of_bounds() {
let mut v = vec![1, 2, 3, 4, 5];
v.drain(5..6);
@@ -585,7 +576,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_drain_inclusive_out_of_bounds() {
let mut v = vec![1, 2, 3, 4, 5];
v.drain(5..=5);
@@ -615,7 +605,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_splice_out_of_bounds() {
let mut v = vec![1, 2, 3, 4, 5];
let a = [10, 11, 12];
@@ -624,7 +613,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_splice_inclusive_out_of_bounds() {
let mut v = vec![1, 2, 3, 4, 5];
let a = [10, 11, 12];
diff --git a/src/liballoc/tests/vec_deque.rs b/src/liballoc/tests/vec_deque.rs
index 16ddc14..e0fe10a 100644
--- a/src/liballoc/tests/vec_deque.rs
+++ b/src/liballoc/tests/vec_deque.rs
@@ -108,7 +108,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_index_out_of_bounds() {
let mut deq = VecDeque::new();
for i in 1..4 {
diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs
index 8383d30..753f10e 100644
--- a/src/libcore/cell.rs
+++ b/src/libcore/cell.rs
@@ -1186,7 +1186,6 @@
/// # Examples
///
/// ```
- /// #![feature(refcell_map_split)]
/// use std::cell::{Ref, RefCell};
///
/// let cell = RefCell::new([1, 2, 3, 4]);
@@ -1195,7 +1194,7 @@
/// assert_eq!(*begin, [1, 2]);
/// assert_eq!(*end, [3, 4]);
/// ```
- #[unstable(feature = "refcell_map_split", issue = "51476")]
+ #[stable(feature = "refcell_map_split", since = "1.35.0")]
#[inline]
pub fn map_split<U: ?Sized, V: ?Sized, F>(orig: Ref<'b, T>, f: F) -> (Ref<'b, U>, Ref<'b, V>)
where F: FnOnce(&T) -> (&U, &V)
@@ -1268,7 +1267,6 @@
/// # Examples
///
/// ```
- /// #![feature(refcell_map_split)]
/// use std::cell::{RefCell, RefMut};
///
/// let cell = RefCell::new([1, 2, 3, 4]);
@@ -1279,7 +1277,7 @@
/// begin.copy_from_slice(&[4, 3]);
/// end.copy_from_slice(&[2, 1]);
/// ```
- #[unstable(feature = "refcell_map_split", issue = "51476")]
+ #[stable(feature = "refcell_map_split", since = "1.35.0")]
#[inline]
pub fn map_split<U: ?Sized, V: ?Sized, F>(
orig: RefMut<'b, T>, f: F
diff --git a/src/libcore/char/mod.rs b/src/libcore/char/mod.rs
index f3369c4..66839766 100644
--- a/src/libcore/char/mod.rs
+++ b/src/libcore/char/mod.rs
@@ -389,11 +389,17 @@
fn next(&mut self) -> Option<char> {
self.0.next()
}
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.0.size_hint()
+ }
}
#[stable(feature = "fused", since = "1.26.0")]
impl FusedIterator for ToLowercase {}
+#[stable(feature = "exact_size_case_mapping_iter", since = "1.35.0")]
+impl ExactSizeIterator for ToLowercase {}
+
/// Returns an iterator that yields the uppercase equivalent of a `char`.
///
/// This `struct` is created by the [`to_uppercase`] method on [`char`]. See
@@ -411,11 +417,17 @@
fn next(&mut self) -> Option<char> {
self.0.next()
}
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.0.size_hint()
+ }
}
#[stable(feature = "fused", since = "1.26.0")]
impl FusedIterator for ToUppercase {}
+#[stable(feature = "exact_size_case_mapping_iter", since = "1.35.0")]
+impl ExactSizeIterator for ToUppercase {}
+
#[derive(Debug, Clone)]
enum CaseMappingIter {
Three(char, char, char),
@@ -457,6 +469,16 @@
CaseMappingIter::Zero => None,
}
}
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ let size = match self {
+ CaseMappingIter::Three(..) => 3,
+ CaseMappingIter::Two(..) => 2,
+ CaseMappingIter::One(_) => 1,
+ CaseMappingIter::Zero => 0,
+ };
+ (size, Some(size))
+ }
}
impl fmt::Display for CaseMappingIter {
diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs
index 7de94d2..ea52b0e 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -72,7 +72,7 @@
/// }
///
/// impl PartialEq for Book {
-/// fn eq(&self, other: &Book) -> bool {
+/// fn eq(&self, other: &Self) -> bool {
/// self.isbn == other.isbn
/// }
/// }
@@ -233,7 +233,7 @@
/// format: BookFormat,
/// }
/// impl PartialEq for Book {
-/// fn eq(&self, other: &Book) -> bool {
+/// fn eq(&self, other: &Self) -> bool {
/// self.isbn == other.isbn
/// }
/// }
@@ -493,19 +493,19 @@
/// }
///
/// impl Ord for Person {
-/// fn cmp(&self, other: &Person) -> Ordering {
+/// fn cmp(&self, other: &Self) -> Ordering {
/// self.height.cmp(&other.height)
/// }
/// }
///
/// impl PartialOrd for Person {
-/// fn partial_cmp(&self, other: &Person) -> Option<Ordering> {
+/// fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
/// Some(self.cmp(other))
/// }
/// }
///
/// impl PartialEq for Person {
-/// fn eq(&self, other: &Person) -> bool {
+/// fn eq(&self, other: &Self) -> bool {
/// self.height == other.height
/// }
/// }
@@ -691,13 +691,13 @@
/// }
///
/// impl PartialOrd for Person {
-/// fn partial_cmp(&self, other: &Person) -> Option<Ordering> {
+/// fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
/// self.height.partial_cmp(&other.height)
/// }
/// }
///
/// impl PartialEq for Person {
-/// fn eq(&self, other: &Person) -> bool {
+/// fn eq(&self, other: &Self) -> bool {
/// self.height == other.height
/// }
/// }
diff --git a/src/libcore/ffi.rs b/src/libcore/ffi.rs
index d88793f..5cc9c25 100644
--- a/src/libcore/ffi.rs
+++ b/src/libcore/ffi.rs
@@ -79,9 +79,9 @@
all supported platforms",
issue = "44930")]
struct VaListImpl {
- stack: *mut (),
- gr_top: *mut (),
- vr_top: *mut (),
+ stack: *mut c_void,
+ gr_top: *mut c_void,
+ vr_top: *mut c_void,
gr_offs: i32,
vr_offs: i32,
}
@@ -98,8 +98,8 @@
gpr: u8,
fpr: u8,
reserved: u16,
- overflow_arg_area: *mut (),
- reg_save_area: *mut (),
+ overflow_arg_area: *mut c_void,
+ reg_save_area: *mut c_void,
}
/// x86_64 ABI implementation of a `va_list`.
@@ -113,8 +113,8 @@
struct VaListImpl {
gp_offset: i32,
fp_offset: i32,
- overflow_arg_area: *mut (),
- reg_save_area: *mut (),
+ overflow_arg_area: *mut c_void,
+ reg_save_area: *mut c_void,
}
/// A wrapper for a `va_list`
diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs
index d4ad22c..cccd51b 100644
--- a/src/libcore/iter/adapters/mod.rs
+++ b/src/libcore/iter/adapters/mod.rs
@@ -1198,7 +1198,7 @@
}
}
-/// An iterator that rejects elements while `predicate` is true.
+/// An iterator that rejects elements while `predicate` returns `true`.
///
/// This `struct` is created by the [`skip_while`] method on [`Iterator`]. See its
/// documentation for more.
@@ -1286,7 +1286,7 @@
impl<I, P> FusedIterator for SkipWhile<I, P>
where I: FusedIterator, P: FnMut(&I::Item) -> bool {}
-/// An iterator that only accepts elements while `predicate` is true.
+/// An iterator that only accepts elements while `predicate` returns `true`.
///
/// This `struct` is created by the [`take_while`] method on [`Iterator`]. See its
/// documentation for more.
diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs
index 5dcca7e..e6a616b 100644
--- a/src/libcore/iter/mod.rs
+++ b/src/libcore/iter/mod.rs
@@ -101,7 +101,7 @@
//! type Item = usize;
//!
//! // next() is the only required method
-//! fn next(&mut self) -> Option<usize> {
+//! fn next(&mut self) -> Option<Self::Item> {
//! // Increment our count. This is why we started at zero.
//! self.count += 1;
//!
diff --git a/src/libcore/iter/sources.rs b/src/libcore/iter/sources.rs
index 74ff7f4..ffc24df 100644
--- a/src/libcore/iter/sources.rs
+++ b/src/libcore/iter/sources.rs
@@ -39,8 +39,7 @@
/// Creates a new iterator that endlessly repeats a single element.
///
-/// The `repeat()` function repeats a single value over and over and over and
-/// over and over and 🔁.
+/// The `repeat()` function repeats a single value over and over again.
///
/// Infinite iterators like `repeat()` are often used with adapters like
/// [`take`], in order to make them finite.
@@ -128,8 +127,7 @@
/// Creates a new iterator that repeats elements of type `A` endlessly by
/// applying the provided closure, the repeater, `F: FnMut() -> A`.
///
-/// The `repeat_with()` function calls the repeater over and over and over and
-/// over and over and 🔁.
+/// The `repeat_with()` function calls the repeater over and over again.
///
/// Infinite iterators like `repeat_with()` are often used with adapters like
/// [`take`], in order to make them finite.
diff --git a/src/libcore/iter/traits/collect.rs b/src/libcore/iter/traits/collect.rs
index 5204f6a..cd61ab5 100644
--- a/src/libcore/iter/traits/collect.rs
+++ b/src/libcore/iter/traits/collect.rs
@@ -167,7 +167,7 @@
/// // and we'll implement IntoIterator
/// impl IntoIterator for MyCollection {
/// type Item = i32;
-/// type IntoIter = ::std::vec::IntoIter<i32>;
+/// type IntoIter = ::std::vec::IntoIter<Self::Item>;
///
/// fn into_iter(self) -> Self::IntoIter {
/// self.0.into_iter()
diff --git a/src/libcore/iter/traits/exact_size.rs b/src/libcore/iter/traits/exact_size.rs
index d6eab40..8fc4ac9 100644
--- a/src/libcore/iter/traits/exact_size.rs
+++ b/src/libcore/iter/traits/exact_size.rs
@@ -45,7 +45,7 @@
/// # }
/// # impl Iterator for Counter {
/// # type Item = usize;
-/// # fn next(&mut self) -> Option<usize> {
+/// # fn next(&mut self) -> Option<Self::Item> {
/// # self.count += 1;
/// # if self.count < 6 {
/// # Some(self.count)
diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs
index b052f59..d77936c 100644
--- a/src/libcore/macros.rs
+++ b/src/libcore/macros.rs
@@ -559,6 +559,65 @@
($($arg:tt)+) => (panic!("not yet implemented: {}", format_args!($($arg)*)));
}
+/// A standardized placeholder for marking unfinished code.
+///
+/// This can be useful if you are prototyping and are just looking to have your
+/// code typecheck. `todo!` works exactly like `unimplemented!`, there only
+/// difference between the two macros is the name.
+///
+/// # Panics
+///
+/// This will always [panic!](macro.panic.html)
+///
+/// # Examples
+///
+/// Here's an example of some in-progress code. We have a trait `Foo`:
+///
+/// ```
+/// trait Foo {
+/// fn bar(&self);
+/// fn baz(&self);
+/// }
+/// ```
+///
+/// We want to implement `Foo` on one of our types, but we also want to work on
+/// just `bar()` first. In order for our code to compile, we need to implement
+/// `baz()`, so we can use `todo!`:
+///
+/// ```
+/// #![feature(todo_macro)]
+///
+/// # trait Foo {
+/// # fn bar(&self);
+/// # fn baz(&self);
+/// # }
+/// struct MyStruct;
+///
+/// impl Foo for MyStruct {
+/// fn bar(&self) {
+/// // implementation goes here
+/// }
+///
+/// fn baz(&self) {
+/// // let's not worry about implementing baz() for now
+/// todo!();
+/// }
+/// }
+///
+/// fn main() {
+/// let s = MyStruct;
+/// s.bar();
+///
+/// // we aren't even using baz() yet, so this is fine.
+/// }
+/// ```
+#[macro_export]
+#[unstable(feature = "todo_macro", issue = "59277")]
+macro_rules! todo {
+ () => (panic!("not yet implemented"));
+ ($($arg:tt)+) => (panic!("not yet implemented: {}", format_args!($($arg)*)));
+}
+
/// A macro to create an array of [`MaybeUninit`]
///
/// This macro constructs an uninitialized array of the type `[MaybeUninit<K>; N]`.
diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs
index 90e84d0..3d2fcdc 100644
--- a/src/libcore/mem.rs
+++ b/src/libcore/mem.rs
@@ -1111,11 +1111,12 @@
/// ```
///
/// The compiler then knows to not make any incorrect assumptions or optimizations on this code.
+//
// FIXME before stabilizing, explain how to initialize a struct field-by-field.
#[allow(missing_debug_implementations)]
#[unstable(feature = "maybe_uninit", issue = "53491")]
#[derive(Copy)]
-// NOTE after stabilizing `MaybeUninit` proceed to deprecate `mem::uninitialized`.
+// NOTE: after stabilizing `MaybeUninit`, proceed to deprecate `mem::uninitialized`.
pub union MaybeUninit<T> {
uninit: (),
value: ManuallyDrop<T>,
@@ -1125,13 +1126,13 @@
impl<T: Copy> Clone for MaybeUninit<T> {
#[inline(always)]
fn clone(&self) -> Self {
- // Not calling T::clone(), we cannot know if we are initialized enough for that.
+ // Not calling `T::clone()`, we cannot know if we are initialized enough for that.
*self
}
}
impl<T> MaybeUninit<T> {
- /// Create a new `MaybeUninit<T>` initialized with the given value.
+ /// Creates a new `MaybeUninit<T>` initialized with the given value.
///
/// Note that dropping a `MaybeUninit<T>` will never call `T`'s drop code.
/// It is your responsibility to make sure `T` gets dropped if it got initialized.
@@ -1239,6 +1240,7 @@
/// let x_vec = unsafe { &*x.as_ptr() };
/// // We have created a reference to an uninitialized vector! This is undefined behavior.
/// ```
+ ///
/// (Notice that the rules around references to uninitialized data are not finalized yet, but
/// until they are, it is advisable to avoid them.)
#[unstable(feature = "maybe_uninit", issue = "53491")]
@@ -1277,6 +1279,7 @@
/// let x_vec = unsafe { &mut *x.as_mut_ptr() };
/// // We have created a reference to an uninitialized vector! This is undefined behavior.
/// ```
+ ///
/// (Notice that the rules around references to uninitialized data are not finalized yet, but
/// until they are, it is advisable to avoid them.)
#[unstable(feature = "maybe_uninit", issue = "53491")]
diff --git a/src/libcore/num/dec2flt/algorithm.rs b/src/libcore/num/dec2flt/algorithm.rs
index 3b57bb7..a83134a 100644
--- a/src/libcore/num/dec2flt/algorithm.rs
+++ b/src/libcore/num/dec2flt/algorithm.rs
@@ -326,7 +326,7 @@
round_by_remainder(v, rem, q, z)
}
-/// Skip over most Algorithm M iterations by checking the bit length.
+/// Skips over most Algorithm M iterations by checking the bit length.
fn quick_start<T: RawFloat>(u: &mut Big, v: &mut Big, k: &mut i16) {
// The bit length is an estimate of the base two logarithm, and log(u / v) = log(u) - log(v).
// The estimate is off by at most 1, but always an under-estimate, so the error on log(u)
diff --git a/src/libcore/num/dec2flt/mod.rs b/src/libcore/num/dec2flt/mod.rs
index 47ea5aa..d62cdae 100644
--- a/src/libcore/num/dec2flt/mod.rs
+++ b/src/libcore/num/dec2flt/mod.rs
@@ -304,8 +304,8 @@
}
}
-/// Quick and dirty upper bound on the size (log10) of the largest value that Algorithm R and
-/// Algorithm M will compute while working on the given decimal.
+/// Returns a quick-an-dirty upper bound on the size (log10) of the largest value that Algorithm R
+/// and Algorithm M will compute while working on the given decimal.
fn bound_intermediate_digits(decimal: &Decimal, e: i64) -> u64 {
// We don't need to worry too much about overflow here thanks to trivial_cases() and the
// parser, which filter out the most extreme inputs for us.
@@ -324,7 +324,7 @@
}
}
-/// Detect obvious overflows and underflows without even looking at the decimal digits.
+/// Detects obvious overflows and underflows without even looking at the decimal digits.
fn trivial_cases<T: RawFloat>(decimal: &Decimal) -> Option<T> {
// There were zeros but they were stripped by simplify()
if decimal.integral.is_empty() && decimal.fractional.is_empty() {
diff --git a/src/libcore/num/dec2flt/parse.rs b/src/libcore/num/dec2flt/parse.rs
index 933f8c1..f970595 100644
--- a/src/libcore/num/dec2flt/parse.rs
+++ b/src/libcore/num/dec2flt/parse.rs
@@ -78,7 +78,7 @@
}
}
-/// Carve off decimal digits up to the first non-digit character.
+/// Carves off decimal digits up to the first non-digit character.
fn eat_digits(s: &[u8]) -> (&[u8], &[u8]) {
let mut i = 0;
while i < s.len() && b'0' <= s[i] && s[i] <= b'9' {
diff --git a/src/libcore/num/flt2dec/decoder.rs b/src/libcore/num/flt2dec/decoder.rs
index a3bf783..a8da31d 100644
--- a/src/libcore/num/flt2dec/decoder.rs
+++ b/src/libcore/num/flt2dec/decoder.rs
@@ -10,7 +10,7 @@
///
/// - Any number from `(mant - minus) * 2^exp` to `(mant + plus) * 2^exp` will
/// round to the original value. The range is inclusive only when
-/// `inclusive` is true.
+/// `inclusive` is `true`.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct Decoded {
/// The scaled mantissa.
diff --git a/src/libcore/num/flt2dec/mod.rs b/src/libcore/num/flt2dec/mod.rs
index f9b46a1..defd424 100644
--- a/src/libcore/num/flt2dec/mod.rs
+++ b/src/libcore/num/flt2dec/mod.rs
@@ -315,15 +315,15 @@
}
}
-/// Formats given decimal digits `0.<...buf...> * 10^exp` into the exponential form
-/// with at least given number of significant digits. When `upper` is true,
+/// Formats the given decimal digits `0.<...buf...> * 10^exp` into the exponential
+/// form with at least the given number of significant digits. When `upper` is `true`,
/// the exponent will be prefixed by `E`; otherwise that's `e`. The result is
/// stored to the supplied parts array and a slice of written parts is returned.
///
/// `min_digits` can be less than the number of actual significant digits in `buf`;
/// it will be ignored and full digits will be printed. It is only used to print
-/// additional zeroes after rendered digits. Thus `min_digits` of 0 means that
-/// it will only print given digits and nothing else.
+/// additional zeroes after rendered digits. Thus, `min_digits == 0` means that
+/// it will only print the given digits and nothing else.
fn digits_to_exp_str<'a>(buf: &'a [u8], exp: i16, min_ndigits: usize, upper: bool,
parts: &'a mut [Part<'a>]) -> &'a [Part<'a>] {
assert!(!buf.is_empty());
@@ -384,7 +384,7 @@
}
}
-/// Formats given floating point number into the decimal form with at least
+/// Formats the given floating point number into the decimal form with at least
/// given number of fractional digits. The result is stored to the supplied parts
/// array while utilizing given byte buffer as a scratch. `upper` is currently
/// unused but left for the future decision to change the case of non-finite values,
@@ -438,7 +438,7 @@
}
}
-/// Formats given floating point number into the decimal form or
+/// Formats the given floating point number into the decimal form or
/// the exponential form, depending on the resulting exponent. The result is
/// stored to the supplied parts array while utilizing given byte buffer
/// as a scratch. `upper` is used to determine the case of non-finite values
@@ -497,7 +497,7 @@
}
}
-/// Returns rather crude approximation (upper bound) for the maximum buffer size
+/// Returns a rather crude approximation (upper bound) for the maximum buffer size
/// calculated from the given decoded exponent.
///
/// The exact limit is:
diff --git a/src/libcore/ops/arith.rs b/src/libcore/ops/arith.rs
index 0252ede..28c9ff9 100644
--- a/src/libcore/ops/arith.rs
+++ b/src/libcore/ops/arith.rs
@@ -1,6 +1,6 @@
/// The addition operator `+`.
///
-/// Note that `RHS` is `Self` by default, but this is not mandatory. For
+/// Note that `Rhs` is `Self` by default, but this is not mandatory. For
/// example, [`std::time::SystemTime`] implements `Add<Duration>`, which permits
/// operations of the form `SystemTime = SystemTime + Duration`.
///
@@ -20,10 +20,10 @@
/// }
///
/// impl Add for Point {
-/// type Output = Point;
+/// type Output = Self;
///
-/// fn add(self, other: Point) -> Point {
-/// Point {
+/// fn add(self, other: Self) -> Self {
+/// Self {
/// x: self.x + other.x,
/// y: self.y + other.y,
/// }
@@ -50,10 +50,10 @@
///
/// // Notice that the implementation uses the associated type `Output`.
/// impl<T: Add<Output = T>> Add for Point<T> {
-/// type Output = Point<T>;
+/// type Output = Self;
///
-/// fn add(self, other: Point<T>) -> Point<T> {
-/// Point {
+/// fn add(self, other: Self) -> Self::Output {
+/// Self {
/// x: self.x + other.x,
/// y: self.y + other.y,
/// }
@@ -67,18 +67,18 @@
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_on_unimplemented(
on(
- all(_Self="{integer}", RHS="{float}"),
+ all(_Self="{integer}", Rhs="{float}"),
message="cannot add a float to an integer",
),
on(
- all(_Self="{float}", RHS="{integer}"),
+ all(_Self="{float}", Rhs="{integer}"),
message="cannot add an integer to a float",
),
- message="cannot add `{RHS}` to `{Self}`",
- label="no implementation for `{Self} + {RHS}`",
+ message="cannot add `{Rhs}` to `{Self}`",
+ label="no implementation for `{Self} + {Rhs}`",
)]
#[doc(alias = "+")]
-pub trait Add<RHS=Self> {
+pub trait Add<Rhs=Self> {
/// The resulting type after applying the `+` operator.
#[stable(feature = "rust1", since = "1.0.0")]
type Output;
@@ -86,7 +86,7 @@
/// Performs the `+` operation.
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
- fn add(self, rhs: RHS) -> Self::Output;
+ fn add(self, rhs: Rhs) -> Self::Output;
}
macro_rules! add_impl {
@@ -108,7 +108,7 @@
/// The subtraction operator `-`.
///
-/// Note that `RHS` is `Self` by default, but this is not mandatory. For
+/// Note that `Rhs` is `Self` by default, but this is not mandatory. For
/// example, [`std::time::SystemTime`] implements `Sub<Duration>`, which permits
/// operations of the form `SystemTime = SystemTime - Duration`.
///
@@ -158,9 +158,9 @@
///
/// // Notice that the implementation uses the associated type `Output`.
/// impl<T: Sub<Output = T>> Sub for Point<T> {
-/// type Output = Point<T>;
+/// type Output = Self;
///
-/// fn sub(self, other: Point<T>) -> Point<T> {
+/// fn sub(self, other: Self) -> Self::Output {
/// Point {
/// x: self.x - other.x,
/// y: self.y - other.y,
@@ -173,10 +173,10 @@
/// ```
#[lang = "sub"]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented(message="cannot subtract `{RHS}` from `{Self}`",
- label="no implementation for `{Self} - {RHS}`")]
+#[rustc_on_unimplemented(message="cannot subtract `{Rhs}` from `{Self}`",
+ label="no implementation for `{Self} - {Rhs}`")]
#[doc(alias = "-")]
-pub trait Sub<RHS=Self> {
+pub trait Sub<Rhs=Self> {
/// The resulting type after applying the `-` operator.
#[stable(feature = "rust1", since = "1.0.0")]
type Output;
@@ -184,7 +184,7 @@
/// Performs the `-` operation.
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
- fn sub(self, rhs: RHS) -> Self::Output;
+ fn sub(self, rhs: Rhs) -> Self::Output;
}
macro_rules! sub_impl {
@@ -206,7 +206,7 @@
/// The multiplication operator `*`.
///
-/// Note that `RHS` is `Self` by default, but this is not mandatory.
+/// Note that `Rhs` is `Self` by default, but this is not mandatory.
///
/// # Examples
///
@@ -280,9 +280,9 @@
/// struct Vector { value: Vec<usize> }
///
/// impl Mul<Scalar> for Vector {
-/// type Output = Vector;
+/// type Output = Self;
///
-/// fn mul(self, rhs: Scalar) -> Vector {
+/// fn mul(self, rhs: Scalar) -> Self::Output {
/// Vector { value: self.value.iter().map(|v| v * rhs.value).collect() }
/// }
/// }
@@ -293,10 +293,10 @@
/// ```
#[lang = "mul"]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented(message="cannot multiply `{RHS}` to `{Self}`",
- label="no implementation for `{Self} * {RHS}`")]
+#[rustc_on_unimplemented(message="cannot multiply `{Rhs}` to `{Self}`",
+ label="no implementation for `{Self} * {Rhs}`")]
#[doc(alias = "*")]
-pub trait Mul<RHS=Self> {
+pub trait Mul<Rhs=Self> {
/// The resulting type after applying the `*` operator.
#[stable(feature = "rust1", since = "1.0.0")]
type Output;
@@ -304,7 +304,7 @@
/// Performs the `*` operation.
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
- fn mul(self, rhs: RHS) -> Self::Output;
+ fn mul(self, rhs: Rhs) -> Self::Output;
}
macro_rules! mul_impl {
@@ -326,7 +326,7 @@
/// The division operator `/`.
///
-/// Note that `RHS` is `Self` by default, but this is not mandatory.
+/// Note that `Rhs` is `Self` by default, but this is not mandatory.
///
/// # Examples
///
@@ -364,7 +364,7 @@
/// // The division of rational numbers is a closed operation.
/// type Output = Self;
///
-/// fn div(self, rhs: Self) -> Self {
+/// fn div(self, rhs: Self) -> Self::Output {
/// if rhs.nominator == 0 {
/// panic!("Cannot divide by zero-valued `Rational`!");
/// }
@@ -404,9 +404,9 @@
/// struct Vector { value: Vec<f32> }
///
/// impl Div<Scalar> for Vector {
-/// type Output = Vector;
+/// type Output = Self;
///
-/// fn div(self, rhs: Scalar) -> Vector {
+/// fn div(self, rhs: Scalar) -> Self::Output {
/// Vector { value: self.value.iter().map(|v| v / rhs.value).collect() }
/// }
/// }
@@ -417,10 +417,10 @@
/// ```
#[lang = "div"]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented(message="cannot divide `{Self}` by `{RHS}`",
- label="no implementation for `{Self} / {RHS}`")]
+#[rustc_on_unimplemented(message="cannot divide `{Self}` by `{Rhs}`",
+ label="no implementation for `{Self} / {Rhs}`")]
#[doc(alias = "/")]
-pub trait Div<RHS=Self> {
+pub trait Div<Rhs=Self> {
/// The resulting type after applying the `/` operator.
#[stable(feature = "rust1", since = "1.0.0")]
type Output;
@@ -428,7 +428,7 @@
/// Performs the `/` operation.
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
- fn div(self, rhs: RHS) -> Self::Output;
+ fn div(self, rhs: Rhs) -> Self::Output;
}
macro_rules! div_impl_integer {
@@ -467,7 +467,7 @@
/// The remainder operator `%`.
///
-/// Note that `RHS` is `Self` by default, but this is not mandatory.
+/// Note that `Rhs` is `Self` by default, but this is not mandatory.
///
/// # Examples
///
@@ -485,9 +485,9 @@
/// }
///
/// impl<'a, T> Rem<usize> for SplitSlice<'a, T> {
-/// type Output = SplitSlice<'a, T>;
+/// type Output = Self;
///
-/// fn rem(self, modulus: usize) -> Self {
+/// fn rem(self, modulus: usize) -> Self::Output {
/// let len = self.slice.len();
/// let rem = len % modulus;
/// let start = len - rem;
@@ -502,10 +502,10 @@
/// ```
#[lang = "rem"]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented(message="cannot mod `{Self}` by `{RHS}`",
- label="no implementation for `{Self} % {RHS}`")]
+#[rustc_on_unimplemented(message="cannot mod `{Self}` by `{Rhs}`",
+ label="no implementation for `{Self} % {Rhs}`")]
#[doc(alias = "%")]
-pub trait Rem<RHS=Self> {
+pub trait Rem<Rhs=Self> {
/// The resulting type after applying the `%` operator.
#[stable(feature = "rust1", since = "1.0.0")]
type Output = Self;
@@ -513,7 +513,7 @@
/// Performs the `%` operation.
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
- fn rem(self, rhs: RHS) -> Self::Output;
+ fn rem(self, rhs: Rhs) -> Self::Output;
}
macro_rules! rem_impl_integer {
@@ -571,7 +571,7 @@
/// impl Neg for Sign {
/// type Output = Sign;
///
-/// fn neg(self) -> Sign {
+/// fn neg(self) -> Self::Output {
/// match self {
/// Sign::Negative => Sign::Positive,
/// Sign::Zero => Sign::Zero,
@@ -650,8 +650,8 @@
/// }
///
/// impl AddAssign for Point {
-/// fn add_assign(&mut self, other: Point) {
-/// *self = Point {
+/// fn add_assign(&mut self, other: Self) {
+/// *self = Self {
/// x: self.x + other.x,
/// y: self.y + other.y,
/// };
@@ -706,8 +706,8 @@
/// }
///
/// impl SubAssign for Point {
-/// fn sub_assign(&mut self, other: Point) {
-/// *self = Point {
+/// fn sub_assign(&mut self, other: Self) {
+/// *self = Self {
/// x: self.x - other.x,
/// y: self.y - other.y,
/// };
diff --git a/src/libcore/ops/bit.rs b/src/libcore/ops/bit.rs
index 2c9bf24..a8f862f 100644
--- a/src/libcore/ops/bit.rs
+++ b/src/libcore/ops/bit.rs
@@ -17,7 +17,7 @@
/// impl Not for Answer {
/// type Output = Answer;
///
-/// fn not(self) -> Answer {
+/// fn not(self) -> Self::Output {
/// match self {
/// Answer::Yes => Answer::No,
/// Answer::No => Answer::Yes
@@ -59,7 +59,7 @@
/// The bitwise AND operator `&`.
///
-/// Note that `RHS` is `Self` by default, but this is not mandatory.
+/// Note that `Rhs` is `Self` by default, but this is not mandatory.
///
/// # Examples
///
@@ -75,7 +75,7 @@
/// type Output = Self;
///
/// // rhs is the "right-hand side" of the expression `a & b`
-/// fn bitand(self, rhs: Self) -> Self {
+/// fn bitand(self, rhs: Self) -> Self::Output {
/// Scalar(self.0 & rhs.0)
/// }
/// }
@@ -97,7 +97,7 @@
/// impl BitAnd for BooleanVector {
/// type Output = Self;
///
-/// fn bitand(self, BooleanVector(rhs): Self) -> Self {
+/// fn bitand(self, BooleanVector(rhs): Self) -> Self::Output {
/// let BooleanVector(lhs) = self;
/// assert_eq!(lhs.len(), rhs.len());
/// BooleanVector(lhs.iter().zip(rhs.iter()).map(|(x, y)| *x && *y).collect())
@@ -112,9 +112,9 @@
#[lang = "bitand"]
#[doc(alias = "&")]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented(message="no implementation for `{Self} & {RHS}`",
- label="no implementation for `{Self} & {RHS}`")]
-pub trait BitAnd<RHS=Self> {
+#[rustc_on_unimplemented(message="no implementation for `{Self} & {Rhs}`",
+ label="no implementation for `{Self} & {Rhs}`")]
+pub trait BitAnd<Rhs=Self> {
/// The resulting type after applying the `&` operator.
#[stable(feature = "rust1", since = "1.0.0")]
type Output;
@@ -122,7 +122,7 @@
/// Performs the `&` operation.
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
- fn bitand(self, rhs: RHS) -> Self::Output;
+ fn bitand(self, rhs: Rhs) -> Self::Output;
}
macro_rules! bitand_impl {
@@ -143,7 +143,7 @@
/// The bitwise OR operator `|`.
///
-/// Note that `RHS` is `Self` by default, but this is not mandatory.
+/// Note that `Rhs` is `Self` by default, but this is not mandatory.
///
/// # Examples
///
@@ -181,7 +181,7 @@
/// impl BitOr for BooleanVector {
/// type Output = Self;
///
-/// fn bitor(self, BooleanVector(rhs): Self) -> Self {
+/// fn bitor(self, BooleanVector(rhs): Self) -> Self::Output {
/// let BooleanVector(lhs) = self;
/// assert_eq!(lhs.len(), rhs.len());
/// BooleanVector(lhs.iter().zip(rhs.iter()).map(|(x, y)| *x || *y).collect())
@@ -196,9 +196,9 @@
#[lang = "bitor"]
#[doc(alias = "|")]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented(message="no implementation for `{Self} | {RHS}`",
- label="no implementation for `{Self} | {RHS}`")]
-pub trait BitOr<RHS=Self> {
+#[rustc_on_unimplemented(message="no implementation for `{Self} | {Rhs}`",
+ label="no implementation for `{Self} | {Rhs}`")]
+pub trait BitOr<Rhs=Self> {
/// The resulting type after applying the `|` operator.
#[stable(feature = "rust1", since = "1.0.0")]
type Output;
@@ -206,7 +206,7 @@
/// Performs the `|` operation.
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
- fn bitor(self, rhs: RHS) -> Self::Output;
+ fn bitor(self, rhs: Rhs) -> Self::Output;
}
macro_rules! bitor_impl {
@@ -227,7 +227,7 @@
/// The bitwise XOR operator `^`.
///
-/// Note that `RHS` is `Self` by default, but this is not mandatory.
+/// Note that `Rhs` is `Self` by default, but this is not mandatory.
///
/// # Examples
///
@@ -243,7 +243,7 @@
/// type Output = Self;
///
/// // rhs is the "right-hand side" of the expression `a ^ b`
-/// fn bitxor(self, rhs: Self) -> Self {
+/// fn bitxor(self, rhs: Self) -> Self::Output {
/// Scalar(self.0 ^ rhs.0)
/// }
/// }
@@ -265,7 +265,7 @@
/// impl BitXor for BooleanVector {
/// type Output = Self;
///
-/// fn bitxor(self, BooleanVector(rhs): Self) -> Self {
+/// fn bitxor(self, BooleanVector(rhs): Self) -> Self::Output {
/// let BooleanVector(lhs) = self;
/// assert_eq!(lhs.len(), rhs.len());
/// BooleanVector(lhs.iter()
@@ -283,9 +283,9 @@
#[lang = "bitxor"]
#[doc(alias = "^")]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented(message="no implementation for `{Self} ^ {RHS}`",
- label="no implementation for `{Self} ^ {RHS}`")]
-pub trait BitXor<RHS=Self> {
+#[rustc_on_unimplemented(message="no implementation for `{Self} ^ {Rhs}`",
+ label="no implementation for `{Self} ^ {Rhs}`")]
+pub trait BitXor<Rhs=Self> {
/// The resulting type after applying the `^` operator.
#[stable(feature = "rust1", since = "1.0.0")]
type Output;
@@ -293,7 +293,7 @@
/// Performs the `^` operation.
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
- fn bitxor(self, rhs: RHS) -> Self::Output;
+ fn bitxor(self, rhs: Rhs) -> Self::Output;
}
macro_rules! bitxor_impl {
@@ -355,7 +355,7 @@
/// impl<T: Clone> Shl<usize> for SpinVector<T> {
/// type Output = Self;
///
-/// fn shl(self, rhs: usize) -> SpinVector<T> {
+/// fn shl(self, rhs: usize) -> Self::Output {
/// // Rotate the vector by `rhs` places.
/// let (a, b) = self.vec.split_at(rhs);
/// let mut spun_vector: Vec<T> = vec![];
@@ -371,9 +371,9 @@
#[lang = "shl"]
#[doc(alias = "<<")]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented(message="no implementation for `{Self} << {RHS}`",
- label="no implementation for `{Self} << {RHS}`")]
-pub trait Shl<RHS=Self> {
+#[rustc_on_unimplemented(message="no implementation for `{Self} << {Rhs}`",
+ label="no implementation for `{Self} << {Rhs}`")]
+pub trait Shl<Rhs=Self> {
/// The resulting type after applying the `<<` operator.
#[stable(feature = "rust1", since = "1.0.0")]
type Output;
@@ -381,7 +381,7 @@
/// Performs the `<<` operation.
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
- fn shl(self, rhs: RHS) -> Self::Output;
+ fn shl(self, rhs: Rhs) -> Self::Output;
}
macro_rules! shl_impl {
@@ -464,7 +464,7 @@
/// impl<T: Clone> Shr<usize> for SpinVector<T> {
/// type Output = Self;
///
-/// fn shr(self, rhs: usize) -> SpinVector<T> {
+/// fn shr(self, rhs: usize) -> Self::Output {
/// // Rotate the vector by `rhs` places.
/// let (a, b) = self.vec.split_at(self.vec.len() - rhs);
/// let mut spun_vector: Vec<T> = vec![];
@@ -480,9 +480,9 @@
#[lang = "shr"]
#[doc(alias = ">>")]
#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_on_unimplemented(message="no implementation for `{Self} >> {RHS}`",
- label="no implementation for `{Self} >> {RHS}`")]
-pub trait Shr<RHS=Self> {
+#[rustc_on_unimplemented(message="no implementation for `{Self} >> {Rhs}`",
+ label="no implementation for `{Self} >> {Rhs}`")]
+pub trait Shr<Rhs=Self> {
/// The resulting type after applying the `>>` operator.
#[stable(feature = "rust1", since = "1.0.0")]
type Output;
@@ -490,7 +490,7 @@
/// Performs the `>>` operation.
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
- fn shr(self, rhs: RHS) -> Self::Output;
+ fn shr(self, rhs: Rhs) -> Self::Output;
}
macro_rules! shr_impl {
diff --git a/src/libcore/ops/deref.rs b/src/libcore/ops/deref.rs
index eb76c2d..e44a6c4 100644
--- a/src/libcore/ops/deref.rs
+++ b/src/libcore/ops/deref.rs
@@ -49,7 +49,7 @@
/// impl<T> Deref for DerefExample<T> {
/// type Target = T;
///
-/// fn deref(&self) -> &T {
+/// fn deref(&self) -> &Self::Target {
/// &self.value
/// }
/// }
@@ -139,13 +139,13 @@
/// impl<T> Deref for DerefMutExample<T> {
/// type Target = T;
///
-/// fn deref(&self) -> &T {
+/// fn deref(&self) -> &Self::Target {
/// &self.value
/// }
/// }
///
/// impl<T> DerefMut for DerefMutExample<T> {
-/// fn deref_mut(&mut self) -> &mut T {
+/// fn deref_mut(&mut self) -> &mut Self::Target {
/// &mut self.value
/// }
/// }
diff --git a/src/libcore/ops/index.rs b/src/libcore/ops/index.rs
index d4ed861..3158f58 100644
--- a/src/libcore/ops/index.rs
+++ b/src/libcore/ops/index.rs
@@ -33,7 +33,7 @@
/// impl Index<Nucleotide> for NucleotideCount {
/// type Output = usize;
///
-/// fn index(&self, nucleotide: Nucleotide) -> &usize {
+/// fn index(&self, nucleotide: Nucleotide) -> &Self::Output {
/// match nucleotide {
/// Nucleotide::A => &self.a,
/// Nucleotide::C => &self.c,
@@ -105,7 +105,7 @@
/// impl Index<Side> for Balance {
/// type Output = Weight;
///
-/// fn index<'a>(&'a self, index: Side) -> &'a Weight {
+/// fn index<'a>(&'a self, index: Side) -> &'a Self::Output {
/// println!("Accessing {:?}-side of balance immutably", index);
/// match index {
/// Side::Left => &self.left,
@@ -115,7 +115,7 @@
/// }
///
/// impl IndexMut<Side> for Balance {
-/// fn index_mut<'a>(&'a mut self, index: Side) -> &'a mut Weight {
+/// fn index_mut<'a>(&'a mut self, index: Side) -> &'a mut Self::Output {
/// println!("Accessing {:?}-side of balance mutably", index);
/// match index {
/// Side::Left => &mut self.left,
diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs
index 81a8d00..4f71c8e 100644
--- a/src/libcore/ops/range.rs
+++ b/src/libcore/ops/range.rs
@@ -71,7 +71,7 @@
/// assert_eq!(arr[1..=3], [ 1,2,3 ]);
/// ```
#[doc(alias = "..")]
-#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186
+#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Range<Idx> {
/// The lower bound of the range (inclusive).
@@ -95,8 +95,6 @@
/// # Examples
///
/// ```
- /// #![feature(range_contains)]
- ///
/// use std::f32;
///
/// assert!(!(3..5).contains(&2));
@@ -112,7 +110,7 @@
/// assert!(!(0.0..f32::NAN).contains(&0.5));
/// assert!(!(f32::NAN..1.0).contains(&0.5));
/// ```
- #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
+ #[stable(feature = "range_contains", since = "1.35.0")]
pub fn contains<U>(&self, item: &U) -> bool
where
Idx: PartialOrd<U>,
@@ -175,7 +173,7 @@
///
/// [`Iterator`]: ../iter/trait.IntoIterator.html
#[doc(alias = "..")]
-#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186
+#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186
#[stable(feature = "rust1", since = "1.0.0")]
pub struct RangeFrom<Idx> {
/// The lower bound of the range (inclusive).
@@ -196,8 +194,6 @@
/// # Examples
///
/// ```
- /// #![feature(range_contains)]
- ///
/// use std::f32;
///
/// assert!(!(3..).contains(&2));
@@ -208,7 +204,7 @@
/// assert!(!(0.0..).contains(&f32::NAN));
/// assert!(!(f32::NAN..).contains(&0.5));
/// ```
- #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
+ #[stable(feature = "range_contains", since = "1.35.0")]
pub fn contains<U>(&self, item: &U) -> bool
where
Idx: PartialOrd<U>,
@@ -280,8 +276,6 @@
/// # Examples
///
/// ```
- /// #![feature(range_contains)]
- ///
/// use std::f32;
///
/// assert!( (..5).contains(&-1_000_000_000));
@@ -292,7 +286,7 @@
/// assert!(!(..1.0).contains(&f32::NAN));
/// assert!(!(..f32::NAN).contains(&0.5));
/// ```
- #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
+ #[stable(feature = "range_contains", since = "1.35.0")]
pub fn contains<U>(&self, item: &U) -> bool
where
Idx: PartialOrd<U>,
@@ -329,7 +323,7 @@
/// assert_eq!(arr[1..=3], [ 1,2,3 ]); // RangeInclusive
/// ```
#[doc(alias = "..=")]
-#[derive(Clone)] // not Copy -- see #27186
+#[derive(Clone)] // not Copy -- see #27186
#[stable(feature = "inclusive_range", since = "1.26.0")]
pub struct RangeInclusive<Idx> {
pub(crate) start: Idx,
@@ -365,7 +359,8 @@
impl<Idx: PartialEq> PartialEq for RangeInclusive<Idx> {
#[inline]
fn eq(&self, other: &Self) -> bool {
- self.start == other.start && self.end == other.end
+ self.start == other.start
+ && self.end == other.end
&& RangeInclusiveEquality::canonicalized_is_empty(self)
== RangeInclusiveEquality::canonicalized_is_empty(other)
}
@@ -397,7 +392,11 @@
#[inline]
#[rustc_promotable]
pub const fn new(start: Idx, end: Idx) -> Self {
- Self { start, end, is_empty: None }
+ Self {
+ start,
+ end,
+ is_empty: None,
+ }
}
/// Returns the lower bound of the range (inclusive).
@@ -478,8 +477,6 @@
/// # Examples
///
/// ```
- /// #![feature(range_contains)]
- ///
/// use std::f32;
///
/// assert!(!(3..=5).contains(&2));
@@ -496,7 +493,7 @@
/// assert!(!(0.0..=f32::NAN).contains(&0.0));
/// assert!(!(f32::NAN..=1.0).contains(&1.0));
/// ```
- #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
+ #[stable(feature = "range_contains", since = "1.35.0")]
pub fn contains<U>(&self, item: &U) -> bool
where
Idx: PartialOrd<U>,
@@ -609,15 +606,12 @@
}
}
-#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
impl<Idx: PartialOrd<Idx>> RangeToInclusive<Idx> {
/// Returns `true` if `item` is contained in the range.
///
/// # Examples
///
/// ```
- /// #![feature(range_contains)]
- ///
/// use std::f32;
///
/// assert!( (..=5).contains(&-1_000_000_000));
@@ -628,7 +622,7 @@
/// assert!(!(..=1.0).contains(&f32::NAN));
/// assert!(!(..=f32::NAN).contains(&0.5));
/// ```
- #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
+ #[stable(feature = "range_contains", since = "1.35.0")]
pub fn contains<U>(&self, item: &U) -> bool
where
Idx: PartialOrd<U>,
@@ -730,14 +724,11 @@
#[stable(feature = "collections_range", since = "1.28.0")]
fn end_bound(&self) -> Bound<&T>;
-
/// Returns `true` if `item` is contained in the range.
///
/// # Examples
///
/// ```
- /// #![feature(range_contains)]
- ///
/// use std::f32;
///
/// assert!( (3..5).contains(&4));
@@ -747,7 +738,7 @@
/// assert!(!(0.0..1.0).contains(&f32::NAN));
/// assert!(!(0.0..f32::NAN).contains(&0.5));
/// assert!(!(f32::NAN..1.0).contains(&0.5));
- #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
+ #[stable(feature = "range_contains", since = "1.35.0")]
fn contains<U>(&self, item: &U) -> bool
where
T: PartialOrd<U>,
@@ -757,9 +748,7 @@
Included(ref start) => *start <= item,
Excluded(ref start) => *start < item,
Unbounded => true,
- })
- &&
- (match self.end_bound() {
+ }) && (match self.end_bound() {
Included(ref end) => item <= *end,
Excluded(ref end) => item < *end,
Unbounded => true,
@@ -835,7 +824,7 @@
match *self {
(Included(ref start), _) => Included(start),
(Excluded(ref start), _) => Excluded(start),
- (Unbounded, _) => Unbounded,
+ (Unbounded, _) => Unbounded,
}
}
@@ -843,7 +832,7 @@
match *self {
(_, Included(ref end)) => Included(end),
(_, Excluded(ref end)) => Excluded(end),
- (_, Unbounded) => Unbounded,
+ (_, Unbounded) => Unbounded,
}
}
}
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index 46dfe28..dfc3884 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -210,7 +210,7 @@
// Adapter for working with references
/////////////////////////////////////////////////////////////////////////
- /// Converts from `Option<T>` to `Option<&T>`.
+ /// Converts from `&Option<T>` to `Option<&T>`.
///
/// # Examples
///
@@ -239,7 +239,7 @@
}
}
- /// Converts from `Option<T>` to `Option<&mut T>`.
+ /// Converts from `&mut Option<T>` to `Option<&mut T>`.
///
/// # Examples
///
@@ -881,15 +881,13 @@
/// # Examples
///
/// ```
- /// #![feature(copied)]
- ///
/// let x = 12;
/// let opt_x = Some(&x);
/// assert_eq!(opt_x, Some(&12));
/// let copied = opt_x.copied();
/// assert_eq!(copied, Some(12));
/// ```
- #[unstable(feature = "copied", issue = "57126")]
+ #[stable(feature = "copied", since = "1.35.0")]
pub fn copied(self) -> Option<T> {
self.map(|&t| t)
}
@@ -902,15 +900,13 @@
/// # Examples
///
/// ```
- /// #![feature(copied)]
- ///
/// let mut x = 12;
/// let opt_x = Some(&mut x);
/// assert_eq!(opt_x, Some(&mut 12));
/// let copied = opt_x.copied();
/// assert_eq!(copied, Some(12));
/// ```
- #[unstable(feature = "copied", issue = "57126")]
+ #[stable(feature = "copied", since = "1.35.0")]
pub fn copied(self) -> Option<T> {
self.map(|&mut t| t)
}
diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs
index fb78f5e..57bd3ed 100644
--- a/src/libcore/pin.rs
+++ b/src/libcore/pin.rs
@@ -1,4 +1,4 @@
-//! Types which pin data to its location in memory
+//! Types that pin data to its location in memory.
//!
//! It is sometimes useful to have objects that are guaranteed to not move,
//! in the sense that their placement in memory does not change, and can thus be relied upon.
@@ -109,7 +109,7 @@
//! assert_eq!(still_unmoved.slice, NonNull::from(&still_unmoved.data));
//!
//! // Since our type doesn't implement Unpin, this will fail to compile:
-//! // let new_unmoved = Unmovable::new("world".to_string());
+//! // let mut new_unmoved = Unmovable::new("world".to_string());
//! // std::mem::swap(&mut *still_unmoved, &mut *new_unmoved);
//! ```
//!
diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index 2bd6b53..967f7e3 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -369,7 +369,7 @@
// Adapter for working with references
/////////////////////////////////////////////////////////////////////////
- /// Converts from `Result<T, E>` to `Result<&T, &E>`.
+ /// Converts from `&Result<T, E>` to `Result<&T, &E>`.
///
/// Produces a new `Result`, containing a reference
/// into the original, leaving the original in place.
@@ -394,7 +394,7 @@
}
}
- /// Converts from `Result<T, E>` to `Result<&mut T, &mut E>`.
+ /// Converts from `&mut Result<T, E>` to `Result<&mut T, &mut E>`.
///
/// # Examples
///
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index 53334ad..528281d 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -2968,7 +2968,7 @@
///
/// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
/// allows a reverse search and forward/reverse search yields the same
- /// elements. This is true for, eg, [`char`] but not for `&str`.
+ /// elements. This is true for, e.g., [`char`], but not for `&str`.
///
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
///
@@ -3143,7 +3143,7 @@
///
/// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
/// allows a reverse search and forward/reverse search yields the same
- /// elements. This is true for, eg, [`char`] but not for `&str`.
+ /// elements. This is true for, e.g., [`char`], but not for `&str`.
///
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
///
@@ -3326,7 +3326,7 @@
///
/// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
/// allows a reverse search and forward/reverse search yields the same
- /// elements. This is true for, eg, [`char`] but not for `&str`.
+ /// elements. This is true for, e.g., [`char`], but not for `&str`.
///
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
///
@@ -3402,7 +3402,7 @@
///
/// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
/// allows a reverse search and forward/reverse search yields the same
- /// elements. This is true for, eg, [`char`] but not for `&str`.
+ /// elements. This is true for, e.g., [`char`], but not for `&str`.
///
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
///
diff --git a/src/libcore/task/wake.rs b/src/libcore/task/wake.rs
index 21f0a8c..12f812d 100644
--- a/src/libcore/task/wake.rs
+++ b/src/libcore/task/wake.rs
@@ -108,7 +108,7 @@
unsafe { (self.waker.vtable.wake)(self.waker.data) }
}
- /// Returns whether or not this `Waker` and other `Waker` have awaken the same task.
+ /// Returns `true` if this `Waker` and another `Waker` have awoken the same task.
///
/// This function works on a best-effort basis, and may return false even
/// when the `Waker`s would awaken the same task. However, if this function
diff --git a/src/libcore/tests/cell.rs b/src/libcore/tests/cell.rs
index b164160..7bd7d18 100644
--- a/src/libcore/tests/cell.rs
+++ b/src/libcore/tests/cell.rs
@@ -5,15 +5,15 @@
#[test]
fn smoketest_cell() {
let x = Cell::new(10);
- assert!(x == Cell::new(10));
- assert!(x.get() == 10);
+ assert_eq!(x, Cell::new(10));
+ assert_eq!(x.get(), 10);
x.set(20);
- assert!(x == Cell::new(20));
- assert!(x.get() == 20);
+ assert_eq!(x, Cell::new(20));
+ assert_eq!(x.get(), 20);
let y = Cell::new((30, 40));
- assert!(y == Cell::new((30, 40)));
- assert!(y.get() == (30, 40));
+ assert_eq!(y, Cell::new((30, 40)));
+ assert_eq!(y.get(), (30, 40));
}
#[test]
@@ -109,7 +109,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn discard_doesnt_unborrow() {
let x = RefCell::new(0);
let _b = x.borrow();
@@ -350,7 +349,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn refcell_swap_borrows() {
let x = RefCell::new(0);
let _b = x.borrow();
@@ -360,7 +358,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn refcell_replace_borrows() {
let x = RefCell::new(0);
let _b = x.borrow();
diff --git a/src/libcore/tests/char.rs b/src/libcore/tests/char.rs
index 6185624..57e9f4e 100644
--- a/src/libcore/tests/char.rs
+++ b/src/libcore/tests/char.rs
@@ -76,6 +76,8 @@
#[test]
fn test_to_lowercase() {
fn lower(c: char) -> String {
+ let to_lowercase = c.to_lowercase();
+ assert_eq!(to_lowercase.len(), to_lowercase.count());
let iter: String = c.to_lowercase().collect();
let disp: String = c.to_lowercase().to_string();
assert_eq!(iter, disp);
@@ -101,6 +103,8 @@
#[test]
fn test_to_uppercase() {
fn upper(c: char) -> String {
+ let to_uppercase = c.to_uppercase();
+ assert_eq!(to_uppercase.len(), to_uppercase.count());
let iter: String = c.to_uppercase().collect();
let disp: String = c.to_uppercase().to_string();
assert_eq!(iter, disp);
diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs
index a9db9b3..a3f0b02 100644
--- a/src/libcore/tests/iter.rs
+++ b/src/libcore/tests/iter.rs
@@ -253,7 +253,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_iterator_step_by_zero() {
let mut it = (0..).step_by(0);
it.next();
@@ -1442,7 +1441,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_rposition_panic() {
let v: [(Box<_>, Box<_>); 4] =
[(box 0, box 0), (box 0, box 0),
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index d002137..08dda4b 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -1,6 +1,5 @@
#![feature(box_syntax)]
#![feature(cell_update)]
-#![feature(copied)]
#![feature(core_private_bignum)]
#![feature(core_private_diy_float)]
#![feature(dec2flt)]
@@ -17,7 +16,6 @@
#![feature(pattern)]
#![feature(range_is_empty)]
#![feature(raw)]
-#![feature(refcell_map_split)]
#![feature(refcell_replace_swap)]
#![feature(slice_patterns)]
#![feature(sort_internals)]
diff --git a/src/libcore/tests/num/bignum.rs b/src/libcore/tests/num/bignum.rs
index 956c22c..b873f1d 100644
--- a/src/libcore/tests/num/bignum.rs
+++ b/src/libcore/tests/num/bignum.rs
@@ -3,7 +3,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_from_u64_overflow() {
Big::from_u64(0x1000000);
}
@@ -20,14 +19,12 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_add_overflow_1() {
Big::from_small(1).add(&Big::from_u64(0xffffff));
}
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_add_overflow_2() {
Big::from_u64(0xffffff).add(&Big::from_small(1));
}
@@ -45,7 +42,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_add_small_overflow() {
Big::from_u64(0xffffff).add_small(1);
}
@@ -61,14 +57,12 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_sub_underflow_1() {
Big::from_u64(0x10665).sub(&Big::from_u64(0x10666));
}
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_sub_underflow_2() {
Big::from_small(0).sub(&Big::from_u64(0x123456));
}
@@ -82,7 +76,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_mul_small_overflow() {
Big::from_u64(0x800000).mul_small(2);
}
@@ -101,14 +94,12 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_mul_pow2_overflow_1() {
Big::from_u64(0x1).mul_pow2(24);
}
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_mul_pow2_overflow_2() {
Big::from_u64(0x123).mul_pow2(16);
}
@@ -127,14 +118,12 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_mul_pow5_overflow_1() {
Big::from_small(1).mul_pow5(12);
}
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_mul_pow5_overflow_2() {
Big::from_small(230).mul_pow5(8);
}
@@ -152,14 +141,12 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_mul_digits_overflow_1() {
Big::from_u64(0x800000).mul_digits(&[2]);
}
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_mul_digits_overflow_2() {
Big::from_u64(0x1000).mul_digits(&[0, 0x10]);
}
@@ -219,7 +206,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_get_bit_out_of_range() {
Big::from_small(42).get_bit(24);
}
diff --git a/src/libcore/tests/num/int_macros.rs b/src/libcore/tests/num/int_macros.rs
index 5c6ee8f..4881f79 100644
--- a/src/libcore/tests/num/int_macros.rs
+++ b/src/libcore/tests/num/int_macros.rs
@@ -12,7 +12,7 @@
fn test_overflows() {
assert!(MAX > 0);
assert!(MIN <= 0);
- assert!(MIN + MAX + 1 == 0);
+ assert_eq!(MIN + MAX + 1, 0);
}
#[test]
@@ -22,22 +22,22 @@
#[test]
fn test_rem_euclid() {
- assert!((-1 as $T).rem_euclid(MIN) == MAX);
+ assert_eq!((-1 as $T).rem_euclid(MIN), MAX);
}
#[test]
pub fn test_abs() {
- assert!((1 as $T).abs() == 1 as $T);
- assert!((0 as $T).abs() == 0 as $T);
- assert!((-1 as $T).abs() == 1 as $T);
+ assert_eq!((1 as $T).abs(), 1 as $T);
+ assert_eq!((0 as $T).abs(), 0 as $T);
+ assert_eq!((-1 as $T).abs(), 1 as $T);
}
#[test]
fn test_signum() {
- assert!((1 as $T).signum() == 1 as $T);
- assert!((0 as $T).signum() == 0 as $T);
- assert!((-0 as $T).signum() == 0 as $T);
- assert!((-1 as $T).signum() == -1 as $T);
+ assert_eq!((1 as $T).signum(), 1 as $T);
+ assert_eq!((0 as $T).signum(), 0 as $T);
+ assert_eq!((-0 as $T).signum(), 0 as $T);
+ assert_eq!((-1 as $T).signum(), -1 as $T);
}
#[test]
@@ -58,12 +58,12 @@
#[test]
fn test_bitwise_operators() {
- assert!(0b1110 as $T == (0b1100 as $T).bitor(0b1010 as $T));
- assert!(0b1000 as $T == (0b1100 as $T).bitand(0b1010 as $T));
- assert!(0b0110 as $T == (0b1100 as $T).bitxor(0b1010 as $T));
- assert!(0b1110 as $T == (0b0111 as $T).shl(1));
- assert!(0b0111 as $T == (0b1110 as $T).shr(1));
- assert!(-(0b11 as $T) - (1 as $T) == (0b11 as $T).not());
+ assert_eq!(0b1110 as $T, (0b1100 as $T).bitor(0b1010 as $T));
+ assert_eq!(0b1000 as $T, (0b1100 as $T).bitand(0b1010 as $T));
+ assert_eq!(0b0110 as $T, (0b1100 as $T).bitxor(0b1010 as $T));
+ assert_eq!(0b1110 as $T, (0b0111 as $T).shl(1));
+ assert_eq!(0b0111 as $T, (0b1110 as $T).shr(1));
+ assert_eq!(-(0b11 as $T) - (1 as $T), (0b11 as $T).not());
}
const A: $T = 0b0101100;
@@ -75,17 +75,17 @@
#[test]
fn test_count_ones() {
- assert!(A.count_ones() == 3);
- assert!(B.count_ones() == 2);
- assert!(C.count_ones() == 5);
+ assert_eq!(A.count_ones(), 3);
+ assert_eq!(B.count_ones(), 2);
+ assert_eq!(C.count_ones(), 5);
}
#[test]
fn test_count_zeros() {
let bits = mem::size_of::<$T>() * 8;
- assert!(A.count_zeros() == bits as u32 - 3);
- assert!(B.count_zeros() == bits as u32 - 2);
- assert!(C.count_zeros() == bits as u32 - 5);
+ assert_eq!(A.count_zeros(), bits as u32 - 3);
+ assert_eq!(B.count_zeros(), bits as u32 - 2);
+ assert_eq!(C.count_zeros(), bits as u32 - 5);
}
#[test]
@@ -148,9 +148,9 @@
#[test]
fn test_signed_checked_div() {
- assert!((10 as $T).checked_div(2) == Some(5));
- assert!((5 as $T).checked_div(0) == None);
- assert!(isize::MIN.checked_div(-1) == None);
+ assert_eq!((10 as $T).checked_div(2), Some(5));
+ assert_eq!((5 as $T).checked_div(0), None);
+ assert_eq!(isize::MIN.checked_div(-1), None);
}
#[test]
diff --git a/src/libcore/tests/ops.rs b/src/libcore/tests/ops.rs
index 401644e..78cf071 100644
--- a/src/libcore/tests/ops.rs
+++ b/src/libcore/tests/ops.rs
@@ -7,11 +7,11 @@
let r = Range { start: 2, end: 10 };
let mut count = 0;
for (i, ri) in r.enumerate() {
- assert!(ri == i + 2);
+ assert_eq!(ri, i + 2);
assert!(ri >= 2 && ri < 10);
count += 1;
}
- assert!(count == 8);
+ assert_eq!(count, 8);
}
#[test]
@@ -19,11 +19,11 @@
let r = RangeFrom { start: 2 };
let mut count = 0;
for (i, ri) in r.take(10).enumerate() {
- assert!(ri == i + 2);
+ assert_eq!(ri, i + 2);
assert!(ri >= 2 && ri < 12);
count += 1;
}
- assert!(count == 10);
+ assert_eq!(count, 10);
}
#[test]
diff --git a/src/libcore/tests/option.rs b/src/libcore/tests/option.rs
index 87ce272..b059b13 100644
--- a/src/libcore/tests/option.rs
+++ b/src/libcore/tests/option.rs
@@ -69,7 +69,6 @@
}
#[test] #[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_option_too_much_dance() {
struct A;
let mut y = Some(A);
@@ -130,7 +129,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_unwrap_panic1() {
let x: Option<isize> = None;
x.unwrap();
@@ -138,7 +136,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn test_unwrap_panic2() {
let x: Option<String> = None;
x.unwrap();
diff --git a/src/libcore/tests/result.rs b/src/libcore/tests/result.rs
index bbc85685..1fab075 100644
--- a/src/libcore/tests/result.rs
+++ b/src/libcore/tests/result.rs
@@ -117,7 +117,6 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
pub fn test_unwrap_or_else_panic() {
fn handler(msg: &'static str) -> isize {
if msg == "I got this." {
@@ -139,7 +138,6 @@
}
#[test]
#[should_panic(expected="Got expected error: \"All good\"")]
-#[cfg(not(miri))] // Miri does not support panics
pub fn test_expect_err() {
let err: Result<isize, &'static str> = Err("All good");
err.expect("Got expected error");
@@ -153,7 +151,6 @@
}
#[test]
#[should_panic(expected="Got expected ok: \"All good\"")]
-#[cfg(not(miri))] // Miri does not support panics
pub fn test_expect_err_ok() {
let err: Result<&'static str, isize> = Ok("All good");
err.expect_err("Got expected ok");
diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs
index 31d16e0..ac9c17a 100644
--- a/src/libcore/tests/slice.rs
+++ b/src/libcore/tests/slice.rs
@@ -782,7 +782,6 @@
// to be used in `should_panic`)
#[test]
#[should_panic(expected = "out of range")]
- #[cfg(not(miri))] // Miri does not support panics
fn assert_range_eq_can_fail_by_panic() {
assert_range_eq!([0, 1, 2], 0..5, [0, 1, 2]);
}
@@ -792,7 +791,6 @@
// to be used in `should_panic`)
#[test]
#[should_panic(expected = "==")]
- #[cfg(not(miri))] // Miri does not support panics
fn assert_range_eq_can_fail_by_inequality() {
assert_range_eq!([0, 1, 2], 0..2, [0, 1, 2]);
}
@@ -842,7 +840,6 @@
#[test]
#[should_panic(expected = $expect_msg)]
- #[cfg(not(miri))] // Miri does not support panics
fn index_fail() {
let v = $data;
let v: &[_] = &v;
@@ -851,7 +848,6 @@
#[test]
#[should_panic(expected = $expect_msg)]
- #[cfg(not(miri))] // Miri does not support panics
fn index_mut_fail() {
let mut v = $data;
let v: &mut [_] = &mut v;
@@ -1304,7 +1300,6 @@
#[test]
#[should_panic(expected = "src is out of bounds")]
-#[cfg(not(miri))] // Miri does not support panics
fn test_copy_within_panics_src_too_long() {
let mut bytes = *b"Hello, World!";
// The length is only 13, so 14 is out of bounds.
@@ -1313,7 +1308,6 @@
#[test]
#[should_panic(expected = "dest is out of bounds")]
-#[cfg(not(miri))] // Miri does not support panics
fn test_copy_within_panics_dest_too_long() {
let mut bytes = *b"Hello, World!";
// The length is only 13, so a slice of length 4 starting at index 10 is out of bounds.
@@ -1321,7 +1315,6 @@
}
#[test]
#[should_panic(expected = "src end is before src start")]
-#[cfg(not(miri))] // Miri does not support panics
fn test_copy_within_panics_src_inverted() {
let mut bytes = *b"Hello, World!";
// 2 is greater than 1, so this range is invalid.
diff --git a/src/libcore/tests/time.rs b/src/libcore/tests/time.rs
index 09aae45..6efd225 100644
--- a/src/libcore/tests/time.rs
+++ b/src/libcore/tests/time.rs
@@ -107,14 +107,12 @@
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn sub_bad1() {
let _ = Duration::new(0, 0) - Duration::new(0, 1);
}
#[test]
#[should_panic]
-#[cfg(not(miri))] // Miri does not support panics
fn sub_bad2() {
let _ = Duration::new(0, 0) - Duration::new(1, 0);
}
diff --git a/src/libcore/time.rs b/src/libcore/time.rs
index 91161ca..ae6d807 100644
--- a/src/libcore/time.rs
+++ b/src/libcore/time.rs
@@ -21,7 +21,6 @@
const NANOS_PER_MICRO: u32 = 1_000;
const MILLIS_PER_SEC: u64 = 1_000;
const MICROS_PER_SEC: u64 = 1_000_000;
-const MAX_NANOS_F64: f64 = ((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f64;
/// A `Duration` type to represent a span of time, typically used for system
/// timeouts.
@@ -510,15 +509,34 @@
/// use std::time::Duration;
///
/// let dur = Duration::new(2, 700_000_000);
- /// assert_eq!(dur.as_float_secs(), 2.7);
+ /// assert_eq!(dur.as_secs_f64(), 2.7);
/// ```
#[unstable(feature = "duration_float", issue = "54361")]
#[inline]
- pub const fn as_float_secs(&self) -> f64 {
+ pub const fn as_secs_f64(&self) -> f64 {
(self.secs as f64) + (self.nanos as f64) / (NANOS_PER_SEC as f64)
}
- /// Creates a new `Duration` from the specified number of seconds.
+ /// Returns the number of seconds contained by this `Duration` as `f32`.
+ ///
+ /// The returned value does include the fractional (nanosecond) part of the duration.
+ ///
+ /// # Examples
+ /// ```
+ /// #![feature(duration_float)]
+ /// use std::time::Duration;
+ ///
+ /// let dur = Duration::new(2, 700_000_000);
+ /// assert_eq!(dur.as_secs_f32(), 2.7);
+ /// ```
+ #[unstable(feature = "duration_float", issue = "54361")]
+ #[inline]
+ pub const fn as_secs_f32(&self) -> f32 {
+ (self.secs as f32) + (self.nanos as f32) / (NANOS_PER_SEC as f32)
+ }
+
+ /// Creates a new `Duration` from the specified number of seconds represented
+ /// as `f64`.
///
/// # Panics
/// This constructor will panic if `secs` is not finite, negative or overflows `Duration`.
@@ -528,12 +546,14 @@
/// #![feature(duration_float)]
/// use std::time::Duration;
///
- /// let dur = Duration::from_float_secs(2.7);
+ /// let dur = Duration::from_secs_f64(2.7);
/// assert_eq!(dur, Duration::new(2, 700_000_000));
/// ```
#[unstable(feature = "duration_float", issue = "54361")]
#[inline]
- pub fn from_float_secs(secs: f64) -> Duration {
+ pub fn from_secs_f64(secs: f64) -> Duration {
+ const MAX_NANOS_F64: f64 =
+ ((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f64;
let nanos = secs * (NANOS_PER_SEC as f64);
if !nanos.is_finite() {
panic!("got non-finite value when converting float to duration");
@@ -551,6 +571,42 @@
}
}
+ /// Creates a new `Duration` from the specified number of seconds represented
+ /// as `f32`.
+ ///
+ /// # Panics
+ /// This constructor will panic if `secs` is not finite, negative or overflows `Duration`.
+ ///
+ /// # Examples
+ /// ```
+ /// #![feature(duration_float)]
+ /// use std::time::Duration;
+ ///
+ /// let dur = Duration::from_secs_f32(2.7);
+ /// assert_eq!(dur, Duration::new(2, 700_000_000));
+ /// ```
+ #[unstable(feature = "duration_float", issue = "54361")]
+ #[inline]
+ pub fn from_secs_f32(secs: f32) -> Duration {
+ const MAX_NANOS_F32: f32 =
+ ((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f32;
+ let nanos = secs * (NANOS_PER_SEC as f32);
+ if !nanos.is_finite() {
+ panic!("got non-finite value when converting float to duration");
+ }
+ if nanos >= MAX_NANOS_F32 {
+ panic!("overflow when converting float to duration");
+ }
+ if nanos < 0.0 {
+ panic!("underflow when converting float to duration");
+ }
+ let nanos = nanos as u128;
+ Duration {
+ secs: (nanos / (NANOS_PER_SEC as u128)) as u64,
+ nanos: (nanos % (NANOS_PER_SEC as u128)) as u32,
+ }
+ }
+
/// Multiplies `Duration` by `f64`.
///
/// # Panics
@@ -568,7 +624,29 @@
#[unstable(feature = "duration_float", issue = "54361")]
#[inline]
pub fn mul_f64(self, rhs: f64) -> Duration {
- Duration::from_float_secs(rhs * self.as_float_secs())
+ Duration::from_secs_f64(rhs * self.as_secs_f64())
+ }
+
+ /// Multiplies `Duration` by `f32`.
+ ///
+ /// # Panics
+ /// This method will panic if result is not finite, negative or overflows `Duration`.
+ ///
+ /// # Examples
+ /// ```
+ /// #![feature(duration_float)]
+ /// use std::time::Duration;
+ ///
+ /// let dur = Duration::new(2, 700_000_000);
+ /// // note that due to rounding errors result is slightly different
+ /// // from 8.478 and 847800.0
+ /// assert_eq!(dur.mul_f32(3.14), Duration::new(8, 478_000_640));
+ /// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847799, 969_120_256));
+ /// ```
+ #[unstable(feature = "duration_float", issue = "54361")]
+ #[inline]
+ pub fn mul_f32(self, rhs: f32) -> Duration {
+ Duration::from_secs_f32(rhs * self.as_secs_f32())
}
/// Divide `Duration` by `f64`.
@@ -589,7 +667,30 @@
#[unstable(feature = "duration_float", issue = "54361")]
#[inline]
pub fn div_f64(self, rhs: f64) -> Duration {
- Duration::from_float_secs(self.as_float_secs() / rhs)
+ Duration::from_secs_f64(self.as_secs_f64() / rhs)
+ }
+
+ /// Divide `Duration` by `f32`.
+ ///
+ /// # Panics
+ /// This method will panic if result is not finite, negative or overflows `Duration`.
+ ///
+ /// # Examples
+ /// ```
+ /// #![feature(duration_float)]
+ /// use std::time::Duration;
+ ///
+ /// let dur = Duration::new(2, 700_000_000);
+ /// // note that due to rounding errors result is slightly
+ /// // different from 0.859_872_611
+ /// assert_eq!(dur.div_f32(3.14), Duration::new(0, 859_872_576));
+ /// // note that truncation is used, not rounding
+ /// assert_eq!(dur.div_f32(3.14e5), Duration::new(0, 8_598));
+ /// ```
+ #[unstable(feature = "duration_float", issue = "54361")]
+ #[inline]
+ pub fn div_f32(self, rhs: f32) -> Duration {
+ Duration::from_secs_f32(self.as_secs_f32() / rhs)
}
/// Divide `Duration` by `Duration` and return `f64`.
@@ -601,12 +702,29 @@
///
/// let dur1 = Duration::new(2, 700_000_000);
/// let dur2 = Duration::new(5, 400_000_000);
- /// assert_eq!(dur1.div_duration(dur2), 0.5);
+ /// assert_eq!(dur1.div_duration_f64(dur2), 0.5);
/// ```
#[unstable(feature = "duration_float", issue = "54361")]
#[inline]
- pub fn div_duration(self, rhs: Duration) -> f64 {
- self.as_float_secs() / rhs.as_float_secs()
+ pub fn div_duration_f64(self, rhs: Duration) -> f64 {
+ self.as_secs_f64() / rhs.as_secs_f64()
+ }
+
+ /// Divide `Duration` by `Duration` and return `f32`.
+ ///
+ /// # Examples
+ /// ```
+ /// #![feature(duration_float)]
+ /// use std::time::Duration;
+ ///
+ /// let dur1 = Duration::new(2, 700_000_000);
+ /// let dur2 = Duration::new(5, 400_000_000);
+ /// assert_eq!(dur1.div_duration_f32(dur2), 0.5);
+ /// ```
+ #[unstable(feature = "duration_float", issue = "54361")]
+ #[inline]
+ pub fn div_duration_f32(self, rhs: Duration) -> f32 {
+ self.as_secs_f32() / rhs.as_secs_f32()
}
}
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index eb75e62..43e865a 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -423,7 +423,7 @@
}
}
-define_dep_nodes!( <'tcx>
+rustc_dep_node_append!([define_dep_nodes!][ <'tcx>
// We use this for most things when incr. comp. is turned off.
[] Null,
@@ -492,9 +492,6 @@
// table in the tcx (or elsewhere) maps to one of these
// nodes.
[] AssociatedItems(DefId),
- [] TypeOfItem(DefId),
- [] GenericsOfItem(DefId),
- [] PredicatesOfItem(DefId),
[] ExplicitPredicatesOfItem(DefId),
[] PredicatesDefinedOnItem(DefId),
[] InferredOutlivesOf(DefId),
@@ -570,7 +567,6 @@
[] FnArgNames(DefId),
[] RenderedConst(DefId),
[] DylibDepFormats(CrateNum),
- [] IsPanicRuntime(CrateNum),
[] IsCompilerBuiltins(CrateNum),
[] HasGlobalAllocator(CrateNum),
[] HasPanicHandler(CrateNum),
@@ -588,7 +584,6 @@
[] CheckTraitItemWellFormed(DefId),
[] CheckImplItemWellFormed(DefId),
[] ReachableNonGenerics(CrateNum),
- [] NativeLibraries(CrateNum),
[] EntryFn(CrateNum),
[] PluginRegistrarFn(CrateNum),
[] ProcMacroDeclsStatic(CrateNum),
@@ -679,7 +674,23 @@
[] UpstreamMonomorphizations(CrateNum),
[] UpstreamMonomorphizationsFor(DefId),
-);
+]);
+
+pub trait RecoverKey<'tcx>: Sized {
+ fn recover(tcx: TyCtxt<'_, 'tcx, 'tcx>, dep_node: &DepNode) -> Option<Self>;
+}
+
+impl RecoverKey<'tcx> for CrateNum {
+ fn recover(tcx: TyCtxt<'_, 'tcx, 'tcx>, dep_node: &DepNode) -> Option<Self> {
+ dep_node.extract_def_id(tcx).map(|id| id.krate)
+ }
+}
+
+impl RecoverKey<'tcx> for DefId {
+ fn recover(tcx: TyCtxt<'_, 'tcx, 'tcx>, dep_node: &DepNode) -> Option<Self> {
+ dep_node.extract_def_id(tcx)
+ }
+}
trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {
const CAN_RECONSTRUCT_QUERY_KEY: bool;
diff --git a/src/librustc/dep_graph/mod.rs b/src/librustc/dep_graph/mod.rs
index b84d2ad..1535e6d 100644
--- a/src/librustc/dep_graph/mod.rs
+++ b/src/librustc/dep_graph/mod.rs
@@ -9,7 +9,7 @@
pub mod cgu_reuse_tracker;
pub use self::dep_tracking_map::{DepTrackingMap, DepTrackingMapConfig};
-pub use self::dep_node::{DepNode, DepKind, DepConstructor, WorkProductId, label_strs};
+pub use self::dep_node::{DepNode, DepKind, DepConstructor, WorkProductId, RecoverKey, label_strs};
pub use self::graph::{DepGraph, WorkProduct, DepNodeIndex, DepNodeColor, TaskDeps, hash_result};
pub use self::graph::WorkProductFileKind;
pub use self::prev::PreviousDepGraph;
diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs
index 86f7e14..8602d15 100644
--- a/src/librustc/hir/check_attr.rs
+++ b/src/librustc/hir/check_attr.rs
@@ -166,7 +166,7 @@
// ```
let hints: Vec<_> = item.attrs
.iter()
- .filter(|attr| attr.name() == "repr")
+ .filter(|attr| attr.check_name("repr"))
.filter_map(|attr| attr.meta_item_list())
.flatten()
.collect();
@@ -177,7 +177,7 @@
let mut is_transparent = false;
for hint in &hints {
- let name = if let Some(name) = hint.name() {
+ let name = if let Some(name) = hint.ident_str() {
name
} else {
// Invalid repr hint like repr(42). We don't check for unrecognized hints here
@@ -185,7 +185,7 @@
continue;
};
- let (article, allowed_targets) = match &*name.as_str() {
+ let (article, allowed_targets) = match name {
"C" | "align" => {
is_c |= name == "C";
if target != Target::Struct &&
@@ -233,7 +233,7 @@
_ => continue,
};
self.emit_repr_error(
- hint.span,
+ hint.span(),
item.span,
&format!("attribute should be applied to {}", allowed_targets),
&format!("not {} {}", article, allowed_targets),
@@ -242,7 +242,7 @@
// 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);
+ let hint_spans = hints.iter().map(|hint| hint.span());
// Error on repr(transparent, <anything else>).
if is_transparent && hints.len() > 1 {
@@ -313,7 +313,7 @@
fn check_used(&self, item: &hir::Item, target: Target) {
for attr in &item.attrs {
- if attr.name() == "used" && target != Target::Static {
+ if attr.check_name("used") && target != Target::Static {
self.tcx.sess
.span_err(attr.span, "attribute must be applied to a `static` variable");
}
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 949fdd2..73c3b30 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -2672,7 +2672,7 @@
fn lower_variant_data(&mut self, vdata: &VariantData) -> hir::VariantData {
match *vdata {
- VariantData::Struct(ref fields, id) => {
+ VariantData::Struct(ref fields, id, recovered) => {
let LoweredNodeId { node_id: _, hir_id } = self.lower_node_id(id);
hir::VariantData::Struct(
@@ -2682,6 +2682,7 @@
.map(|f| self.lower_struct_field(f))
.collect(),
hir_id,
+ recovered,
)
},
VariantData::Tuple(ref fields, id) => {
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index 600e7e2..151c541 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -541,7 +541,8 @@
pub fn ty_param_owner(&self, id: HirId) -> HirId {
match self.get_by_hir_id(id) {
- Node::Item(&Item { node: ItemKind::Trait(..), .. }) => id,
+ Node::Item(&Item { node: ItemKind::Trait(..), .. }) |
+ Node::Item(&Item { node: ItemKind::TraitAlias(..), .. }) => id,
Node::GenericParam(_) => self.get_parent_node_by_hir_id(id),
_ => bug!("ty_param_owner: {} not a type parameter", self.hir_to_string(id))
}
@@ -549,7 +550,8 @@
pub fn ty_param_name(&self, id: HirId) -> Name {
match self.get_by_hir_id(id) {
- Node::Item(&Item { node: ItemKind::Trait(..), .. }) => keywords::SelfUpper.name(),
+ Node::Item(&Item { node: ItemKind::Trait(..), .. }) |
+ Node::Item(&Item { node: ItemKind::TraitAlias(..), .. }) => keywords::SelfUpper.name(),
Node::GenericParam(param) => param.name.ident().name,
_ => bug!("ty_param_name: {} not a type parameter", self.hir_to_string(id)),
}
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 88ab58d..5edddb3 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -816,6 +816,9 @@
pub legacy: bool,
}
+/// A block of statements `{ .. }`, which may have a label (in this case the
+/// `targeted_by_break` field will be `true`) and may be `unsafe` by means of
+/// the `rules` being anything but `DefaultBlock`.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct Block {
/// Statements in a block.
@@ -1178,6 +1181,7 @@
}
}
+/// The contents of a statement.
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
pub enum StmtKind {
/// A local (`let`) binding.
@@ -1208,21 +1212,28 @@
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct Local {
pub pat: P<Pat>,
+ /// Type annotation, if any (otherwise the type will be inferred).
pub ty: Option<P<Ty>>,
/// Initializer expression to set the value, if any.
pub init: Option<P<Expr>>,
pub hir_id: HirId,
pub span: Span,
pub attrs: ThinVec<Attribute>,
+ /// Can be `ForLoopDesugar` if the `let` statement is part of a `for` loop
+ /// desugaring. Otherwise will be `Normal`.
pub source: LocalSource,
}
-/// Represents a single arm of a `match` expression.
+/// Represents a single arm of a `match` expression, e.g.
+/// `<pats> (if <guard>) => <body>`.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct Arm {
pub attrs: HirVec<Attribute>,
+ /// Multiple patterns can be combined with `|`
pub pats: HirVec<P<Pat>>,
+ /// Optional guard clause.
pub guard: Option<Guard>,
+ /// The expression the arm evaluates to if this arm matches.
pub body: P<Expr>,
}
@@ -2173,7 +2184,7 @@
/// Id of the whole struct lives in `Item`.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
pub enum VariantData {
- Struct(HirVec<StructField>, HirId),
+ Struct(HirVec<StructField>, HirId, /* recovered */ bool),
Tuple(HirVec<StructField>, HirId),
Unit(HirId),
}
@@ -2187,7 +2198,7 @@
}
pub fn hir_id(&self) -> HirId {
match *self {
- VariantData::Struct(_, hir_id)
+ VariantData::Struct(_, hir_id, _)
| VariantData::Tuple(_, hir_id)
| VariantData::Unit(hir_id) => hir_id,
}
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index 54a21f2..bff4190 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -591,12 +591,12 @@
self.s.word(";")?;
self.end()?; // end the outer cbox
}
- hir::ItemKind::Fn(ref decl, header, ref typarams, body) => {
+ hir::ItemKind::Fn(ref decl, header, ref param_names, body) => {
self.head("")?;
self.print_fn(decl,
header,
Some(item.ident.name),
- typarams,
+ param_names,
&item.vis,
&[],
Some(body))?;
diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs
index f34423c..496ccc8 100644
--- a/src/librustc/ich/impls_syntax.rs
+++ b/src/librustc/ich/impls_syntax.rs
@@ -197,7 +197,8 @@
let filtered: SmallVec<[&ast::Attribute; 8]> = self
.iter()
.filter(|attr| {
- !attr.is_sugared_doc && !hcx.is_ignored_attr(attr.name())
+ !attr.is_sugared_doc &&
+ !attr.ident().map_or(false, |ident| hcx.is_ignored_attr(ident.name))
})
.collect();
@@ -224,7 +225,7 @@
hcx: &mut StableHashingContext<'a>,
hasher: &mut StableHasher<W>) {
// Make sure that these have been filtered out.
- debug_assert!(!hcx.is_ignored_attr(self.name()));
+ debug_assert!(!self.ident().map_or(false, |ident| hcx.is_ignored_attr(ident.name)));
debug_assert!(!self.is_sugared_doc);
let ast::Attribute {
@@ -359,15 +360,13 @@
}
}
-impl_stable_hash_for_spanned!(::syntax::ast::NestedMetaItemKind);
-
-impl_stable_hash_for!(enum ::syntax::ast::NestedMetaItemKind {
+impl_stable_hash_for!(enum ::syntax::ast::NestedMetaItem {
MetaItem(meta_item),
Literal(lit)
});
impl_stable_hash_for!(struct ::syntax::ast::MetaItem {
- ident,
+ path,
node,
span
});
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index b667732..4b2fda3 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -60,6 +60,8 @@
#![feature(test)]
#![feature(in_band_lifetimes)]
#![feature(crate_visibility_modifier)]
+#![feature(proc_macro_hygiene)]
+#![feature(log_syntax)]
#![recursion_limit="512"]
@@ -69,6 +71,7 @@
#[macro_use] extern crate scoped_tls;
#[cfg(windows)]
extern crate libc;
+#[macro_use] extern crate rustc_macros;
#[macro_use] extern crate rustc_data_structures;
#[macro_use] extern crate log;
@@ -96,6 +99,9 @@
// registered before they are used.
pub mod diagnostics;
+#[macro_use]
+pub mod query;
+
pub mod cfg;
pub mod dep_graph;
pub mod hir;
diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs
index 3c6635c..19e899c 100644
--- a/src/librustc/lint/levels.rs
+++ b/src/librustc/lint/levels.rs
@@ -194,7 +194,7 @@
struct_span_err!(sess, span, E0452, "malformed lint attribute")
};
for attr in attrs {
- let level = match Level::from_str(&attr.name().as_str()) {
+ let level = match attr.ident_str().and_then(|name| Level::from_str(name)) {
None => continue,
Some(lvl) => lvl,
};
@@ -221,7 +221,7 @@
match item.node {
ast::MetaItemKind::Word => {} // actual lint names handled later
ast::MetaItemKind::NameValue(ref name_value) => {
- if item.ident == "reason" {
+ if item.path == "reason" {
// found reason, reslice meta list to exclude it
metas = &metas[0..metas.len()-1];
// FIXME (#55112): issue unused-attributes lint if we thereby
@@ -255,13 +255,13 @@
}
for li in metas {
- let word = match li.word() {
- Some(word) => word,
- None => {
- let mut err = bad_attr(li.span);
+ let meta_item = match li.meta_item() {
+ Some(meta_item) if meta_item.is_word() => meta_item,
+ _ => {
+ let mut err = bad_attr(li.span());
if let Some(item) = li.meta_item() {
if let ast::MetaItemKind::NameValue(_) = item.node {
- if item.ident == "reason" {
+ if item.path == "reason" {
err.help("reason in lint attribute must come last");
}
}
@@ -270,26 +270,27 @@
continue;
}
};
- let tool_name = if let Some(lint_tool) = word.is_scoped() {
- if !attr::is_known_lint_tool(lint_tool) {
+ let tool_name = if meta_item.path.segments.len() > 1 {
+ let tool_ident = meta_item.path.segments[0].ident;
+ if !attr::is_known_lint_tool(tool_ident) {
span_err!(
sess,
- lint_tool.span,
+ tool_ident.span,
E0710,
"an unknown tool name found in scoped lint: `{}`",
- word.ident
+ meta_item.path
);
continue;
}
- Some(lint_tool.as_str())
+ Some(tool_ident.as_str())
} else {
None
};
- let name = word.name();
+ let name = meta_item.path.segments.last().expect("empty lint name").ident.name;
match store.check_lint_name(&name.as_str(), tool_name) {
CheckLintNameResult::Ok(ids) => {
- let src = LintSource::Node(name, li.span, reason);
+ let src = LintSource::Node(name, li.span(), reason);
for id in ids {
specs.insert(*id, (level, src));
}
@@ -300,7 +301,7 @@
Ok(ids) => {
let complete_name = &format!("{}::{}", tool_name.unwrap(), name);
let src = LintSource::Node(
- Symbol::intern(complete_name), li.span, reason
+ Symbol::intern(complete_name), li.span(), reason
);
for id in ids {
specs.insert(*id, (level, src));
@@ -322,18 +323,18 @@
lint,
lvl,
src,
- Some(li.span.into()),
+ Some(li.span().into()),
&msg,
);
err.span_suggestion(
- li.span,
+ li.span(),
"change it to",
new_lint_name.to_string(),
Applicability::MachineApplicable,
).emit();
let src = LintSource::Node(
- Symbol::intern(&new_lint_name), li.span, reason
+ Symbol::intern(&new_lint_name), li.span(), reason
);
for id in ids {
specs.insert(*id, (level, src));
@@ -360,11 +361,11 @@
lint,
level,
src,
- Some(li.span.into()),
+ Some(li.span().into()),
&msg);
if let Some(new_name) = renamed {
err.span_suggestion(
- li.span,
+ li.span(),
"use the new name",
new_name,
Applicability::MachineApplicable
@@ -383,12 +384,12 @@
lint,
level,
src,
- Some(li.span.into()),
+ Some(li.span().into()),
&msg);
if let Some(suggestion) = suggestion {
db.span_suggestion(
- li.span,
+ li.span(),
"did you mean",
suggestion.to_string(),
Applicability::MachineApplicable,
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index c01b0ae..03ed62f 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -724,7 +724,7 @@
pub fn maybe_lint_level_root(tcx: TyCtxt<'_, '_, '_>, id: hir::HirId) -> bool {
let attrs = tcx.hir().attrs_by_hir_id(id);
for attr in attrs {
- if Level::from_str(&attr.name().as_str()).is_some() {
+ if attr.ident_str().and_then(Level::from_str).is_some() {
return true;
}
}
@@ -833,7 +833,8 @@
/// Returns whether `span` originates in a foreign crate's external macro.
///
-/// This is used to test whether a lint should be entirely aborted above.
+/// This is used to test whether a lint should not even begin to figure out whether it should
+/// be reported on the current node.
pub fn in_external_macro(sess: &Session, span: Span) -> bool {
let info = match span.ctxt().outer().expn_info() {
Some(info) => info,
@@ -859,3 +860,17 @@
Err(_) => true,
}
}
+
+/// Returns whether `span` originates in a derive macro's expansion
+pub fn in_derive_expansion(span: Span) -> bool {
+ let info = match span.ctxt().outer().expn_info() {
+ Some(info) => info,
+ // no ExpnInfo means this span doesn't come from a macro
+ None => return false,
+ };
+
+ match info.format {
+ ExpnFormat::MacroAttribute(symbol) => symbol.as_str().starts_with("derive("),
+ _ => false,
+ }
+}
diff --git a/src/librustc/middle/lib_features.rs b/src/librustc/middle/lib_features.rs
index 9d15b05..237b00d 100644
--- a/src/librustc/middle/lib_features.rs
+++ b/src/librustc/middle/lib_features.rs
@@ -65,9 +65,9 @@
for meta in metas {
if let Some(mi) = meta.meta_item() {
// Find the `feature = ".."` meta-item.
- match (&*mi.name().as_str(), mi.value_str()) {
- ("feature", val) => feature = val,
- ("since", val) => since = val,
+ match (mi.ident_str(), mi.value_str()) {
+ (Some("feature"), val) => feature = val,
+ (Some("since"), val) => since = val,
_ => {}
}
}
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 96f0bea..ab105360 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -2299,6 +2299,7 @@
let span = lifetime_refs[0].span;
let mut late_depth = 0;
let mut scope = self.scope;
+ let mut lifetime_names = FxHashSet::default();
let error = loop {
match *scope {
// Do not assign any resolution, it will be inferred.
@@ -2306,12 +2307,18 @@
Scope::Root => break None,
- Scope::Binder { s, .. } => {
+ Scope::Binder { s, ref lifetimes, .. } => {
+ // collect named lifetimes for suggestions
+ for name in lifetimes.keys() {
+ if let hir::ParamName::Plain(name) = name {
+ lifetime_names.insert(*name);
+ }
+ }
late_depth += 1;
scope = s;
}
- Scope::Elision { ref elide, .. } => {
+ Scope::Elision { ref elide, ref s, .. } => {
let lifetime = match *elide {
Elide::FreshLateAnon(ref counter) => {
for lifetime_ref in lifetime_refs {
@@ -2321,7 +2328,17 @@
return;
}
Elide::Exact(l) => l.shifted(late_depth),
- Elide::Error(ref e) => break Some(e),
+ Elide::Error(ref e) => {
+ if let Scope::Binder { ref lifetimes, .. } = s {
+ // collect named lifetimes for suggestions
+ for name in lifetimes.keys() {
+ if let hir::ParamName::Plain(name) = name {
+ lifetime_names.insert(*name);
+ }
+ }
+ }
+ break Some(e);
+ }
};
for lifetime_ref in lifetime_refs {
self.insert_lifetime(lifetime_ref, lifetime);
@@ -2344,7 +2361,13 @@
}
}
if add_label {
- add_missing_lifetime_specifiers_label(&mut err, span, lifetime_refs.len());
+ add_missing_lifetime_specifiers_label(
+ &mut err,
+ span,
+ lifetime_refs.len(),
+ &lifetime_names,
+ self.tcx.sess.source_map().span_to_snippet(span).ok().as_ref().map(|s| s.as_str()),
+ );
}
err.emit();
@@ -2885,10 +2908,23 @@
err: &mut DiagnosticBuilder<'_>,
span: Span,
count: usize,
+ lifetime_names: &FxHashSet<ast::Ident>,
+ snippet: Option<&str>,
) {
if count > 1 {
err.span_label(span, format!("expected {} lifetime parameters", count));
+ } else if let (1, Some(name), Some("&")) = (
+ lifetime_names.len(),
+ lifetime_names.iter().next(),
+ snippet,
+ ) {
+ err.span_suggestion(
+ span,
+ "consider using the named lifetime",
+ format!("&{} ", name),
+ Applicability::MaybeIncorrect,
+ );
} else {
err.span_label(span, "expected lifetime parameter");
- };
+ }
}
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index 0a2a375..c1a97cd 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -3,7 +3,7 @@
pub use self::StabilityLevel::*;
-use crate::lint::{self, Lint};
+use crate::lint::{self, Lint, in_derive_expansion};
use crate::hir::{self, Item, Generics, StructField, Variant, HirId};
use crate::hir::def::Def;
use crate::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE};
@@ -194,11 +194,12 @@
} else {
// Emit errors for non-staged-api crates.
for attr in attrs {
- let tag = attr.name();
- if tag == "unstable" || tag == "stable" || tag == "rustc_deprecated" {
- attr::mark_used(attr);
- self.tcx.sess.span_err(attr.span(), "stability attributes may not be used \
- outside of the standard library");
+ if let Some(tag) = attr.ident_str() {
+ if tag == "unstable" || tag == "stable" || tag == "rustc_deprecated" {
+ attr::mark_used(attr);
+ self.tcx.sess.span_err(attr.span, "stability attributes may not be used \
+ outside of the standard library");
+ }
}
}
@@ -561,6 +562,9 @@
suggestion: Option<Symbol>,
message: &str,
lint: &'static Lint| {
+ if in_derive_expansion(span) {
+ return;
+ }
let msg = if let Some(note) = note {
format!("{}: {}", message, note)
} else {
diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs
index d4ee60e..80fef91 100644
--- a/src/librustc/mir/interpret/allocation.rs
+++ b/src/librustc/mir/interpret/allocation.rs
@@ -101,8 +101,7 @@
impl<Tag, Extra> Allocation<Tag, Extra> {
/// Creates a read-only allocation initialized by the given bytes
pub fn from_bytes(slice: &[u8], align: Align, extra: Extra) -> Self {
- let mut undef_mask = UndefMask::new(Size::ZERO);
- undef_mask.grow(Size::from_bytes(slice.len() as u64), true);
+ let undef_mask = UndefMask::new(Size::from_bytes(slice.len() as u64), true);
Self {
bytes: slice.to_owned(),
relocations: Relocations::new(),
@@ -122,7 +121,7 @@
Allocation {
bytes: vec![0; size.bytes() as usize],
relocations: Relocations::new(),
- undef_mask: UndefMask::new(size),
+ undef_mask: UndefMask::new(size, false),
align,
mutability: Mutability::Mutable,
extra,
@@ -614,8 +613,9 @@
////////////////////////////////////////////////////////////////////////////////
type Block = u64;
-const BLOCK_SIZE: u64 = 64;
+/// A bitmask where each bit refers to the byte with the same index. If the bit is `true`, the byte
+/// is defined. If it is `false` the byte is undefined.
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
pub struct UndefMask {
blocks: Vec<Block>,
@@ -625,12 +625,14 @@
impl_stable_hash_for!(struct mir::interpret::UndefMask{blocks, len});
impl UndefMask {
- pub fn new(size: Size) -> Self {
+ pub const BLOCK_SIZE: u64 = 64;
+
+ pub fn new(size: Size, state: bool) -> Self {
let mut m = UndefMask {
blocks: vec![],
len: Size::ZERO,
};
- m.grow(size, false);
+ m.grow(size, state);
m
}
@@ -644,6 +646,7 @@
return Err(self.len);
}
+ // FIXME(oli-obk): optimize this for allocations larger than a block.
let idx = (start.bytes()..end.bytes())
.map(|i| Size::from_bytes(i))
.find(|&i| !self.get(i));
@@ -663,20 +666,63 @@
}
pub fn set_range_inbounds(&mut self, start: Size, end: Size, new_state: bool) {
- for i in start.bytes()..end.bytes() {
- self.set(Size::from_bytes(i), new_state);
+ let (blocka, bita) = bit_index(start);
+ let (blockb, bitb) = bit_index(end);
+ if blocka == blockb {
+ // first set all bits but the first `bita`
+ // then unset the last `64 - bitb` bits
+ let range = if bitb == 0 {
+ u64::max_value() << bita
+ } else {
+ (u64::max_value() << bita) & (u64::max_value() >> (64 - bitb))
+ };
+ if new_state {
+ self.blocks[blocka] |= range;
+ } else {
+ self.blocks[blocka] &= !range;
+ }
+ return;
+ }
+ // across block boundaries
+ if new_state {
+ // set bita..64 to 1
+ self.blocks[blocka] |= u64::max_value() << bita;
+ // set 0..bitb to 1
+ if bitb != 0 {
+ self.blocks[blockb] |= u64::max_value() >> (64 - bitb);
+ }
+ // fill in all the other blocks (much faster than one bit at a time)
+ for block in (blocka + 1) .. blockb {
+ self.blocks[block] = u64::max_value();
+ }
+ } else {
+ // set bita..64 to 0
+ self.blocks[blocka] &= !(u64::max_value() << bita);
+ // set 0..bitb to 0
+ if bitb != 0 {
+ self.blocks[blockb] &= !(u64::max_value() >> (64 - bitb));
+ }
+ // fill in all the other blocks (much faster than one bit at a time)
+ for block in (blocka + 1) .. blockb {
+ self.blocks[block] = 0;
+ }
}
}
#[inline]
pub fn get(&self, i: Size) -> bool {
let (block, bit) = bit_index(i);
- (self.blocks[block] & 1 << bit) != 0
+ (self.blocks[block] & (1 << bit)) != 0
}
#[inline]
pub fn set(&mut self, i: Size, new_state: bool) {
let (block, bit) = bit_index(i);
+ self.set_bit(block, bit, new_state);
+ }
+
+ #[inline]
+ fn set_bit(&mut self, block: usize, bit: usize, new_state: bool) {
if new_state {
self.blocks[block] |= 1 << bit;
} else {
@@ -685,11 +731,15 @@
}
pub fn grow(&mut self, amount: Size, new_state: bool) {
- let unused_trailing_bits = self.blocks.len() as u64 * BLOCK_SIZE - self.len.bytes();
+ if amount.bytes() == 0 {
+ return;
+ }
+ let unused_trailing_bits = self.blocks.len() as u64 * Self::BLOCK_SIZE - self.len.bytes();
if amount.bytes() > unused_trailing_bits {
- let additional_blocks = amount.bytes() / BLOCK_SIZE + 1;
+ let additional_blocks = amount.bytes() / Self::BLOCK_SIZE + 1;
assert_eq!(additional_blocks as usize as u64, additional_blocks);
self.blocks.extend(
+ // FIXME(oli-obk): optimize this by repeating `new_state as Block`
iter::repeat(0).take(additional_blocks as usize),
);
}
@@ -702,8 +752,8 @@
#[inline]
fn bit_index(bits: Size) -> (usize, usize) {
let bits = bits.bytes();
- let a = bits / BLOCK_SIZE;
- let b = bits % BLOCK_SIZE;
+ let a = bits / UndefMask::BLOCK_SIZE;
+ let b = bits % UndefMask::BLOCK_SIZE;
assert_eq!(a as usize as u64, a);
assert_eq!(b as usize as u64, b);
(a as usize, b as usize)
diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs
index 9620ac9..7b47c02 100644
--- a/src/librustc/mir/interpret/value.rs
+++ b/src/librustc/mir/interpret/value.rs
@@ -1,7 +1,8 @@
use std::fmt;
use rustc_macros::HashStable;
-use crate::ty::{Ty, InferConst, ParamConst, layout::{HasDataLayout, Size}};
+use crate::ty::{Ty, InferConst, ParamConst, layout::{HasDataLayout, Size}, subst::SubstsRef};
+use crate::hir::def_id::DefId;
use super::{EvalResult, Pointer, PointerArithmetic, Allocation, AllocId, sign_extend, truncate};
@@ -42,6 +43,10 @@
/// An allocation together with a pointer into the allocation.
/// Invariant: the pointer's `AllocId` resolves to the allocation.
ByRef(Pointer, &'tcx Allocation),
+
+ /// Used in the HIR by using `Unevaluated` everywhere and later normalizing to one of the other
+ /// variants when the code is monomorphic enough for that.
+ Unevaluated(DefId, SubstsRef<'tcx>),
}
#[cfg(target_arch = "x86_64")]
@@ -54,6 +59,7 @@
ConstValue::Param(_) |
ConstValue::Infer(_) |
ConstValue::ByRef(..) |
+ ConstValue::Unevaluated(..) |
ConstValue::Slice(..) => None,
ConstValue::Scalar(val) => Some(val),
}
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 718b506..9f2027e 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -2179,8 +2179,8 @@
span,
ty,
user_ty: None,
- literal: tcx.mk_lazy_const(
- ty::LazyConst::Evaluated(ty::Const::zero_sized(ty)),
+ literal: tcx.mk_const(
+ ty::Const::zero_sized(ty),
),
})
}
@@ -2497,7 +2497,7 @@
/// Needed for NLL to impose user-given type constraints.
pub user_ty: Option<UserTypeAnnotationIndex>,
- pub literal: &'tcx ty::LazyConst<'tcx>,
+ pub literal: &'tcx ty::Const<'tcx>,
}
/// A collection of projections into user types.
@@ -2696,18 +2696,9 @@
impl<'tcx> Debug for Constant<'tcx> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
write!(fmt, "const ")?;
- fmt_lazy_const_val(fmt, self.literal)
+ fmt_const_val(fmt, *self.literal)
}
}
-
-/// Write a `ConstValue` in a way closer to the original source code than the `Debug` output.
-pub fn fmt_lazy_const_val(f: &mut impl Write, const_val: &ty::LazyConst<'_>) -> fmt::Result {
- match *const_val {
- ty::LazyConst::Unevaluated(..) => write!(f, "{:?}", const_val),
- ty::LazyConst::Evaluated(c) => fmt_const_val(f, c),
- }
-}
-
/// Write a `ConstValue` in a way closer to the original source code than the `Debug` output.
pub fn fmt_const_val(f: &mut impl Write, const_val: ty::Const<'_>) -> fmt::Result {
use crate::ty::TyKind::*;
@@ -2760,7 +2751,7 @@
}
}
// just raw dump everything else
- write!(f, "{:?}:{}", value, ty)
+ write!(f, "{:?} : {}", value, ty)
}
fn def_path_str(def_id: DefId) -> String {
diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs
index 28e816f..8bc0075 100644
--- a/src/librustc/mir/visit.rs
+++ b/src/librustc/mir/visit.rs
@@ -232,7 +232,7 @@
}
fn visit_const(&mut self,
- constant: & $($mutability)? &'tcx ty::LazyConst<'tcx>,
+ constant: & $($mutability)? &'tcx ty::Const<'tcx>,
_: Location) {
self.super_const(constant);
}
@@ -886,7 +886,7 @@
fn super_region(&mut self, _region: & $($mutability)? ty::Region<'tcx>) {
}
- fn super_const(&mut self, _const: & $($mutability)? &'tcx ty::LazyConst<'tcx>) {
+ fn super_const(&mut self, _const: & $($mutability)? &'tcx ty::Const<'tcx>) {
}
fn super_substs(&mut self, _substs: & $($mutability)? SubstsRef<'tcx>) {
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
new file mode 100644
index 0000000..ecc0089
--- /dev/null
+++ b/src/librustc/query/mod.rs
@@ -0,0 +1,66 @@
+use crate::ty::query::QueryDescription;
+use crate::ty::query::queries;
+use crate::ty::TyCtxt;
+use crate::ty;
+use crate::hir::def_id::CrateNum;
+use crate::dep_graph::SerializedDepNodeIndex;
+use std::borrow::Cow;
+
+// Each of these queries corresponds to a function pointer field in the
+// `Providers` struct for requesting a value of that type, and a method
+// on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way
+// which memoizes and does dep-graph tracking, wrapping around the actual
+// `Providers` that the driver creates (using several `rustc_*` crates).
+//
+// The result type of each query must implement `Clone`, and additionally
+// `ty::query::values::Value`, which produces an appropriate placeholder
+// (error) value if the query resulted in a query cycle.
+// Queries marked with `fatal_cycle` do not need the latter implementation,
+// as they will raise an fatal error on query cycles instead.
+rustc_queries! {
+ Other {
+ /// Records the type of every item.
+ query type_of(key: DefId) -> Ty<'tcx> {
+ cache { key.is_local() }
+ }
+
+ /// Maps from the `DefId` of an item (trait/struct/enum/fn) to its
+ /// associated generics.
+ query generics_of(key: DefId) -> &'tcx ty::Generics {
+ cache { key.is_local() }
+ load_cached(tcx, id) {
+ let generics: Option<ty::Generics> = tcx.queries.on_disk_cache
+ .try_load_query_result(tcx, id);
+ generics.map(|x| tcx.alloc_generics(x))
+ }
+ }
+
+ /// Maps from the `DefId` of an item (trait/struct/enum/fn) to the
+ /// predicates (where-clauses) that must be proven true in order
+ /// to reference it. This is almost always the "predicates query"
+ /// that you want.
+ ///
+ /// `predicates_of` builds on `predicates_defined_on` -- in fact,
+ /// it is almost always the same as that query, except for the
+ /// case of traits. For traits, `predicates_of` contains
+ /// an additional `Self: Trait<...>` predicate that users don't
+ /// actually write. This reflects the fact that to invoke the
+ /// trait (e.g., via `Default::default`) you must supply types
+ /// that actually implement the trait. (However, this extra
+ /// predicate gets in the way of some checks, which are intended
+ /// to operate over only the actual where-clauses written by the
+ /// user.)
+ query predicates_of(_: DefId) -> Lrc<ty::GenericPredicates<'tcx>> {}
+
+ query native_libraries(_: CrateNum) -> Lrc<Vec<NativeLibrary>> {
+ desc { "looking up the native libraries of a linked crate" }
+ }
+ }
+
+ Codegen {
+ query is_panic_runtime(_: CrateNum) -> bool {
+ fatal_cycle
+ desc { "checking if the crate is_panic_runtime" }
+ }
+ }
+}
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 55c4b0e..0ae7c10 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -800,6 +800,7 @@
pub const parse_opt_pathbuf: Option<&str> = Some("a path");
pub const parse_list: Option<&str> = Some("a space-separated list of strings");
pub const parse_opt_list: Option<&str> = Some("a space-separated list of strings");
+ pub const parse_opt_comma_list: Option<&str> = Some("a comma-separated list of strings");
pub const parse_uint: Option<&str> = Some("a number");
pub const parse_passes: Option<&str> =
Some("a space-separated list of passes, or `all`");
@@ -926,6 +927,18 @@
}
}
+ fn parse_opt_comma_list(slot: &mut Option<Vec<String>>, v: Option<&str>)
+ -> bool {
+ match v {
+ Some(s) => {
+ let v = s.split(',').map(|s| s.to_string()).collect();
+ *slot = Some(v);
+ true
+ },
+ None => false,
+ }
+ }
+
fn parse_uint(slot: &mut usize, v: Option<&str>) -> bool {
match v.and_then(|s| s.parse().ok()) {
Some(i) => { *slot = i; true },
@@ -1427,6 +1440,8 @@
merge_functions: Option<MergeFunctions> = (None, parse_merge_functions, [TRACKED],
"control the operation of the MergeFunctions LLVM pass, taking
the same values as the target option of the same name"),
+ allow_features: Option<Vec<String>> = (None, parse_opt_comma_list, [TRACKED],
+ "only allow the listed language features to be enabled in code (space separated)"),
}
pub fn default_lib_output() -> CrateType {
@@ -1824,7 +1839,7 @@
match &mut parser.parse_meta_item() {
Ok(meta_item) if parser.token == token::Eof => {
- if meta_item.ident.segments.len() != 1 {
+ if meta_item.path.segments.len() != 1 {
error!("argument key must be an identifier");
}
match &meta_item.node {
@@ -1835,7 +1850,8 @@
error!("argument value must be a string");
}
MetaItemKind::NameValue(..) | MetaItemKind::Word => {
- return (meta_item.name(), meta_item.value_str());
+ let ident = meta_item.ident().expect("multi-segment cfg key");
+ return (ident.name, meta_item.value_str());
}
}
}
@@ -3273,6 +3289,10 @@
opts = reference.clone();
opts.debugging_opts.merge_functions = Some(MergeFunctions::Disabled);
assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
+
+ opts = reference.clone();
+ opts.debugging_opts.allow_features = Some(vec![String::from("lang_items")]);
+ assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
}
#[test]
diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs
index fc0058a..d0acaf6 100644
--- a/src/librustc/traits/on_unimplemented.rs
+++ b/src/librustc/traits/on_unimplemented.rs
@@ -107,7 +107,7 @@
{
if let Some(items) = item.meta_item_list() {
if let Ok(subcommand) =
- Self::parse(tcx, trait_def_id, &items, item.span, false)
+ Self::parse(tcx, trait_def_id, &items, item.span(), false)
{
subcommands.push(subcommand);
} else {
@@ -118,7 +118,7 @@
}
// nothing found
- parse_error(tcx, item.span,
+ parse_error(tcx, item.span(),
"this attribute must have a valid value",
"expected value here",
Some(r#"eg `#[rustc_on_unimplemented(message="foo")]`"#));
@@ -177,10 +177,12 @@
for command in self.subcommands.iter().chain(Some(self)).rev() {
if let Some(ref condition) = command.condition {
if !attr::eval_condition(condition, &tcx.sess.parse_sess, &mut |c| {
- options.contains(&(
- c.name().as_str().to_string(),
- c.value_str().map(|s| s.as_str().to_string())
- ))
+ c.ident_str().map_or(false, |name| {
+ options.contains(&(
+ name.to_string(),
+ c.value_str().map(|s| s.as_str().to_string())
+ ))
+ })
}) {
debug!("evaluate: skipping {:?} due to condition", command);
continue
diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs
index ab6acc6..360e232 100644
--- a/src/librustc/traits/project.rs
+++ b/src/librustc/traits/project.rs
@@ -15,7 +15,7 @@
use crate::hir::def_id::DefId;
use crate::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime};
use crate::infer::type_variable::TypeVariableOrigin;
-use crate::mir::interpret::{GlobalId};
+use crate::mir::interpret::{GlobalId, ConstValue};
use rustc_data_structures::snapshot_map::{Snapshot, SnapshotMap};
use rustc_macros::HashStable;
use syntax::ast::Ident;
@@ -397,8 +397,8 @@
}
}
- fn fold_const(&mut self, constant: &'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> {
- if let ty::LazyConst::Unevaluated(def_id, substs) = *constant {
+ fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
+ if let ConstValue::Unevaluated(def_id, substs) = constant.val {
let tcx = self.selcx.tcx().global_tcx();
if let Some(param_env) = self.tcx().lift_to_global(&self.param_env) {
if substs.needs_infer() || substs.has_placeholders() {
@@ -411,8 +411,9 @@
};
if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) {
let substs = tcx.lift_to_global(&substs).unwrap();
+ let evaluated = tcx.mk_const(evaluated);
let evaluated = evaluated.subst(tcx, substs);
- return tcx.mk_lazy_const(ty::LazyConst::Evaluated(evaluated));
+ return evaluated;
}
}
} else {
@@ -424,7 +425,7 @@
promoted: None
};
if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) {
- return tcx.mk_lazy_const(ty::LazyConst::Evaluated(evaluated));
+ return tcx.mk_const(evaluated);
}
}
}
diff --git a/src/librustc/traits/query/normalize.rs b/src/librustc/traits/query/normalize.rs
index 8a30c18..9940249 100644
--- a/src/librustc/traits/query/normalize.rs
+++ b/src/librustc/traits/query/normalize.rs
@@ -5,7 +5,7 @@
use crate::infer::at::At;
use crate::infer::canonical::OriginalQueryValues;
use crate::infer::{InferCtxt, InferOk};
-use crate::mir::interpret::GlobalId;
+use crate::mir::interpret::{GlobalId, ConstValue};
use crate::traits::project::Normalized;
use crate::traits::{Obligation, ObligationCause, PredicateObligation, Reveal};
use crate::ty::fold::{TypeFoldable, TypeFolder};
@@ -188,8 +188,8 @@
}
}
- fn fold_const(&mut self, constant: &'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> {
- if let ty::LazyConst::Unevaluated(def_id, substs) = *constant {
+ fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
+ if let ConstValue::Unevaluated(def_id, substs) = constant.val {
let tcx = self.infcx.tcx.global_tcx();
if let Some(param_env) = self.tcx().lift_to_global(&self.param_env) {
if substs.needs_infer() || substs.has_placeholders() {
@@ -202,8 +202,9 @@
};
if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) {
let substs = tcx.lift_to_global(&substs).unwrap();
+ let evaluated = tcx.mk_const(evaluated);
let evaluated = evaluated.subst(tcx, substs);
- return tcx.mk_lazy_const(ty::LazyConst::Evaluated(evaluated));
+ return evaluated;
}
}
} else {
@@ -215,7 +216,7 @@
promoted: None,
};
if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) {
- return tcx.mk_lazy_const(ty::LazyConst::Evaluated(evaluated));
+ return tcx.mk_const(evaluated);
}
}
}
diff --git a/src/librustc/ty/codec.rs b/src/librustc/ty/codec.rs
index 3ab744e..e747434 100644
--- a/src/librustc/ty/codec.rs
+++ b/src/librustc/ty/codec.rs
@@ -247,12 +247,12 @@
}
#[inline]
-pub fn decode_lazy_const<'a, 'tcx, D>(decoder: &mut D)
- -> Result<&'tcx ty::LazyConst<'tcx>, D::Error>
+pub fn decode_const<'a, 'tcx, D>(decoder: &mut D)
+ -> Result<&'tcx ty::Const<'tcx>, D::Error>
where D: TyDecoder<'a, 'tcx>,
'tcx: 'a,
{
- Ok(decoder.tcx().mk_lazy_const(Decodable::decode(decoder)?))
+ Ok(decoder.tcx().mk_const(Decodable::decode(decoder)?))
}
#[inline]
@@ -389,10 +389,10 @@
}
}
- impl<$($typaram),*> SpecializedDecoder<&'tcx $crate::ty::LazyConst<'tcx>>
+ impl<$($typaram),*> SpecializedDecoder<&'tcx $crate::ty::Const<'tcx>>
for $DecoderName<$($typaram),*> {
- fn specialized_decode(&mut self) -> Result<&'tcx ty::LazyConst<'tcx>, Self::Error> {
- decode_lazy_const(self)
+ fn specialized_decode(&mut self) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
+ decode_const(self)
}
}
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 1942f98..6de0a39 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -28,7 +28,7 @@
use crate::traits::{Clause, Clauses, GoalKind, Goal, Goals};
use crate::ty::{self, DefIdTree, Ty, TypeAndMut};
use crate::ty::{TyS, TyKind, List};
-use crate::ty::{AdtKind, AdtDef, ClosureSubsts, GeneratorSubsts, Region, Const, LazyConst};
+use crate::ty::{AdtKind, AdtDef, ClosureSubsts, GeneratorSubsts, Region, Const};
use crate::ty::{PolyFnSig, InferTy, ParamTy, ProjectionTy, ExistentialPredicate, Predicate};
use crate::ty::RegionKind;
use crate::ty::{TyVar, TyVid, IntVar, IntVid, FloatVar, FloatVid, ConstVid};
@@ -126,7 +126,7 @@
goal: InternedSet<'tcx, GoalKind<'tcx>>,
goal_list: InternedSet<'tcx, List<Goal<'tcx>>>,
projs: InternedSet<'tcx, List<ProjectionKind<'tcx>>>,
- lazy_const: InternedSet<'tcx, LazyConst<'tcx>>,
+ const_: InternedSet<'tcx, Const<'tcx>>,
}
impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
@@ -144,7 +144,7 @@
goal: Default::default(),
goal_list: Default::default(),
projs: Default::default(),
- lazy_const: Default::default(),
+ const_: Default::default(),
}
}
@@ -874,14 +874,11 @@
_ => false,
},
- UnpackedKind::Const(ct) => match ct {
- ty::LazyConst::Evaluated(ty::Const {
- val: ConstValue::Infer(InferConst::Canonical(debruijn, b)),
- ..
- }) => {
+ UnpackedKind::Const(ct) => match ct.val {
+ ConstValue::Infer(InferConst::Canonical(debruijn, b)) => {
// We only allow a `ty::INNERMOST` index in substitutions.
- assert_eq!(*debruijn, ty::INNERMOST);
- cvar == *b
+ assert_eq!(debruijn, ty::INNERMOST);
+ cvar == b
}
_ => false,
},
@@ -1788,7 +1785,7 @@
nop_lift!{Ty<'a> => Ty<'tcx>}
nop_lift!{Region<'a> => Region<'tcx>}
nop_lift!{Goal<'a> => Goal<'tcx>}
-nop_lift!{&'a LazyConst<'a> => &'tcx LazyConst<'tcx>}
+nop_lift!{&'a Const<'a> => &'tcx Const<'tcx>}
nop_list_lift!{Goal<'a> => Goal<'tcx>}
nop_list_lift!{Clause<'a> => Clause<'tcx>}
@@ -2274,12 +2271,6 @@
}
}
-impl<'tcx: 'lcx, 'lcx> Borrow<LazyConst<'lcx>> for Interned<'tcx, LazyConst<'tcx>> {
- fn borrow<'a>(&'a self) -> &'a LazyConst<'lcx> {
- &self.0
- }
-}
-
impl<'tcx: 'lcx, 'lcx> Borrow<[ExistentialPredicate<'lcx>]>
for Interned<'tcx, List<ExistentialPredicate<'tcx>>> {
fn borrow<'a>(&'a self) -> &'a [ExistentialPredicate<'lcx>] {
@@ -2387,7 +2378,7 @@
direct_interners!('tcx,
region: mk_region(|r: &RegionKind| r.keep_in_local_tcx()) -> RegionKind,
goal: mk_goal(|c: &GoalKind<'_>| keep_local(c)) -> GoalKind<'tcx>,
- lazy_const: mk_lazy_const(|c: &LazyConst<'_>| keep_local(&c)) -> LazyConst<'tcx>
+ const_: mk_const(|c: &Const<'_>| keep_local(&c)) -> Const<'tcx>
);
macro_rules! slice_interners {
@@ -2575,8 +2566,8 @@
#[inline]
pub fn mk_array(self, ty: Ty<'tcx>, n: u64) -> Ty<'tcx> {
- self.mk_ty(Array(ty, self.mk_lazy_const(
- ty::LazyConst::Evaluated(ty::Const::from_usize(self.global_tcx(), n))
+ self.mk_ty(Array(ty, self.mk_const(
+ ty::Const::from_usize(self.global_tcx(), n)
)))
}
@@ -2670,11 +2661,11 @@
}
#[inline]
- pub fn mk_const_var(self, v: ConstVid<'tcx>, ty: Ty<'tcx>) -> &'tcx LazyConst<'tcx> {
- self.mk_lazy_const(LazyConst::Evaluated(ty::Const {
+ pub fn mk_const_var(self, v: ConstVid<'tcx>, ty: Ty<'tcx>) -> &'tcx Const<'tcx> {
+ self.mk_const(ty::Const {
val: ConstValue::Infer(InferConst::Var(v)),
ty,
- }))
+ })
}
#[inline]
@@ -2705,11 +2696,11 @@
index: u32,
name: InternedString,
ty: Ty<'tcx>
- ) -> &'tcx LazyConst<'tcx> {
- self.mk_lazy_const(LazyConst::Evaluated(ty::Const {
+ ) -> &'tcx Const<'tcx> {
+ self.mk_const(ty::Const {
val: ConstValue::Param(ParamConst { index, name }),
ty,
- }))
+ })
}
#[inline]
diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs
index fa3c76a..74d0a29 100644
--- a/src/librustc/ty/error.rs
+++ b/src/librustc/ty/error.rs
@@ -176,12 +176,9 @@
ty::Adt(def, _) => format!("{} `{}`", def.descr(), tcx.def_path_str(def.did)).into(),
ty::Foreign(def_id) => format!("extern type `{}`", tcx.def_path_str(def_id)).into(),
- ty::Array(_, n) => match n {
- ty::LazyConst::Evaluated(n) => match n.assert_usize(tcx) {
- Some(n) => format!("array of {} elements", n).into(),
- None => "array".into(),
- },
- ty::LazyConst::Unevaluated(..) => "array".into(),
+ ty::Array(_, n) => match n.assert_usize(tcx) {
+ Some(n) => format!("array of {} elements", n).into(),
+ None => "array".into(),
}
ty::Slice(_) => "slice".into(),
ty::RawPtr(_) => "*-ptr".into(),
diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs
index 64ceb97..7aed2a4 100644
--- a/src/librustc/ty/flags.rs
+++ b/src/librustc/ty/flags.rs
@@ -24,6 +24,12 @@
result
}
+ pub fn for_const(c: &ty::Const<'_>) -> TypeFlags {
+ let mut result = FlagComputation::new();
+ result.add_const(c);
+ result.flags
+ }
+
fn add_flags(&mut self, flags: TypeFlags) {
self.flags = self.flags | (flags & TypeFlags::NOMINAL_FLAGS);
}
@@ -173,10 +179,7 @@
&ty::Array(tt, len) => {
self.add_ty(tt);
- if let ty::LazyConst::Unevaluated(_, substs) = len {
- self.add_flags(TypeFlags::HAS_PROJECTION);
- self.add_substs(substs);
- }
+ self.add_const(len);
}
&ty::Slice(tt) => {
@@ -233,19 +236,26 @@
}
}
- fn add_const(&mut self, c: &ty::LazyConst<'_>) {
- match c {
- ty::LazyConst::Unevaluated(_, substs) => self.add_substs(substs),
- // Only done to add the binder for the type. The type flags are
- // included in `Const::type_flags`.
- ty::LazyConst::Evaluated(ty::Const { ty, val }) => {
- self.add_ty(ty);
- if let ConstValue::Infer(InferConst::Canonical(debruijn, _)) = val {
- self.add_binder(*debruijn)
+ fn add_const(&mut self, c: &ty::Const<'_>) {
+ self.add_ty(c.ty);
+ match c.val {
+ ConstValue::Unevaluated(_, substs) => {
+ self.add_substs(substs);
+ self.add_flags(TypeFlags::HAS_NORMALIZABLE_PROJECTION | TypeFlags::HAS_PROJECTION);
+ },
+ ConstValue::Infer(infer) => {
+ self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES | TypeFlags::HAS_CT_INFER);
+ match infer {
+ InferConst::Fresh(_) => {}
+ InferConst::Canonical(debruijn, _) => self.add_binder(debruijn),
+ InferConst::Var(_) => self.add_flags(TypeFlags::KEEP_IN_LOCAL_TCX),
}
}
+ ConstValue::Param(_) => {
+ self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES | TypeFlags::HAS_PARAMS);
+ }
+ _ => {},
}
- self.add_flags(c.type_flags());
}
fn add_existential_projection(&mut self, projection: &ty::ExistentialProjection<'_>) {
diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs
index 7f77d03..321e552 100644
--- a/src/librustc/ty/fold.rs
+++ b/src/librustc/ty/fold.rs
@@ -32,7 +32,7 @@
//! looking for, and does not need to visit anything else.
use crate::hir::def_id::DefId;
-use crate::ty::{self, Binder, Ty, TyCtxt, TypeFlags};
+use crate::ty::{self, Binder, Ty, TyCtxt, TypeFlags, flags::FlagComputation};
use std::collections::BTreeMap;
use std::fmt;
@@ -167,7 +167,7 @@
r.super_fold_with(self)
}
- fn fold_const(&mut self, c: &'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> {
+ fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
c.super_fold_with(self)
}
}
@@ -185,7 +185,7 @@
r.super_visit_with(self)
}
- fn visit_const(&mut self, c: &'tcx ty::LazyConst<'tcx>) -> bool {
+ fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> bool {
c.super_visit_with(self)
}
}
@@ -842,14 +842,10 @@
flags.intersects(self.flags)
}
- fn visit_const(&mut self, c: &'tcx ty::LazyConst<'tcx>) -> bool {
- let flags = c.type_flags();
+ fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> bool {
+ let flags = FlagComputation::for_const(c);
debug!("HasTypeFlagsVisitor: c={:?} c.flags={:?} self.flags={:?}", c, flags, self.flags);
- if flags.intersects(self.flags) {
- true
- } else {
- c.super_visit_with(self)
- }
+ flags.intersects(self.flags) || c.super_visit_with(self)
}
}
diff --git a/src/librustc/ty/inhabitedness/mod.rs b/src/librustc/ty/inhabitedness/mod.rs
index 33ec9c8..d732f3f 100644
--- a/src/librustc/ty/inhabitedness/mod.rs
+++ b/src/librustc/ty/inhabitedness/mod.rs
@@ -1,6 +1,6 @@
use crate::ty::context::TyCtxt;
use crate::ty::{AdtDef, VariantDef, FieldDef, Ty, TyS};
-use crate::ty::{self, DefId, SubstsRef};
+use crate::ty::{DefId, SubstsRef};
use crate::ty::{AdtKind, Visibility};
use crate::ty::TyKind::*;
@@ -212,17 +212,12 @@
}))
}
- Array(ty, len) => {
- match len {
- ty::LazyConst::Unevaluated(..) => DefIdForest::empty(),
- ty::LazyConst::Evaluated(len) => match len.assert_usize(tcx) {
- // If the array is definitely non-empty, it's uninhabited if
- // the type of its elements is uninhabited.
- Some(n) if n != 0 => ty.uninhabited_from(tcx),
- _ => DefIdForest::empty()
- },
- }
- }
+ Array(ty, len) => match len.assert_usize(tcx) {
+ // If the array is definitely non-empty, it's uninhabited if
+ // the type of its elements is uninhabited.
+ Some(n) if n != 0 => ty.uninhabited_from(tcx),
+ _ => DefIdForest::empty()
+ },
// References to uninitialised memory is valid for any type, including
// uninhabited types, in unsafe code, so we treat all references as
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 882e2dc..91b84b6 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -59,7 +59,7 @@
pub use self::sty::{ClosureSubsts, GeneratorSubsts, UpvarSubsts, TypeAndMut};
pub use self::sty::{TraitRef, TyKind, PolyTraitRef};
pub use self::sty::{ExistentialTraitRef, PolyExistentialTraitRef};
-pub use self::sty::{ExistentialProjection, PolyExistentialProjection, Const, LazyConst};
+pub use self::sty::{ExistentialProjection, PolyExistentialProjection, Const};
pub use self::sty::{BoundRegion, EarlyBoundRegion, FreeRegion, Region};
pub use self::sty::RegionKind;
pub use self::sty::{TyVid, IntVid, FloatVid, ConstVid, RegionVid};
@@ -1811,6 +1811,7 @@
pub fields: Vec<FieldDef>,
pub ctor_kind: CtorKind,
flags: VariantFlags,
+ pub recovered: bool,
}
impl<'a, 'gcx, 'tcx> VariantDef {
@@ -1829,16 +1830,17 @@
///
/// If someone speeds up attribute loading to not be a performance concern, they can
/// remove this hack and use the constructor `DefId` everywhere.
- pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
- did: DefId,
- ident: Ident,
- discr: VariantDiscr,
- fields: Vec<FieldDef>,
- adt_kind: AdtKind,
- ctor_kind: CtorKind,
- attribute_def_id: DefId)
- -> Self
- {
+ pub fn new(
+ tcx: TyCtxt<'a, 'gcx, 'tcx>,
+ did: DefId,
+ ident: Ident,
+ discr: VariantDiscr,
+ fields: Vec<FieldDef>,
+ adt_kind: AdtKind,
+ ctor_kind: CtorKind,
+ attribute_def_id: DefId,
+ recovered: bool,
+ ) -> Self {
debug!("VariantDef::new({:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?})", did, ident, discr,
fields, adt_kind, ctor_kind, attribute_def_id);
let mut flags = VariantFlags::NO_VARIANT_FLAGS;
@@ -1852,7 +1854,8 @@
discr,
fields,
ctor_kind,
- flags
+ flags,
+ recovered,
}
}
@@ -1868,7 +1871,8 @@
discr,
fields,
ctor_kind,
- flags
+ flags,
+ recovered
});
#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs
index fa57e0b..7701a10 100644
--- a/src/librustc/ty/print/pretty.rs
+++ b/src/librustc/ty/print/pretty.rs
@@ -660,18 +660,12 @@
},
ty::Array(ty, sz) => {
p!(write("["), print(ty), write("; "));
- match sz {
- ty::LazyConst::Unevaluated(_def_id, _substs) => {
- p!(write("_"));
- }
- ty::LazyConst::Evaluated(c) => {
- match c.val {
- ConstValue::Infer(..) => p!(write("_")),
- ConstValue::Param(ParamConst { name, .. }) =>
- p!(write("{}", name)),
- _ => p!(write("{}", c.unwrap_usize(self.tcx()))),
- }
- }
+ match sz.val {
+ ConstValue::Unevaluated(..) |
+ ConstValue::Infer(..) => p!(write("_")),
+ ConstValue::Param(ParamConst { name, .. }) =>
+ p!(write("{}", name)),
+ _ => p!(write("{}", sz.unwrap_usize(self.tcx()))),
}
p!(write("]"))
}
@@ -1533,26 +1527,15 @@
p!(print_def_path(self.def_id, self.substs));
}
- ConstValue<'tcx> {
- match self {
+ &'tcx ty::Const<'tcx> {
+ match self.val {
+ ConstValue::Unevaluated(..) |
ConstValue::Infer(..) => p!(write("_")),
ConstValue::Param(ParamConst { name, .. }) => p!(write("{}", name)),
_ => p!(write("{:?}", self)),
}
}
- ty::Const<'tcx> {
- p!(write("{} : {}", self.val, self.ty))
- }
-
- &'tcx ty::LazyConst<'tcx> {
- match self {
- // FIXME(const_generics) this should print at least the type.
- ty::LazyConst::Unevaluated(..) => p!(write("_ : _")),
- ty::LazyConst::Evaluated(c) => p!(write("{}", c)),
- }
- }
-
ty::ParamTy {
p!(write("{}", self.name))
}
diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs
index 395b288..d8159f1 100644
--- a/src/librustc/ty/query/config.rs
+++ b/src/librustc/ty/query/config.rs
@@ -34,7 +34,7 @@
type Value: Clone;
}
-pub(super) trait QueryAccessors<'tcx>: QueryConfig<'tcx> {
+pub(crate) trait QueryAccessors<'tcx>: QueryConfig<'tcx> {
fn query(key: Self::Key) -> Query<'tcx>;
// Don't use this method to access query results, instead use the methods on TyCtxt
@@ -53,7 +53,7 @@
fn handle_cycle_error(tcx: TyCtxt<'_, 'tcx, '_>, error: CycleError<'tcx>) -> Self::Value;
}
-pub(super) trait QueryDescription<'tcx>: QueryAccessors<'tcx> {
+pub(crate) trait QueryDescription<'tcx>: QueryAccessors<'tcx> {
fn describe(tcx: TyCtxt<'_, '_, '_>, key: Self::Key) -> Cow<'static, str>;
#[inline]
@@ -587,12 +587,6 @@
}
}
-impl<'tcx> QueryDescription<'tcx> for queries::is_panic_runtime<'tcx> {
- fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
- "checking if the crate is_panic_runtime".into()
- }
-}
-
impl<'tcx> QueryDescription<'tcx> for queries::is_compiler_builtins<'tcx> {
fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
"checking if the crate is_compiler_builtins".into()
@@ -671,12 +665,6 @@
}
}
-impl<'tcx> QueryDescription<'tcx> for queries::native_libraries<'tcx> {
- fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
- "looking up the native libraries of a linked crate".into()
- }
-}
-
impl<'tcx> QueryDescription<'tcx> for queries::foreign_modules<'tcx> {
fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
"looking up the foreign modules of a linked crate".into()
@@ -949,21 +937,6 @@
}
}
-impl<'tcx> QueryDescription<'tcx> for queries::generics_of<'tcx> {
- #[inline]
- fn cache_on_disk(_: TyCtxt<'_, 'tcx, 'tcx>, def_id: Self::Key) -> bool {
- def_id.is_local()
- }
-
- fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
- id: SerializedDepNodeIndex)
- -> Option<Self::Value> {
- let generics: Option<ty::Generics> = tcx.queries.on_disk_cache
- .try_load_query_result(tcx, id);
- generics.map(|x| tcx.alloc_generics(x))
- }
-}
-
impl<'tcx> QueryDescription<'tcx> for queries::program_clauses_for<'tcx> {
fn describe(_tcx: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> {
"generating chalk-style clauses".into()
@@ -1027,7 +1000,6 @@
impl_disk_cacheable_query!(mir_const_qualif, |_, def_id| def_id.is_local());
impl_disk_cacheable_query!(check_match, |_, def_id| def_id.is_local());
impl_disk_cacheable_query!(def_symbol_name, |_, _| true);
-impl_disk_cacheable_query!(type_of, |_, def_id| def_id.is_local());
impl_disk_cacheable_query!(predicates_of, |_, def_id| def_id.is_local());
impl_disk_cacheable_query!(used_trait_imports, |_, def_id| def_id.is_local());
impl_disk_cacheable_query!(codegen_fn_attrs, |_, _| true);
diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs
index 8804ed2..2f085a9 100644
--- a/src/librustc/ty/query/mod.rs
+++ b/src/librustc/ty/query/mod.rs
@@ -80,13 +80,14 @@
use self::values::Value;
mod config;
+pub(crate) use self::config::QueryDescription;
pub use self::config::QueryConfig;
-use self::config::{QueryAccessors, QueryDescription};
+use self::config::QueryAccessors;
mod on_disk_cache;
pub use self::on_disk_cache::OnDiskCache;
-// Each of these quries corresponds to a function pointer field in the
+// Each of these queries corresponds to a function pointer field in the
// `Providers` struct for requesting a value of that type, and a method
// on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way
// which memoizes and does dep-graph tracking, wrapping around the actual
@@ -97,35 +98,12 @@
// (error) value if the query resulted in a query cycle.
// Queries marked with `fatal_cycle` do not need the latter implementation,
// as they will raise an fatal error on query cycles instead.
-define_queries! { <'tcx>
+
+rustc_query_append! { [define_queries!][ <'tcx>
Other {
/// Run analysis passes on the crate
[] fn analysis: Analysis(CrateNum) -> Result<(), ErrorReported>,
- /// Records the type of every item.
- [] fn type_of: TypeOfItem(DefId) -> Ty<'tcx>,
-
- /// Maps from the `DefId` of an item (trait/struct/enum/fn) to its
- /// associated generics.
- [] fn generics_of: GenericsOfItem(DefId) -> &'tcx ty::Generics,
-
- /// Maps from the `DefId` of an item (trait/struct/enum/fn) to the
- /// predicates (where-clauses) that must be proven true in order
- /// to reference it. This is almost always the "predicates query"
- /// that you want.
- ///
- /// `predicates_of` builds on `predicates_defined_on` -- in fact,
- /// it is almost always the same as that query, except for the
- /// case of traits. For traits, `predicates_of` contains
- /// an additional `Self: Trait<...>` predicate that users don't
- /// actually write. This reflects the fact that to invoke the
- /// trait (e.g., via `Default::default`) you must supply types
- /// that actually implement the trait. (However, this extra
- /// predicate gets in the way of some checks, which are intended
- /// to operate over only the actual where-clauses written by the
- /// user.)
- [] fn predicates_of: PredicatesOfItem(DefId) -> Lrc<ty::GenericPredicates<'tcx>>,
-
/// Maps from the `DefId` of an item (trait/struct/enum/fn) to the
/// predicates (where-clauses) directly defined on it. This is
/// equal to the `explicit_predicates_of` predicates plus the
@@ -446,7 +424,6 @@
},
Codegen {
- [fatal_cycle] fn is_panic_runtime: IsPanicRuntime(CrateNum) -> bool,
[fatal_cycle] fn is_compiler_builtins: IsCompilerBuiltins(CrateNum) -> bool,
[fatal_cycle] fn has_global_allocator: HasGlobalAllocator(CrateNum) -> bool,
[fatal_cycle] fn has_panic_handler: HasPanicHandler(CrateNum) -> bool,
@@ -504,8 +481,6 @@
},
Other {
- [] fn native_libraries: NativeLibraries(CrateNum) -> Lrc<Vec<NativeLibrary>>,
-
[] fn foreign_modules: ForeignModules(CrateNum) -> Lrc<Vec<ForeignModule>>,
/// Identifies the entry-point (e.g., the `main` function) for a given
@@ -752,7 +727,7 @@
[] fn wasm_import_module_map: WasmImportModuleMap(CrateNum)
-> Lrc<FxHashMap<DefId, String>>,
},
-}
+]}
//////////////////////////////////////////////////////////////////////
// These functions are little shims used to find the dep-node for a
diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs
index cff99f2..e82e09c 100644
--- a/src/librustc/ty/query/plumbing.rs
+++ b/src/librustc/ty/query/plumbing.rs
@@ -1131,10 +1131,12 @@
/// then `force_from_dep_node()` should not fail for it. Otherwise, you can just
/// add it to the "We don't have enough information to reconstruct..." group in
/// the match below.
-pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
- dep_node: &DepNode)
- -> bool {
+pub fn force_from_dep_node<'tcx>(
+ tcx: TyCtxt<'_, 'tcx, 'tcx>,
+ dep_node: &DepNode
+) -> bool {
use crate::hir::def_id::LOCAL_CRATE;
+ use crate::dep_graph::RecoverKey;
// We must avoid ever having to call force_from_dep_node() for a
// DepNode::CodegenUnit:
@@ -1171,17 +1173,26 @@
() => { (def_id!()).krate }
};
- macro_rules! force {
- ($query:ident, $key:expr) => {
+ macro_rules! force_ex {
+ ($tcx:expr, $query:ident, $key:expr) => {
{
- tcx.force_query::<crate::ty::query::queries::$query<'_>>($key, DUMMY_SP, *dep_node);
+ $tcx.force_query::<crate::ty::query::queries::$query<'_>>(
+ $key,
+ DUMMY_SP,
+ *dep_node
+ );
}
}
};
+ macro_rules! force {
+ ($query:ident, $key:expr) => { force_ex!(tcx, $query, $key) }
+ };
+
// FIXME(#45015): We should try move this boilerplate code into a macro
// somehow.
- match dep_node.kind {
+
+ rustc_dep_node_force!([dep_node, tcx]
// These are inputs that are expected to be pre-allocated and that
// should therefore always be red or green already
DepKind::AllLocalTraitImpls |
@@ -1274,9 +1285,6 @@
DepKind::MirKeys => { force!(mir_keys, LOCAL_CRATE); }
DepKind::CrateVariances => { force!(crate_variances, LOCAL_CRATE); }
DepKind::AssociatedItems => { force!(associated_item, def_id!()); }
- DepKind::TypeOfItem => { force!(type_of, def_id!()); }
- DepKind::GenericsOfItem => { force!(generics_of, def_id!()); }
- DepKind::PredicatesOfItem => { force!(predicates_of, def_id!()); }
DepKind::PredicatesDefinedOnItem => { force!(predicates_defined_on, def_id!()); }
DepKind::ExplicitPredicatesOfItem => { force!(explicit_predicates_of, def_id!()); }
DepKind::InferredOutlivesOf => { force!(inferred_outlives_of, def_id!()); }
@@ -1332,7 +1340,6 @@
DepKind::FnArgNames => { force!(fn_arg_names, def_id!()); }
DepKind::RenderedConst => { force!(rendered_const, def_id!()); }
DepKind::DylibDepFormats => { force!(dylib_dependency_formats, krate!()); }
- DepKind::IsPanicRuntime => { force!(is_panic_runtime, krate!()); }
DepKind::IsCompilerBuiltins => { force!(is_compiler_builtins, krate!()); }
DepKind::HasGlobalAllocator => { force!(has_global_allocator, krate!()); }
DepKind::HasPanicHandler => { force!(has_panic_handler, krate!()); }
@@ -1349,7 +1356,6 @@
DepKind::CheckTraitItemWellFormed => { force!(check_trait_item_well_formed, def_id!()); }
DepKind::CheckImplItemWellFormed => { force!(check_impl_item_well_formed, def_id!()); }
DepKind::ReachableNonGenerics => { force!(reachable_non_generics, krate!()); }
- DepKind::NativeLibraries => { force!(native_libraries, krate!()); }
DepKind::EntryFn => { force!(entry_fn, krate!()); }
DepKind::PluginRegistrarFn => { force!(plugin_registrar_fn, krate!()); }
DepKind::ProcMacroDeclsStatic => { force!(proc_macro_decls_static, krate!()); }
@@ -1432,7 +1438,7 @@
DepKind::BackendOptimizationLevel => {
force!(backend_optimization_level, krate!());
}
- }
+ );
true
}
@@ -1493,9 +1499,9 @@
SymbolName => def_symbol_name,
ConstIsRvaluePromotableToStatic => const_is_rvalue_promotable_to_static,
CheckMatch => check_match,
- TypeOfItem => type_of,
- GenericsOfItem => generics_of,
- PredicatesOfItem => predicates_of,
+ type_of => type_of,
+ generics_of => generics_of,
+ predicates_of => predicates_of,
UsedTraitImports => used_trait_imports,
CodegenFnAttrs => codegen_fn_attrs,
SpecializationGraph => specialization_graph_of,
diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs
index b245d90..810bd10 100644
--- a/src/librustc/ty/relate.rs
+++ b/src/librustc/ty/relate.rs
@@ -8,7 +8,7 @@
use crate::ty::subst::{Kind, UnpackedKind, SubstsRef};
use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
use crate::ty::error::{ExpectedFound, TypeError};
-use crate::mir::interpret::GlobalId;
+use crate::mir::interpret::{GlobalId, ConstValue};
use crate::util::common::ErrorReported;
use syntax_pos::DUMMY_SP;
use std::rc::Rc;
@@ -466,9 +466,9 @@
(&ty::Array(a_t, sz_a), &ty::Array(b_t, sz_b)) =>
{
let t = relation.relate(&a_t, &b_t)?;
- let to_u64 = |x: ty::LazyConst<'tcx>| -> Result<u64, ErrorReported> {
- match x {
- ty::LazyConst::Unevaluated(def_id, substs) => {
+ let to_u64 = |x: ty::Const<'tcx>| -> Result<u64, ErrorReported> {
+ match x.val {
+ ConstValue::Unevaluated(def_id, substs) => {
// FIXME(eddyb) get the right param_env.
let param_env = ty::ParamEnv::empty();
if let Some(substs) = tcx.lift_to_global(&substs) {
@@ -494,7 +494,7 @@
"array length could not be evaluated");
Err(ErrorReported)
}
- ty::LazyConst::Evaluated(c) => c.assert_usize(tcx).ok_or_else(|| {
+ _ => x.assert_usize(tcx).ok_or_else(|| {
tcx.sess.delay_span_bug(DUMMY_SP,
"array length could not be evaluated");
ErrorReported
diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs
index ecfb034..cbdda73 100644
--- a/src/librustc/ty/structural_impls.rs
+++ b/src/librustc/ty/structural_impls.rs
@@ -6,7 +6,7 @@
use crate::hir::def::Namespace;
use crate::mir::ProjectionKind;
use crate::mir::interpret::ConstValue;
-use crate::ty::{self, Lift, Ty, TyCtxt, ConstVid, InferConst};
+use crate::ty::{self, Lift, Ty, TyCtxt, ConstVid};
use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
use crate::ty::print::{FmtPrinter, Printer};
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
@@ -794,34 +794,6 @@
}
}
-BraceStructLiftImpl! {
- impl<'a, 'tcx> Lift<'tcx> for ty::Const<'a> {
- type Lifted = ty::Const<'tcx>;
- val, ty
- }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ConstValue<'a> {
- type Lifted = ConstValue<'tcx>;
- fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
- match *self {
- ConstValue::Param(param) => Some(ConstValue::Param(param)),
- ConstValue::Infer(infer) => {
- Some(ConstValue::Infer(match infer {
- InferConst::Var(vid) => InferConst::Var(vid.lift_to_tcx(tcx)?),
- InferConst::Fresh(i) => InferConst::Fresh(i),
- InferConst::Canonical(debrujin, var) => InferConst::Canonical(debrujin, var),
- }))
- }
- ConstValue::Scalar(x) => Some(ConstValue::Scalar(x)),
- ConstValue::Slice(x, y) => Some(ConstValue::Slice(x, y)),
- ConstValue::ByRef(ptr, alloc) => Some(ConstValue::ByRef(
- ptr, alloc.lift_to_tcx(tcx)?,
- )),
- }
- }
-}
-
impl<'a, 'tcx> Lift<'tcx> for ConstVid<'a> {
type Lifted = ConstVid<'tcx>;
fn lift_to_tcx<'b, 'gcx>(&self, _: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
@@ -1362,15 +1334,14 @@
}
}
-impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::LazyConst<'tcx> {
+impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
- let new = match self {
- ty::LazyConst::Evaluated(v) => ty::LazyConst::Evaluated(v.fold_with(folder)),
- ty::LazyConst::Unevaluated(def_id, substs) => {
- ty::LazyConst::Unevaluated(*def_id, substs.fold_with(folder))
- }
- };
- folder.tcx().mk_lazy_const(new)
+ let ty = self.ty.fold_with(folder);
+ let val = self.val.fold_with(folder);
+ folder.tcx().mk_const(ty::Const {
+ ty,
+ val
+ })
}
fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
@@ -1378,10 +1349,7 @@
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
- match *self {
- ty::LazyConst::Evaluated(c) => c.visit_with(visitor),
- ty::LazyConst::Unevaluated(_, substs) => substs.visit_with(visitor),
- }
+ self.ty.visit_with(visitor) || self.val.visit_with(visitor)
}
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
@@ -1389,27 +1357,29 @@
}
}
-impl<'tcx> TypeFoldable<'tcx> for ty::Const<'tcx> {
+impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
- let ty = self.ty.fold_with(folder);
- let val = self.val.fold_with(folder);
- ty::Const {
- ty,
- val
+ match *self {
+ ConstValue::ByRef(ptr, alloc) => ConstValue::ByRef(ptr, alloc),
+ // FIXME(const_generics): implement TypeFoldable for InferConst
+ ConstValue::Infer(ic) => ConstValue::Infer(ic),
+ ConstValue::Param(p) => ConstValue::Param(p.fold_with(folder)),
+ ConstValue::Scalar(a) => ConstValue::Scalar(a),
+ ConstValue::Slice(a, b) => ConstValue::Slice(a, b),
+ ConstValue::Unevaluated(did, substs)
+ => ConstValue::Unevaluated(did, substs.fold_with(folder)),
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
- self.ty.visit_with(visitor) || self.val.visit_with(visitor)
- }
-}
-
-impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> {
- fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
- *self
- }
-
- fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
- false
+ match *self {
+ ConstValue::ByRef(..) => false,
+ // FIXME(const_generics): implement TypeFoldable for InferConst
+ ConstValue::Infer(_ic) => false,
+ ConstValue::Param(p) => p.visit_with(visitor),
+ ConstValue::Scalar(_) => false,
+ ConstValue::Slice(..) => false,
+ ConstValue::Unevaluated(_, substs) => substs.visit_with(visitor),
+ }
}
}
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index dfe8724..df76e61 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -118,7 +118,7 @@
Str,
/// An array with the given length. Written as `[T; n]`.
- Array(Ty<'tcx>, &'tcx ty::LazyConst<'tcx>),
+ Array(Ty<'tcx>, &'tcx ty::Const<'tcx>),
/// The pointee of an array slice. Written as `[T]`.
Slice(Ty<'tcx>),
@@ -1089,7 +1089,7 @@
ParamConst::new(def.index, def.name)
}
- pub fn to_const(self, tcx: TyCtxt<'a, 'gcx, 'tcx>, ty: Ty<'tcx>) -> &'tcx LazyConst<'tcx> {
+ pub fn to_const(self, tcx: TyCtxt<'a, 'gcx, 'tcx>, ty: Ty<'tcx>) -> &'tcx Const<'tcx> {
tcx.mk_const_param(self.index, self.name, ty)
}
}
@@ -1911,7 +1911,6 @@
pub fn is_machine(&self) -> bool {
match self.sty {
- Int(ast::IntTy::Isize) | Uint(ast::UintTy::Usize) => false,
Int(..) | Uint(..) | Float(..) => true,
_ => false,
}
@@ -2097,52 +2096,6 @@
}
}
-#[derive(Copy, Clone, Debug, Hash, RustcEncodable, RustcDecodable,
- Eq, PartialEq, Ord, PartialOrd, HashStable)]
-/// Used in the HIR by using `Unevaluated` everywhere and later normalizing to `Evaluated` if the
-/// code is monomorphic enough for that.
-pub enum LazyConst<'tcx> {
- Unevaluated(DefId, SubstsRef<'tcx>),
- Evaluated(Const<'tcx>),
-}
-
-#[cfg(target_arch = "x86_64")]
-static_assert!(LAZY_CONST_SIZE: ::std::mem::size_of::<LazyConst<'static>>() == 56);
-
-impl<'tcx> LazyConst<'tcx> {
- pub fn map_evaluated<R>(self, f: impl FnOnce(Const<'tcx>) -> Option<R>) -> Option<R> {
- match self {
- LazyConst::Evaluated(c) => f(c),
- LazyConst::Unevaluated(..) => None,
- }
- }
-
- pub fn assert_usize(self, tcx: TyCtxt<'_, '_, '_>) -> Option<u64> {
- self.map_evaluated(|c| c.assert_usize(tcx))
- }
-
- #[inline]
- pub fn unwrap_usize(&self, tcx: TyCtxt<'_, '_, '_>) -> u64 {
- self.assert_usize(tcx).expect("expected `LazyConst` to contain a usize")
- }
-
- pub fn type_flags(&self) -> TypeFlags {
- // FIXME(const_generics): incorporate substs flags.
- let flags = match self {
- LazyConst::Unevaluated(..) => {
- TypeFlags::HAS_NORMALIZABLE_PROJECTION | TypeFlags::HAS_PROJECTION
- }
- LazyConst::Evaluated(c) => {
- c.type_flags()
- }
- };
-
- debug!("type_flags({:?}) = {:?}", self, flags);
-
- flags
- }
-}
-
/// Typed constant value.
#[derive(Copy, Clone, Debug, Hash, RustcEncodable, RustcDecodable,
Eq, PartialEq, Ord, PartialOrd, HashStable)]
@@ -2257,36 +2210,9 @@
self.assert_usize(tcx).unwrap_or_else(||
bug!("expected constant usize, got {:#?}", self))
}
-
- pub fn type_flags(&self) -> TypeFlags {
- let mut flags = self.ty.flags;
-
- match self.val {
- ConstValue::Param(_) => {
- flags |= TypeFlags::HAS_FREE_LOCAL_NAMES;
- flags |= TypeFlags::HAS_PARAMS;
- }
- ConstValue::Infer(infer) => {
- flags |= TypeFlags::HAS_FREE_LOCAL_NAMES;
- flags |= TypeFlags::HAS_CT_INFER;
- match infer {
- InferConst::Fresh(_) |
- InferConst::Canonical(_, _) => {}
- InferConst::Var(_) => {
- flags |= TypeFlags::KEEP_IN_LOCAL_TCX;
- }
- }
- }
- _ => {}
- }
-
- debug!("type_flags({:?}) = {:?}", self, flags);
-
- flags
- }
}
-impl<'tcx> serialize::UseSpecializedDecodable for &'tcx LazyConst<'tcx> {}
+impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Const<'tcx> {}
/// An inference variable for a const, for use in const generics.
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd,
diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs
index 8464286..3ba2c4c 100644
--- a/src/librustc/ty/subst.rs
+++ b/src/librustc/ty/subst.rs
@@ -26,7 +26,7 @@
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub struct Kind<'tcx> {
ptr: NonZeroUsize,
- marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>, &'tcx ty::LazyConst<'tcx>)>
+ marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>, &'tcx ty::Const<'tcx>)>
}
const TAG_MASK: usize = 0b11;
@@ -38,7 +38,7 @@
pub enum UnpackedKind<'tcx> {
Lifetime(ty::Region<'tcx>),
Type(Ty<'tcx>),
- Const(&'tcx ty::LazyConst<'tcx>),
+ Const(&'tcx ty::Const<'tcx>),
}
impl<'tcx> UnpackedKind<'tcx> {
@@ -104,8 +104,8 @@
}
}
-impl<'tcx> From<&'tcx ty::LazyConst<'tcx>> for Kind<'tcx> {
- fn from(c: &'tcx ty::LazyConst<'tcx>) -> Kind<'tcx> {
+impl<'tcx> From<&'tcx ty::Const<'tcx>> for Kind<'tcx> {
+ fn from(c: &'tcx ty::Const<'tcx>) -> Kind<'tcx> {
UnpackedKind::Const(c).pack()
}
}
@@ -208,12 +208,12 @@
}
ty::GenericParamDefKind::Const => {
- tcx.mk_lazy_const(ty::LazyConst::Evaluated(ty::Const {
+ tcx.mk_const(ty::Const {
val: ConstValue::Infer(
InferConst::Canonical(ty::INNERMOST, ty::BoundVar::from(param.index))
),
ty: tcx.type_of(def_id),
- })).into()
+ }).into()
}
}
})
@@ -304,7 +304,7 @@
}
#[inline]
- pub fn consts(&'a self) -> impl DoubleEndedIterator<Item = &'tcx ty::LazyConst<'tcx>> + 'a {
+ pub fn consts(&'a self) -> impl DoubleEndedIterator<Item = &'tcx ty::Const<'tcx>> + 'a {
self.iter().filter_map(|k| {
if let UnpackedKind::Const(ct) = k.unpack() {
Some(ct)
@@ -345,7 +345,7 @@
}
#[inline]
- pub fn const_at(&self, i: usize) -> &'tcx ty::LazyConst<'tcx> {
+ pub fn const_at(&self, i: usize) -> &'tcx ty::Const<'tcx> {
if let UnpackedKind::Const(ct) = self[i].unpack() {
ct
} else {
@@ -522,16 +522,13 @@
return t1;
}
- fn fold_const(&mut self, c: &'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> {
+ fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
if !c.needs_subst() {
return c;
}
- if let ty::LazyConst::Evaluated(ty::Const {
- val: ConstValue::Param(p),
- ..
- }) = c {
- self.const_for_param(*p, c)
+ if let ConstValue::Param(p) = c.val {
+ self.const_for_param(p, c)
} else {
c.super_fold_with(self)
}
@@ -564,8 +561,8 @@
fn const_for_param(
&self,
p: ParamConst,
- source_cn: &'tcx ty::LazyConst<'tcx>
- ) -> &'tcx ty::LazyConst<'tcx> {
+ source_cn: &'tcx ty::Const<'tcx>
+ ) -> &'tcx ty::Const<'tcx> {
// Look up the const in the substitutions. It really should be in there.
let opt_cn = self.substs.get(p.index as usize).map(|k| k.unpack());
let cn = match opt_cn {
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index 65918a9..4fb2bfb 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -497,10 +497,10 @@
}) => {
!impl_generics.type_param(pt, self).pure_wrt_drop
}
- UnpackedKind::Const(&ty::LazyConst::Evaluated(ty::Const {
+ UnpackedKind::Const(&ty::Const {
val: ConstValue::Param(ref pc),
..
- })) => {
+ }) => {
!impl_generics.const_param(pc, self).pure_wrt_drop
}
UnpackedKind::Lifetime(_) |
diff --git a/src/librustc/ty/walk.rs b/src/librustc/ty/walk.rs
index d9f309a..fa1eadf 100644
--- a/src/librustc/ty/walk.rs
+++ b/src/librustc/ty/walk.rs
@@ -3,6 +3,7 @@
use crate::ty::{self, Ty};
use smallvec::{self, SmallVec};
+use crate::mir::interpret::ConstValue;
// The TypeWalker's stack is hot enough that it's worth going to some effort to
// avoid heap allocations.
@@ -74,9 +75,10 @@
ty::Placeholder(..) | ty::Bound(..) | ty::Foreign(..) => {
}
ty::Array(ty, len) => {
- if let ty::LazyConst::Unevaluated(_, substs) = len {
+ if let ConstValue::Unevaluated(_, substs) = len.val {
stack.extend(substs.types().rev());
}
+ stack.push(len.ty);
stack.push(ty);
}
ty::Slice(ty) => {
diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs
index fa35416..7bfda6a 100644
--- a/src/librustc/ty/wf.rs
+++ b/src/librustc/ty/wf.rs
@@ -7,6 +7,7 @@
use std::iter::once;
use syntax_pos::Span;
use crate::middle::lang_items;
+use crate::mir::interpret::ConstValue;
/// Returns the set of obligations needed to make `ty` well-formed.
/// If `ty` contains unresolved inference variables, this may include
@@ -203,8 +204,8 @@
/// Pushes the obligations required for an array length to be WF
/// into `self.out`.
- fn compute_array_len(&mut self, constant: ty::LazyConst<'tcx>) {
- if let ty::LazyConst::Unevaluated(def_id, substs) = constant {
+ fn compute_array_len(&mut self, constant: ty::Const<'tcx>) {
+ if let ConstValue::Unevaluated(def_id, substs) = constant.val {
let obligations = self.nominal_obligations(def_id, substs);
self.out.extend(obligations);
diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs
index 0a295c2..c75788e 100644
--- a/src/librustc_codegen_llvm/lib.rs
+++ b/src/librustc_codegen_llvm/lib.rs
@@ -15,7 +15,6 @@
#![allow(unused_attributes)]
#![feature(libc)]
#![feature(nll)]
-#![feature(range_contains)]
#![feature(rustc_diagnostic_macros)]
#![feature(optin_builtin_traits)]
#![feature(concat_idents)]
diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs
index 1f4c554..e6470db 100644
--- a/src/librustc_codegen_ssa/back/linker.rs
+++ b/src/librustc_codegen_ssa/back/linker.rs
@@ -382,20 +382,19 @@
if self.sess.target.target.options.is_like_osx {
// Write a plain, newline-separated list of symbols
- let res = (|| -> io::Result<()> {
+ let res: io::Result<()> = try {
let mut f = BufWriter::new(File::create(&path)?);
for sym in self.info.exports[&crate_type].iter() {
debug!(" _{}", sym);
writeln!(f, "_{}", sym)?;
}
- Ok(())
- })();
+ };
if let Err(e) = res {
self.sess.fatal(&format!("failed to write lib.def file: {}", e));
}
} else {
// Write an LD version script
- let res = (|| -> io::Result<()> {
+ let res: io::Result<()> = try {
let mut f = BufWriter::new(File::create(&path)?);
writeln!(f, "{{\n global:")?;
for sym in self.info.exports[&crate_type].iter() {
@@ -403,8 +402,7 @@
writeln!(f, " {};", sym)?;
}
writeln!(f, "\n local:\n *;\n}};")?;
- Ok(())
- })();
+ };
if let Err(e) = res {
self.sess.fatal(&format!("failed to write version script: {}", e));
}
@@ -644,7 +642,7 @@
tmpdir: &Path,
crate_type: CrateType) {
let path = tmpdir.join("lib.def");
- let res = (|| -> io::Result<()> {
+ let res: io::Result<()> = try {
let mut f = BufWriter::new(File::create(&path)?);
// Start off with the standard module name header and then go
@@ -655,8 +653,7 @@
debug!(" _{}", symbol);
writeln!(f, " {}", symbol)?;
}
- Ok(())
- })();
+ };
if let Err(e) = res {
self.sess.fatal(&format!("failed to write lib.def file: {}", e));
}
diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs
index fec4193..fe9b88c 100644
--- a/src/librustc_codegen_ssa/lib.rs
+++ b/src/librustc_codegen_ssa/lib.rs
@@ -7,6 +7,7 @@
#![feature(libc)]
#![feature(rustc_diagnostic_macros)]
#![feature(stmt_expr_attributes)]
+#![feature(try_blocks)]
#![feature(in_band_lifetimes)]
#![feature(nll)]
#![allow(unused_attributes)]
diff --git a/src/librustc_codegen_ssa/mir/constant.rs b/src/librustc_codegen_ssa/mir/constant.rs
index 2bb68dc..a1d44b2 100644
--- a/src/librustc_codegen_ssa/mir/constant.rs
+++ b/src/librustc_codegen_ssa/mir/constant.rs
@@ -2,7 +2,6 @@
use rustc_mir::const_eval::const_field;
use rustc::mir;
use rustc_data_structures::indexed_vec::Idx;
-use rustc::mir::interpret::GlobalId;
use rustc::ty::{self, Ty};
use rustc::ty::layout;
use syntax::source_map::Span;
@@ -11,33 +10,25 @@
use super::FunctionCx;
impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
- fn fully_evaluate(
- &mut self,
- bx: &Bx,
- constant: &'tcx ty::LazyConst<'tcx>,
- ) -> Result<ty::Const<'tcx>, ErrorHandled> {
- match *constant {
- ty::LazyConst::Unevaluated(def_id, ref substs) => {
- let tcx = bx.tcx();
- let param_env = ty::ParamEnv::reveal_all();
- let instance = ty::Instance::resolve(tcx, param_env, def_id, substs).unwrap();
- let cid = GlobalId {
- instance,
- promoted: None,
- };
- tcx.const_eval(param_env.and(cid))
- },
- ty::LazyConst::Evaluated(constant) => Ok(constant),
- }
- }
-
pub fn eval_mir_constant(
&mut self,
bx: &Bx,
constant: &mir::Constant<'tcx>,
) -> Result<ty::Const<'tcx>, ErrorHandled> {
- let c = self.monomorphize(&constant.literal);
- self.fully_evaluate(bx, c)
+ match constant.literal.val {
+ mir::interpret::ConstValue::Unevaluated(def_id, ref substs) => {
+ let substs = self.monomorphize(substs);
+ let instance = ty::Instance::resolve(
+ bx.tcx(), ty::ParamEnv::reveal_all(), def_id, substs,
+ ).unwrap();
+ let cid = mir::interpret::GlobalId {
+ instance,
+ promoted: None,
+ };
+ bx.tcx().const_eval(ty::ParamEnv::reveal_all().and(cid))
+ },
+ _ => Ok(*self.monomorphize(&constant.literal)),
+ }
}
/// process constant containing SIMD shuffle indices
diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs
index 55a1eb0..e17a6e7 100644
--- a/src/librustc_codegen_ssa/mir/operand.rs
+++ b/src/librustc_codegen_ssa/mir/operand.rs
@@ -76,6 +76,7 @@
}
let val = match val.val {
+ ConstValue::Unevaluated(..) => bug!("unevaluated constant in `OperandRef::from_const`"),
ConstValue::Param(_) => bug!("encountered a ConstValue::Param in codegen"),
ConstValue::Infer(_) => bug!("encountered a ConstValue::Infer in codegen"),
ConstValue::Scalar(x) => {
diff --git a/src/librustc_codegen_utils/Cargo.toml b/src/librustc_codegen_utils/Cargo.toml
index 5f241eb..c75208b 100644
--- a/src/librustc_codegen_utils/Cargo.toml
+++ b/src/librustc_codegen_utils/Cargo.toml
@@ -21,4 +21,3 @@
rustc_data_structures = { path = "../librustc_data_structures" }
rustc_metadata = { path = "../librustc_metadata" }
rustc_mir = { path = "../librustc_mir" }
-rustc_incremental = { path = "../librustc_incremental" }
diff --git a/src/librustc_codegen_utils/codegen_backend.rs b/src/librustc_codegen_utils/codegen_backend.rs
index 29bcb4f..56eaffb 100644
--- a/src/librustc_codegen_utils/codegen_backend.rs
+++ b/src/librustc_codegen_utils/codegen_backend.rs
@@ -10,27 +10,16 @@
#![feature(box_syntax)]
use std::any::Any;
-use std::io::Write;
-use std::fs;
-use std::path::Path;
-use std::sync::{mpsc, Arc};
-
-use rustc_data_structures::owning_ref::OwningRef;
-use flate2::Compression;
-use flate2::write::DeflateEncoder;
+use std::sync::mpsc;
use syntax::symbol::Symbol;
-use rustc::hir::def_id::LOCAL_CRATE;
use rustc::session::Session;
use rustc::util::common::ErrorReported;
-use rustc::session::config::{CrateType, OutputFilenames, PrintRequest};
+use rustc::session::config::{OutputFilenames, PrintRequest};
use rustc::ty::TyCtxt;
use rustc::ty::query::Providers;
-use rustc::middle::cstore::EncodedMetadata;
use rustc::middle::cstore::MetadataLoader;
use rustc::dep_graph::DepGraph;
-use rustc_target::spec::Target;
-use crate::link::out_filename;
pub use rustc_data_structures::sync::MetadataRef;
@@ -64,134 +53,3 @@
outputs: &OutputFilenames,
) -> Result<(), ErrorReported>;
}
-
-pub struct NoLlvmMetadataLoader;
-
-impl MetadataLoader for NoLlvmMetadataLoader {
- fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result<MetadataRef, String> {
- let buf = fs::read(filename).map_err(|e| format!("metadata file open err: {:?}", e))?;
- let buf: OwningRef<Vec<u8>, [u8]> = OwningRef::new(buf);
- Ok(rustc_erase_owner!(buf.map_owner_box()))
- }
-
- fn get_dylib_metadata(&self, target: &Target, filename: &Path) -> Result<MetadataRef, String> {
- self.get_rlib_metadata(target, filename)
- }
-}
-
-pub struct MetadataOnlyCodegenBackend(());
-pub struct OngoingCodegen {
- metadata: EncodedMetadata,
- metadata_version: Vec<u8>,
- crate_name: Symbol,
-}
-
-impl MetadataOnlyCodegenBackend {
- pub fn boxed() -> Box<dyn CodegenBackend> {
- box MetadataOnlyCodegenBackend(())
- }
-}
-
-impl CodegenBackend for MetadataOnlyCodegenBackend {
- fn init(&self, sess: &Session) {
- for cty in sess.opts.crate_types.iter() {
- match *cty {
- CrateType::Rlib | CrateType::Dylib | CrateType::Executable => {},
- _ => {
- sess.diagnostic().warn(
- &format!("LLVM unsupported, so output type {} is not supported", cty)
- );
- },
- }
- }
- }
-
- fn metadata_loader(&self) -> Box<dyn MetadataLoader + Sync> {
- box NoLlvmMetadataLoader
- }
-
- fn provide(&self, providers: &mut Providers<'_>) {
- crate::symbol_names::provide(providers);
-
- providers.target_features_whitelist = |_tcx, _cnum| {
- Default::default() // Just a dummy
- };
- providers.is_reachable_non_generic = |_tcx, _defid| true;
- providers.exported_symbols = |_tcx, _crate| Arc::new(Vec::new());
- }
- fn provide_extern(&self, providers: &mut Providers<'_>) {
- providers.is_reachable_non_generic = |_tcx, _defid| true;
- }
-
- fn codegen_crate<'a, 'tcx>(
- &self,
- tcx: TyCtxt<'a, 'tcx, 'tcx>,
- _rx: mpsc::Receiver<Box<dyn Any + Send>>
- ) -> Box<dyn Any> {
- use rustc_mir::monomorphize::item::MonoItem;
-
- crate::check_for_rustc_errors_attr(tcx);
- crate::symbol_names_test::report_symbol_names(tcx);
- rustc_incremental::assert_dep_graph(tcx);
- rustc_incremental::assert_module_sources::assert_module_sources(tcx);
- // FIXME: Fix this
- // rustc::middle::dependency_format::calculate(tcx);
- let _ = tcx.link_args(LOCAL_CRATE);
- let _ = tcx.native_libraries(LOCAL_CRATE);
- let (_, cgus) = tcx.collect_and_partition_mono_items(LOCAL_CRATE);
- for (mono_item, _) in cgus.iter().flat_map(|cgu| cgu.items().iter()) {
- if let MonoItem::Fn(inst) = mono_item {
- let def_id = inst.def_id();
- if def_id.is_local() {
- let _ = tcx.codegen_fn_attrs(def_id);
- }
- }
- }
- tcx.sess.abort_if_errors();
-
- let metadata = tcx.encode_metadata();
-
- box OngoingCodegen {
- metadata,
- metadata_version: tcx.metadata_encoding_version().to_vec(),
- crate_name: tcx.crate_name(LOCAL_CRATE),
- }
- }
-
- fn join_codegen_and_link(
- &self,
- ongoing_codegen: Box<dyn Any>,
- sess: &Session,
- _dep_graph: &DepGraph,
- outputs: &OutputFilenames,
- ) -> Result<(), ErrorReported> {
- let ongoing_codegen = ongoing_codegen.downcast::<OngoingCodegen>()
- .expect("Expected MetadataOnlyCodegenBackend's OngoingCodegen, found Box<dyn Any>");
- for &crate_type in sess.opts.crate_types.iter() {
- if crate_type != CrateType::Rlib &&
- crate_type != CrateType::Dylib {
- continue;
- }
- let output_name =
- out_filename(sess, crate_type, &outputs, &ongoing_codegen.crate_name.as_str());
- let mut compressed = ongoing_codegen.metadata_version.clone();
- let metadata = if crate_type == CrateType::Dylib {
- DeflateEncoder::new(&mut compressed, Compression::fast())
- .write_all(&ongoing_codegen.metadata.raw_data)
- .unwrap();
- &compressed
- } else {
- &ongoing_codegen.metadata.raw_data
- };
- fs::write(&output_name, metadata).unwrap();
- }
-
- sess.abort_if_errors();
- if !sess.opts.crate_types.contains(&CrateType::Rlib)
- && !sess.opts.crate_types.contains(&CrateType::Dylib)
- {
- sess.fatal("Executables are not supported by the metadata-only backend.");
- }
- Ok(())
- }
-}
diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs
index 466cf40..1a3914e 100644
--- a/src/librustc_codegen_utils/lib.rs
+++ b/src/librustc_codegen_utils/lib.rs
@@ -19,7 +19,6 @@
#[macro_use]
extern crate rustc;
-#[macro_use] extern crate rustc_data_structures;
use rustc::ty::TyCtxt;
use rustc::hir::def_id::LOCAL_CRATE;
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index c7b6f37..2598461 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -91,9 +91,6 @@
use syntax::parse::{self, PResult};
use syntax_pos::{DUMMY_SP, MultiSpan, FileName};
-#[cfg(test)]
-mod test;
-
pub mod pretty;
/// Exit status code used for successful compilation and help output.
@@ -683,7 +680,7 @@
let mut cfgs = sess.parse_sess.config.iter().filter_map(|&(name, ref value)| {
let gated_cfg = GatedCfg::gate(&ast::MetaItem {
- ident: ast::Path::from_ident(ast::Ident::with_empty_ctxt(name)),
+ path: ast::Path::from_ident(ast::Ident::with_empty_ctxt(name)),
node: ast::MetaItemKind::Word,
span: DUMMY_SP,
});
diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs
deleted file mode 100644
index f98939e..0000000
--- a/src/librustc_driver/test.rs
+++ /dev/null
@@ -1,614 +0,0 @@
-//! Standalone tests for the inference module.
-
-use errors::emitter::Emitter;
-use errors::{DiagnosticBuilder, Level};
-use rustc::hir;
-use rustc::infer::outlives::env::OutlivesEnvironment;
-use rustc::infer::{self, InferOk, InferResult, SuppressRegionErrors};
-use rustc::middle::region;
-use rustc::session::{DiagnosticOutput, config};
-use rustc::traits::ObligationCause;
-use rustc::ty::subst::Subst;
-use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
-use rustc_data_structures::sync;
-use rustc_target::spec::abi::Abi;
-use rustc_interface::interface;
-use syntax::ast;
-use syntax::feature_gate::UnstableFeatures;
-use syntax::source_map::FileName;
-use syntax::symbol::Symbol;
-
-struct Env<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
- infcx: &'a infer::InferCtxt<'a, 'gcx, 'tcx>,
- region_scope_tree: &'a mut region::ScopeTree,
- param_env: ty::ParamEnv<'tcx>,
-}
-
-struct RH<'a> {
- id: hir::ItemLocalId,
- sub: &'a [RH<'a>],
-}
-
-const EMPTY_SOURCE_STR: &'static str = "#![feature(no_core)] #![no_core]";
-
-struct ExpectErrorEmitter {
- messages: Vec<String>,
-}
-
-fn remove_message(e: &mut ExpectErrorEmitter, msg: &str, lvl: Level) {
- match lvl {
- Level::Bug | Level::Fatal | Level::Error => {}
- _ => {
- return;
- }
- }
-
- debug!("Error: {}", msg);
- match e.messages.iter().position(|m| msg.contains(m)) {
- Some(i) => {
- e.messages.remove(i);
- }
- None => {
- debug!("Unexpected error: {} Expected: {:?}", msg, e.messages);
- panic!("Unexpected error: {} Expected: {:?}", msg, e.messages);
- }
- }
-}
-
-impl Emitter for ExpectErrorEmitter {
- fn emit(&mut self, db: &DiagnosticBuilder) {
- remove_message(self, &db.message(), db.level);
- for child in &db.children {
- remove_message(self, &child.message(), child.level);
- }
- }
-}
-
-fn errors(msgs: &[&str]) -> (Box<dyn Emitter + Send + sync::Send>, usize) {
- let mut v: Vec<_> = msgs.iter().map(|m| m.to_string()).collect();
- if !v.is_empty() {
- v.push("aborting due to previous error".to_owned());
- }
- (
- box ExpectErrorEmitter { messages: v } as Box<dyn Emitter + Send + sync::Send>,
- msgs.len(),
- )
-}
-
-fn test_env<F>(
- source_string: &str,
- (emitter, expected_err_count): (Box<dyn Emitter + Send + sync::Send>, usize),
- body: F,
-)
-where
- F: FnOnce(Env) + Send,
-{
- let mut opts = config::Options::default();
- opts.debugging_opts.verbose = true;
- opts.unstable_features = UnstableFeatures::Allow;
-
- // When we're compiling this library with `--test` it'll run as a binary but
- // not actually exercise much functionality.
- // As a result most of the logic loading the codegen backend is defunkt
- // (it assumes we're a dynamic library in a sysroot)
- // so let's just use the metadata only backend which doesn't need to load any libraries.
- opts.debugging_opts.codegen_backend = Some("metadata_only".to_owned());
-
- let input = config::Input::Str {
- name: FileName::anon_source_code(&source_string),
- input: source_string.to_string(),
- };
-
- let config = interface::Config {
- opts,
- crate_cfg: Default::default(),
- input,
- input_path: None,
- output_file: None,
- output_dir: None,
- file_loader: None,
- diagnostic_output: DiagnosticOutput::Emitter(emitter),
- stderr: None,
- crate_name: Some("test".to_owned()),
- lint_caps: Default::default(),
- };
-
- interface::run_compiler(config, |compiler| {
- compiler.global_ctxt().unwrap().peek_mut().enter(|tcx| {
- tcx.infer_ctxt().enter(|infcx| {
- let mut region_scope_tree = region::ScopeTree::default();
- let param_env = ty::ParamEnv::empty();
- body(Env {
- infcx: &infcx,
- region_scope_tree: &mut region_scope_tree,
- param_env: param_env,
- });
- let outlives_env = OutlivesEnvironment::new(param_env);
- let def_id = tcx.hir().local_def_id(ast::CRATE_NODE_ID);
- infcx.resolve_regions_and_report_errors(
- def_id,
- ®ion_scope_tree,
- &outlives_env,
- SuppressRegionErrors::default(),
- );
- assert_eq!(tcx.sess.err_count(), expected_err_count);
- });
- })
- });
-}
-
-fn d1() -> ty::DebruijnIndex {
- ty::INNERMOST
-}
-
-fn d2() -> ty::DebruijnIndex {
- d1().shifted_in(1)
-}
-
-impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
- pub fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> {
- self.infcx.tcx
- }
-
- pub fn create_region_hierarchy(
- &mut self,
- rh: &RH,
- parent: (region::Scope, region::ScopeDepth),
- ) {
- let me = region::Scope {
- id: rh.id,
- data: region::ScopeData::Node,
- };
- self.region_scope_tree.record_scope_parent(me, Some(parent));
- for child_rh in rh.sub {
- self.create_region_hierarchy(child_rh, (me, parent.1 + 1));
- }
- }
-
- pub fn create_simple_region_hierarchy(&mut self) {
- // Creates a region hierarchy where 1 is root, 10 and 11 are
- // children of 1, etc.
-
- let dscope = region::Scope {
- id: hir::ItemLocalId::from_u32(1),
- data: region::ScopeData::Destruction,
- };
- self.region_scope_tree.record_scope_parent(dscope, None);
- self.create_region_hierarchy(
- &RH {
- id: hir::ItemLocalId::from_u32(1),
- sub: &[
- RH {
- id: hir::ItemLocalId::from_u32(10),
- sub: &[],
- },
- RH {
- id: hir::ItemLocalId::from_u32(11),
- sub: &[],
- },
- ],
- },
- (dscope, 1),
- );
- }
-
- #[allow(dead_code)] // this seems like it could be useful, even if we don't use it now
- pub fn lookup_item(&self, names: &[String]) -> hir::HirId {
- return match search_mod(self, &self.infcx.tcx.hir().krate().module, 0, names) {
- Some(id) => id,
- None => {
- panic!("no item found: `{}`", names.join("::"));
- }
- };
-
- fn search_mod(
- this: &Env,
- m: &hir::Mod,
- idx: usize,
- names: &[String],
- ) -> Option<hir::HirId> {
- assert!(idx < names.len());
- for item in &m.item_ids {
- let item = this.infcx.tcx.hir().expect_item(item.id);
- if item.ident.to_string() == names[idx] {
- return search(this, item, idx + 1, names);
- }
- }
- return None;
- }
-
- fn search(this: &Env, it: &hir::Item, idx: usize, names: &[String]) -> Option<hir::HirId> {
- if idx == names.len() {
- return Some(it.hir_id);
- }
-
- return match it.node {
- hir::ItemKind::Use(..)
- | hir::ItemKind::ExternCrate(..)
- | hir::ItemKind::Const(..)
- | hir::ItemKind::Static(..)
- | hir::ItemKind::Fn(..)
- | hir::ItemKind::ForeignMod(..)
- | hir::ItemKind::GlobalAsm(..)
- | hir::ItemKind::Existential(..)
- | hir::ItemKind::Ty(..) => None,
-
- hir::ItemKind::Enum(..)
- | hir::ItemKind::Struct(..)
- | hir::ItemKind::Union(..)
- | hir::ItemKind::Trait(..)
- | hir::ItemKind::TraitAlias(..)
- | hir::ItemKind::Impl(..) => None,
-
- hir::ItemKind::Mod(ref m) => search_mod(this, m, idx, names),
- };
- }
- }
-
- pub fn make_subtype(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
- match self.infcx
- .at(&ObligationCause::dummy(), self.param_env)
- .sub(a, b)
- {
- Ok(_) => true,
- Err(ref e) => panic!("Encountered error: {}", e),
- }
- }
-
- pub fn is_subtype(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
- self.infcx.can_sub(self.param_env, a, b).is_ok()
- }
-
- pub fn assert_subtype(&self, a: Ty<'tcx>, b: Ty<'tcx>) {
- if !self.is_subtype(a, b) {
- panic!("{} is not a subtype of {}, but it should be", a, b);
- }
- }
-
- pub fn assert_eq(&self, a: Ty<'tcx>, b: Ty<'tcx>) {
- self.assert_subtype(a, b);
- self.assert_subtype(b, a);
- }
-
- pub fn t_fn(&self, input_tys: &[Ty<'tcx>], output_ty: Ty<'tcx>) -> Ty<'tcx> {
- self.infcx
- .tcx
- .mk_fn_ptr(ty::Binder::bind(self.infcx.tcx.mk_fn_sig(
- input_tys.iter().cloned(),
- output_ty,
- false,
- hir::Unsafety::Normal,
- Abi::Rust,
- )))
- }
-
- pub fn t_nil(&self) -> Ty<'tcx> {
- self.infcx.tcx.mk_unit()
- }
-
- pub fn t_pair(&self, ty1: Ty<'tcx>, ty2: Ty<'tcx>) -> Ty<'tcx> {
- self.infcx.tcx.intern_tup(&[ty1, ty2])
- }
-
- pub fn t_param(&self, index: u32) -> Ty<'tcx> {
- let name = format!("T{}", index);
- self.infcx
- .tcx
- .mk_ty_param(index, Symbol::intern(&name).as_interned_str())
- }
-
- pub fn re_early_bound(&self, index: u32, name: &'static str) -> ty::Region<'tcx> {
- let name = Symbol::intern(name).as_interned_str();
- self.infcx
- .tcx
- .mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
- def_id: self.infcx.tcx.hir().local_def_id(ast::CRATE_NODE_ID),
- index,
- name,
- }))
- }
-
- pub fn re_late_bound_with_debruijn(
- &self,
- id: u32,
- debruijn: ty::DebruijnIndex,
- ) -> ty::Region<'tcx> {
- self.infcx
- .tcx
- .mk_region(ty::ReLateBound(debruijn, ty::BrAnon(id)))
- }
-
- pub fn t_rptr(&self, r: ty::Region<'tcx>) -> Ty<'tcx> {
- self.infcx.tcx.mk_imm_ref(r, self.tcx().types.isize)
- }
-
- pub fn t_rptr_late_bound(&self, id: u32) -> Ty<'tcx> {
- let r = self.re_late_bound_with_debruijn(id, d1());
- self.infcx.tcx.mk_imm_ref(r, self.tcx().types.isize)
- }
-
- pub fn t_rptr_late_bound_with_debruijn(
- &self,
- id: u32,
- debruijn: ty::DebruijnIndex,
- ) -> Ty<'tcx> {
- let r = self.re_late_bound_with_debruijn(id, debruijn);
- self.infcx.tcx.mk_imm_ref(r, self.tcx().types.isize)
- }
-
- pub fn t_rptr_scope(&self, id: u32) -> Ty<'tcx> {
- let r = ty::ReScope(region::Scope {
- id: hir::ItemLocalId::from_u32(id),
- data: region::ScopeData::Node,
- });
- self.infcx
- .tcx
- .mk_imm_ref(self.infcx.tcx.mk_region(r), self.tcx().types.isize)
- }
-
- pub fn re_free(&self, id: u32) -> ty::Region<'tcx> {
- self.infcx.tcx.mk_region(ty::ReFree(ty::FreeRegion {
- scope: self.infcx.tcx.hir().local_def_id(ast::CRATE_NODE_ID),
- bound_region: ty::BrAnon(id),
- }))
- }
-
- pub fn t_rptr_free(&self, id: u32) -> Ty<'tcx> {
- let r = self.re_free(id);
- self.infcx.tcx.mk_imm_ref(r, self.tcx().types.isize)
- }
-
- pub fn sub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) -> InferResult<'tcx, ()> {
- self.infcx
- .at(&ObligationCause::dummy(), self.param_env)
- .sub(t1, t2)
- }
-
- /// Checks that `t1 <: t2` is true (this may register additional
- /// region checks).
- pub fn check_sub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) {
- match self.sub(t1, t2) {
- Ok(InferOk {
- obligations,
- value: (),
- }) => {
- // None of these tests should require nested obligations.
- assert!(obligations.is_empty());
- }
- Err(ref e) => {
- panic!("unexpected error computing sub({:?},{:?}): {}", t1, t2, e);
- }
- }
- }
-}
-
-#[test]
-fn contravariant_region_ptr_ok() {
- test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| {
- env.create_simple_region_hierarchy();
- let t_rptr1 = env.t_rptr_scope(1);
- let t_rptr10 = env.t_rptr_scope(10);
- env.assert_eq(t_rptr1, t_rptr1);
- env.assert_eq(t_rptr10, t_rptr10);
- env.make_subtype(t_rptr1, t_rptr10);
- })
-}
-
-#[test]
-fn contravariant_region_ptr_err() {
- test_env(EMPTY_SOURCE_STR, errors(&["mismatched types"]), |mut env| {
- env.create_simple_region_hierarchy();
- let t_rptr1 = env.t_rptr_scope(1);
- let t_rptr10 = env.t_rptr_scope(10);
- env.assert_eq(t_rptr1, t_rptr1);
- env.assert_eq(t_rptr10, t_rptr10);
-
- // This will cause an error when regions are resolved.
- env.make_subtype(t_rptr10, t_rptr1);
- })
-}
-
-#[test]
-fn sub_bound_free_true() {
- //! Test that:
- //!
- //! for<'a> fn(&'a isize) <: fn(&'b isize)
- //!
- //! *does* hold.
-
- test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| {
- env.create_simple_region_hierarchy();
- let t_rptr_bound1 = env.t_rptr_late_bound(1);
- let t_rptr_free1 = env.t_rptr_free(1);
- env.check_sub(
- env.t_fn(&[t_rptr_bound1], env.tcx().types.isize),
- env.t_fn(&[t_rptr_free1], env.tcx().types.isize),
- );
- })
-}
-
-/// Test substituting a bound region into a function, which introduces another level of binding.
-/// This requires adjusting the Debruijn index.
-#[test]
-fn subst_ty_renumber_bound() {
- test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
- // Situation:
- // Theta = [A -> &'a foo]
-
- let t_rptr_bound1 = env.t_rptr_late_bound(1);
-
- // t_source = fn(A)
- let t_source = {
- let t_param = env.t_param(0);
- env.t_fn(&[t_param], env.t_nil())
- };
-
- let substs = env.infcx.tcx.intern_substs(&[t_rptr_bound1.into()]);
- let t_substituted = t_source.subst(env.infcx.tcx, substs);
-
- // t_expected = fn(&'a isize)
- let t_expected = {
- let t_ptr_bound2 = env.t_rptr_late_bound_with_debruijn(1, d2());
- env.t_fn(&[t_ptr_bound2], env.t_nil())
- };
-
- debug!(
- "subst_bound: t_source={:?} substs={:?} t_substituted={:?} t_expected={:?}",
- t_source, substs, t_substituted, t_expected
- );
-
- assert_eq!(t_substituted, t_expected);
- })
-}
-
-/// Tests substituting a bound region into a function, which introduces another level of binding.
-/// This requires adjusting the De Bruijn index.
-#[test]
-fn subst_ty_renumber_some_bounds() {
- test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
- // Situation:
- // `Theta = [A -> &'a foo]`
-
- let t_rptr_bound1 = env.t_rptr_late_bound(1);
-
- // `t_source = (A, fn(A))`
- let t_source = {
- let t_param = env.t_param(0);
- env.t_pair(t_param, env.t_fn(&[t_param], env.t_nil()))
- };
-
- let substs = env.infcx.tcx.intern_substs(&[t_rptr_bound1.into()]);
- let t_substituted = t_source.subst(env.infcx.tcx, substs);
-
- // `t_expected = (&'a isize, fn(&'a isize))`
- //
- // However, note that the Debruijn index is different in the different cases.
- let t_expected = {
- let t_rptr_bound2 = env.t_rptr_late_bound_with_debruijn(1, d2());
- env.t_pair(t_rptr_bound1, env.t_fn(&[t_rptr_bound2], env.t_nil()))
- };
-
- debug!(
- "subst_bound: t_source={:?} substs={:?} t_substituted={:?} t_expected={:?}",
- t_source, substs, t_substituted, t_expected
- );
-
- assert_eq!(t_substituted, t_expected);
- })
-}
-
-/// Tests that we correctly compute whether a type has escaping regions or not.
-#[test]
-fn escaping() {
- test_env(EMPTY_SOURCE_STR, errors(&[]), |mut env| {
- // Situation:
- // `Theta = [A -> &'a foo]`
- env.create_simple_region_hierarchy();
-
- assert!(!env.t_nil().has_escaping_bound_vars());
-
- let t_rptr_free1 = env.t_rptr_free(1);
- assert!(!t_rptr_free1.has_escaping_bound_vars());
-
- let t_rptr_bound1 = env.t_rptr_late_bound_with_debruijn(1, d1());
- assert!(t_rptr_bound1.has_escaping_bound_vars());
-
- let t_rptr_bound2 = env.t_rptr_late_bound_with_debruijn(1, d2());
- assert!(t_rptr_bound2.has_escaping_bound_vars());
-
- // `t_fn = fn(A)`
- let t_param = env.t_param(0);
- assert!(!t_param.has_escaping_bound_vars());
- let t_fn = env.t_fn(&[t_param], env.t_nil());
- assert!(!t_fn.has_escaping_bound_vars());
- })
-}
-
-/// Tests applying a substitution where the value being substituted for an early-bound region is a
-/// late-bound region.
-#[test]
-fn subst_region_renumber_region() {
- test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
- let re_bound1 = env.re_late_bound_with_debruijn(1, d1());
-
- // `type t_source<'a> = fn(&'a isize)`
- let t_source = {
- let re_early = env.re_early_bound(0, "'a");
- env.t_fn(&[env.t_rptr(re_early)], env.t_nil())
- };
-
- let substs = env.infcx.tcx.intern_substs(&[re_bound1.into()]);
- let t_substituted = t_source.subst(env.infcx.tcx, substs);
-
- // `t_expected = fn(&'a isize)`
- //
- // but not that the Debruijn index is different in the different cases.
- let t_expected = {
- let t_rptr_bound2 = env.t_rptr_late_bound_with_debruijn(1, d2());
- env.t_fn(&[t_rptr_bound2], env.t_nil())
- };
-
- debug!(
- "subst_bound: t_source={:?} substs={:?} t_substituted={:?} t_expected={:?}",
- t_source, substs, t_substituted, t_expected
- );
-
- assert_eq!(t_substituted, t_expected);
- })
-}
-
-#[test]
-fn walk_ty() {
- test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
- let tcx = env.infcx.tcx;
- let int_ty = tcx.types.isize;
- let usize_ty = tcx.types.usize;
- let tup1_ty = tcx.intern_tup(&[int_ty, usize_ty, int_ty, usize_ty]);
- let tup2_ty = tcx.intern_tup(&[tup1_ty, tup1_ty, usize_ty]);
- let walked: Vec<_> = tup2_ty.walk().collect();
- assert_eq!(
- walked,
- [
- tup2_ty, tup1_ty, int_ty, usize_ty, int_ty, usize_ty, tup1_ty, int_ty, usize_ty,
- int_ty, usize_ty, usize_ty
- ]
- );
- })
-}
-
-#[test]
-fn walk_ty_skip_subtree() {
- test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
- let tcx = env.infcx.tcx;
- let int_ty = tcx.types.isize;
- let usize_ty = tcx.types.usize;
- let tup1_ty = tcx.intern_tup(&[int_ty, usize_ty, int_ty, usize_ty]);
- let tup2_ty = tcx.intern_tup(&[tup1_ty, tup1_ty, usize_ty]);
-
- // types we expect to see (in order), plus a boolean saying
- // whether to skip the subtree.
- let mut expected = vec![
- (tup2_ty, false),
- (tup1_ty, false),
- (int_ty, false),
- (usize_ty, false),
- (int_ty, false),
- (usize_ty, false),
- (tup1_ty, true), // skip the isize/usize/isize/usize
- (usize_ty, false),
- ];
- expected.reverse();
-
- let mut walker = tup2_ty.walk();
- while let Some(t) = walker.next() {
- debug!("walked to {:?}", t);
- let (expected_ty, skip) = expected.pop().unwrap();
- assert_eq!(t, expected_ty);
- if skip {
- walker.skip_current_subtree();
- }
- }
-
- assert!(expected.is_empty());
- })
-}
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index 7c7698d..6b4b437 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -2,7 +2,6 @@
#![feature(custom_attribute)]
#![allow(unused_attributes)]
-#![feature(range_contains)]
#![cfg_attr(unix, feature(libc))]
#![feature(nll)]
#![feature(optin_builtin_traits)]
diff --git a/src/librustc_incremental/assert_dep_graph.rs b/src/librustc_incremental/assert_dep_graph.rs
index 9fe9a60..c964f4c 100644
--- a/src/librustc_incremental/assert_dep_graph.rs
+++ b/src/librustc_incremental/assert_dep_graph.rs
@@ -99,12 +99,12 @@
fn argument(&self, attr: &ast::Attribute) -> Option<ast::Name> {
let mut value = None;
for list_item in attr.meta_item_list().unwrap_or_default() {
- match list_item.word() {
- Some(word) if value.is_none() =>
- value = Some(word.name()),
+ match list_item.ident() {
+ Some(ident) if list_item.is_word() && value.is_none() =>
+ value = Some(ident.name),
_ =>
// FIXME better-encapsulate meta_item (don't directly access `node`)
- span_bug!(list_item.span(), "unexpected meta-item {:?}", list_item.node),
+ span_bug!(list_item.span(), "unexpected meta-item {:?}", list_item),
}
}
value
diff --git a/src/librustc_incremental/assert_module_sources.rs b/src/librustc_incremental/assert_module_sources.rs
index 5cbb412..2c83501 100644
--- a/src/librustc_incremental/assert_module_sources.rs
+++ b/src/librustc_incremental/assert_module_sources.rs
@@ -153,7 +153,7 @@
return value;
} else {
self.tcx.sess.span_fatal(
- item.span,
+ item.span(),
&format!("associated value expected for `{}`", name));
}
}
diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs
index 633e61a..6b5e19c 100644
--- a/src/librustc_incremental/persist/dirty_clean.rs
+++ b/src/librustc_incremental/persist/dirty_clean.rs
@@ -36,16 +36,16 @@
/// For typedef, constants, and statics
const BASE_CONST: &[&str] = &[
- label_strs::TypeOfItem,
+ label_strs::type_of,
];
/// DepNodes for functions + methods
const BASE_FN: &[&str] = &[
// Callers will depend on the signature of these items, so we better test
label_strs::FnSignature,
- label_strs::GenericsOfItem,
- label_strs::PredicatesOfItem,
- label_strs::TypeOfItem,
+ label_strs::generics_of,
+ label_strs::predicates_of,
+ label_strs::type_of,
// And a big part of compilation (that we eventually want to cache) is type inference
// information:
@@ -62,7 +62,7 @@
/// `impl` implementation of struct/trait
const BASE_IMPL: &[&str] = &[
label_strs::AssociatedItemDefIds,
- label_strs::GenericsOfItem,
+ label_strs::generics_of,
label_strs::ImplTraitRef,
];
@@ -78,17 +78,17 @@
/// Note that changing the type of a field does not change the type of the struct or enum, but
/// adding/removing fields or changing a fields name or visibility does.
const BASE_STRUCT: &[&str] = &[
- label_strs::GenericsOfItem,
- label_strs::PredicatesOfItem,
- label_strs::TypeOfItem,
+ label_strs::generics_of,
+ label_strs::predicates_of,
+ label_strs::type_of,
];
/// Trait definition `DepNode`s.
const BASE_TRAIT_DEF: &[&str] = &[
label_strs::AssociatedItemDefIds,
- label_strs::GenericsOfItem,
+ label_strs::generics_of,
label_strs::ObjectSafety,
- label_strs::PredicatesOfItem,
+ label_strs::predicates_of,
label_strs::SpecializationGraph,
label_strs::TraitDefOfItem,
label_strs::TraitImpls,
@@ -179,7 +179,7 @@
// Fields are kind of separate from their containers, as they can change independently from
// them. We should at least check
//
-// TypeOfItem for these.
+// type_of for these.
type Labels = FxHashSet<String>;
@@ -430,13 +430,13 @@
if DepNode::has_label_string(label) {
if out.contains(label) {
self.tcx.sess.span_fatal(
- item.span,
+ item.span(),
&format!("dep-node label `{}` is repeated", label));
}
out.insert(label.to_string());
} else {
self.tcx.sess.span_fatal(
- item.span,
+ item.span(),
&format!("dep-node label `{}` not recognized", label));
}
}
@@ -576,13 +576,13 @@
if let Some(value) = item.value_str() {
value
} else {
- let msg = if let Some(name) = item.name() {
+ let msg = if let Some(name) = item.ident_str() {
format!("associated value expected for `{}`", name)
} else {
"expected an associated value".to_string()
};
- tcx.sess.span_fatal(item.span, &msg);
+ tcx.sess.span_fatal(item.span(), &msg);
}
}
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index 5bb47bd..0c710fd 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -243,6 +243,7 @@
krate,
&sess.parse_sess,
sess.edition(),
+ &sess.opts.debugging_opts.allow_features,
);
// these need to be set "early" so that expansion sees `quote` if enabled.
sess.init_features(features);
diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs
index 0f858d6..b1ef4e3 100644
--- a/src/librustc_interface/util.rs
+++ b/src/librustc_interface/util.rs
@@ -266,9 +266,6 @@
let codegen_name = sess.opts.debugging_opts.codegen_backend.as_ref()
.unwrap_or(&sess.target.target.options.codegen_backend);
let backend = match &codegen_name[..] {
- "metadata_only" => {
- rustc_codegen_utils::codegen_backend::MetadataOnlyCodegenBackend::boxed
- }
filename if filename.contains(".") => {
load_backend_from_dylib(filename.as_ref())
}
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 7a7c49e..80c5eee 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -760,7 +760,7 @@
impl EarlyLintPass for DeprecatedAttr {
fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &ast::Attribute) {
for &&(n, _, _, ref g) in &self.depr_attrs {
- if attr.name() == n {
+ if attr.ident_str() == Some(n) {
if let &AttributeGate::Gated(Stability::Deprecated(link, suggestion),
ref name,
ref reason,
@@ -831,7 +831,7 @@
let span = sugared_span.take().unwrap_or_else(|| attr.span);
- if attr.name() == "doc" {
+ if attr.check_name("doc") {
let mut err = cx.struct_span_lint(UNUSED_DOC_COMMENTS, span, "unused doc comment");
err.span_label(
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index 7d61547..648cae3 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -267,19 +267,21 @@
}
}
- let name = attr.name();
+ let name = attr.ident_str();
if !attr::is_used(attr) {
debug!("Emitting warning for: {:?}", attr);
cx.span_lint(UNUSED_ATTRIBUTES, attr.span, "unused attribute");
// Is it a builtin attribute that must be used at the crate level?
let known_crate = BUILTIN_ATTRIBUTES.iter()
- .find(|&&(builtin, ty, ..)| name == builtin && ty == AttributeType::CrateLevel)
+ .find(|&&(builtin, ty, ..)| {
+ name == Some(builtin) && ty == AttributeType::CrateLevel
+ })
.is_some();
// Has a plugin registered this attribute as one that must be used at
// the crate level?
let plugin_crate = plugin_attributes.iter()
- .find(|&&(ref x, t)| name == &**x && AttributeType::CrateLevel == t)
+ .find(|&&(ref x, t)| name == Some(x) && AttributeType::CrateLevel == t)
.is_some();
if known_crate || plugin_crate {
let msg = match attr.style {
diff --git a/src/librustc_macros/src/lib.rs b/src/librustc_macros/src/lib.rs
index cad3126..e99ceb1 100644
--- a/src/librustc_macros/src/lib.rs
+++ b/src/librustc_macros/src/lib.rs
@@ -1,8 +1,18 @@
#![feature(proc_macro_hygiene)]
#![deny(rust_2018_idioms)]
+extern crate proc_macro;
+
use synstructure::decl_derive;
+use proc_macro::TokenStream;
+
mod hash_stable;
+mod query;
+
+#[proc_macro]
+pub fn rustc_queries(input: TokenStream) -> TokenStream {
+ query::rustc_queries(input)
+}
decl_derive!([HashStable, attributes(stable_hasher)] => hash_stable::hash_stable_derive);
diff --git a/src/librustc_macros/src/query.rs b/src/librustc_macros/src/query.rs
new file mode 100644
index 0000000..3849e47
--- /dev/null
+++ b/src/librustc_macros/src/query.rs
@@ -0,0 +1,394 @@
+use proc_macro::TokenStream;
+use syn::{
+ Token, Ident, Type, Attribute, ReturnType, Expr, Block, Error,
+ braced, parenthesized, parse_macro_input,
+};
+use syn::spanned::Spanned;
+use syn::parse::{Result, Parse, ParseStream};
+use syn::punctuated::Punctuated;
+use syn;
+use quote::quote;
+
+#[allow(non_camel_case_types)]
+mod kw {
+ syn::custom_keyword!(query);
+}
+
+/// Ident or a wildcard `_`.
+struct IdentOrWild(Ident);
+
+impl Parse for IdentOrWild {
+ fn parse(input: ParseStream<'_>) -> Result<Self> {
+ Ok(if input.peek(Token![_]) {
+ let underscore = input.parse::<Token![_]>()?;
+ IdentOrWild(Ident::new("_", underscore.span()))
+ } else {
+ IdentOrWild(input.parse()?)
+ })
+ }
+}
+
+/// A modifier for a query
+enum QueryModifier {
+ /// The description of the query.
+ Desc(Option<Ident>, Punctuated<Expr, Token![,]>),
+
+ /// Cache the query to disk if the `Expr` returns true.
+ Cache(Option<Ident>, Expr),
+
+ /// Custom code to load the query from disk.
+ LoadCached(Ident, Ident, Block),
+
+ /// A cycle error for this query aborting the compilation with a fatal error.
+ FatalCycle,
+}
+
+impl Parse for QueryModifier {
+ fn parse(input: ParseStream<'_>) -> Result<Self> {
+ let modifier: Ident = input.parse()?;
+ if modifier == "desc" {
+ // Parse a description modifier like:
+ // `desc { |tcx| "foo {}", tcx.item_path(key) }`
+ let attr_content;
+ braced!(attr_content in input);
+ let tcx = if attr_content.peek(Token![|]) {
+ attr_content.parse::<Token![|]>()?;
+ let tcx = attr_content.parse()?;
+ attr_content.parse::<Token![|]>()?;
+ Some(tcx)
+ } else {
+ None
+ };
+ let desc = attr_content.parse_terminated(Expr::parse)?;
+ Ok(QueryModifier::Desc(tcx, desc))
+ } else if modifier == "cache" {
+ // Parse a cache modifier like:
+ // `cache { |tcx| key.is_local() }`
+ let attr_content;
+ braced!(attr_content in input);
+ let tcx = if attr_content.peek(Token![|]) {
+ attr_content.parse::<Token![|]>()?;
+ let tcx = attr_content.parse()?;
+ attr_content.parse::<Token![|]>()?;
+ Some(tcx)
+ } else {
+ None
+ };
+ let expr = attr_content.parse()?;
+ Ok(QueryModifier::Cache(tcx, expr))
+ } else if modifier == "load_cached" {
+ // Parse a load_cached modifier like:
+ // `load_cached(tcx, id) { tcx.queries.on_disk_cache.try_load_query_result(tcx, id) }`
+ let args;
+ parenthesized!(args in input);
+ let tcx = args.parse()?;
+ args.parse::<Token![,]>()?;
+ let id = args.parse()?;
+ let block = input.parse()?;
+ Ok(QueryModifier::LoadCached(tcx, id, block))
+ } else if modifier == "fatal_cycle" {
+ Ok(QueryModifier::FatalCycle)
+ } else {
+ Err(Error::new(modifier.span(), "unknown query modifier"))
+ }
+ }
+}
+
+/// Ensures only doc comment attributes are used
+fn check_attributes(attrs: Vec<Attribute>) -> Result<()> {
+ for attr in attrs {
+ if !attr.path.is_ident("doc") {
+ return Err(Error::new(attr.span(), "attributes not supported on queries"));
+ }
+ }
+ Ok(())
+}
+
+/// A compiler query. `query ... { ... }`
+struct Query {
+ modifiers: List<QueryModifier>,
+ name: Ident,
+ key: IdentOrWild,
+ arg: Type,
+ result: ReturnType,
+}
+
+impl Parse for Query {
+ fn parse(input: ParseStream<'_>) -> Result<Self> {
+ check_attributes(input.call(Attribute::parse_outer)?)?;
+
+ // Parse the query declaration. Like `query type_of(key: DefId) -> Ty<'tcx>`
+ input.parse::<kw::query>()?;
+ let name: Ident = input.parse()?;
+ let arg_content;
+ parenthesized!(arg_content in input);
+ let key = arg_content.parse()?;
+ arg_content.parse::<Token![:]>()?;
+ let arg = arg_content.parse()?;
+ let result = input.parse()?;
+
+ // Parse the query modifiers
+ let content;
+ braced!(content in input);
+ let modifiers = content.parse()?;
+
+ Ok(Query {
+ modifiers,
+ name,
+ key,
+ arg,
+ result,
+ })
+ }
+}
+
+/// A type used to greedily parse another type until the input is empty.
+struct List<T>(Vec<T>);
+
+impl<T: Parse> Parse for List<T> {
+ fn parse(input: ParseStream<'_>) -> Result<Self> {
+ let mut list = Vec::new();
+ while !input.is_empty() {
+ list.push(input.parse()?);
+ }
+ Ok(List(list))
+ }
+}
+
+/// A named group containing queries.
+struct Group {
+ name: Ident,
+ queries: List<Query>,
+}
+
+impl Parse for Group {
+ fn parse(input: ParseStream<'_>) -> Result<Self> {
+ let name: Ident = input.parse()?;
+ let content;
+ braced!(content in input);
+ Ok(Group {
+ name,
+ queries: content.parse()?,
+ })
+ }
+}
+
+struct QueryModifiers {
+ /// The description of the query.
+ desc: Option<(Option<Ident>, Punctuated<Expr, Token![,]>)>,
+
+ /// Cache the query to disk if the `Expr` returns true.
+ cache: Option<(Option<Ident>, Expr)>,
+
+ /// Custom code to load the query from disk.
+ load_cached: Option<(Ident, Ident, Block)>,
+
+ /// A cycle error for this query aborting the compilation with a fatal error.
+ fatal_cycle: bool,
+}
+
+/// Process query modifiers into a struct, erroring on duplicates
+fn process_modifiers(query: &mut Query) -> QueryModifiers {
+ let mut load_cached = None;
+ let mut cache = None;
+ let mut desc = None;
+ let mut fatal_cycle = false;
+ for modifier in query.modifiers.0.drain(..) {
+ match modifier {
+ QueryModifier::LoadCached(tcx, id, block) => {
+ if load_cached.is_some() {
+ panic!("duplicate modifier `load_cached` for query `{}`", query.name);
+ }
+ load_cached = Some((tcx, id, block));
+ }
+ QueryModifier::Cache(tcx, expr) => {
+ if cache.is_some() {
+ panic!("duplicate modifier `cache` for query `{}`", query.name);
+ }
+ cache = Some((tcx, expr));
+ }
+ QueryModifier::Desc(tcx, list) => {
+ if desc.is_some() {
+ panic!("duplicate modifier `desc` for query `{}`", query.name);
+ }
+ desc = Some((tcx, list));
+ }
+ QueryModifier::FatalCycle => {
+ if fatal_cycle {
+ panic!("duplicate modifier `fatal_cycle` for query `{}`", query.name);
+ }
+ fatal_cycle = true;
+ }
+ }
+ }
+ QueryModifiers {
+ load_cached,
+ cache,
+ desc,
+ fatal_cycle,
+ }
+}
+
+/// Add the impl of QueryDescription for the query to `impls` if one is requested
+fn add_query_description_impl(
+ query: &Query,
+ modifiers: QueryModifiers,
+ impls: &mut proc_macro2::TokenStream
+) {
+ let name = &query.name;
+ let arg = &query.arg;
+ let key = &query.key.0;
+
+ // Find out if we should cache the query on disk
+ let cache = modifiers.cache.as_ref().map(|(tcx, expr)| {
+ let try_load_from_disk = if let Some((tcx, id, block)) = modifiers.load_cached.as_ref() {
+ // Use custom code to load the query from disk
+ quote! {
+ #[inline]
+ fn try_load_from_disk(
+ #tcx: TyCtxt<'_, 'tcx, 'tcx>,
+ #id: SerializedDepNodeIndex
+ ) -> Option<Self::Value> {
+ #block
+ }
+ }
+ } else {
+ // Use the default code to load the query from disk
+ quote! {
+ #[inline]
+ fn try_load_from_disk(
+ tcx: TyCtxt<'_, 'tcx, 'tcx>,
+ id: SerializedDepNodeIndex
+ ) -> Option<Self::Value> {
+ tcx.queries.on_disk_cache.try_load_query_result(tcx, id)
+ }
+ }
+ };
+
+ let tcx = tcx.as_ref().map(|t| quote! { #t }).unwrap_or(quote! { _ });
+ quote! {
+ #[inline]
+ fn cache_on_disk(#tcx: TyCtxt<'_, 'tcx, 'tcx>, #key: Self::Key) -> bool {
+ #expr
+ }
+
+ #try_load_from_disk
+ }
+ });
+
+ if cache.is_none() && modifiers.load_cached.is_some() {
+ panic!("load_cached modifier on query `{}` without a cache modifier", name);
+ }
+
+ let desc = modifiers.desc.as_ref().map(|(tcx, desc)| {
+ let tcx = tcx.as_ref().map(|t| quote! { #t }).unwrap_or(quote! { _ });
+ quote! {
+ fn describe(
+ #tcx: TyCtxt<'_, '_, '_>,
+ #key: #arg,
+ ) -> Cow<'static, str> {
+ format!(#desc).into()
+ }
+ }
+ });
+
+ if desc.is_some() || cache.is_some() {
+ let cache = cache.unwrap_or(quote! {});
+ let desc = desc.unwrap_or(quote! {});
+
+ impls.extend(quote! {
+ impl<'tcx> QueryDescription<'tcx> for queries::#name<'tcx> {
+ #desc
+ #cache
+ }
+ });
+ }
+}
+
+pub fn rustc_queries(input: TokenStream) -> TokenStream {
+ let groups = parse_macro_input!(input as List<Group>);
+
+ let mut query_stream = quote! {};
+ let mut query_description_stream = quote! {};
+ let mut dep_node_def_stream = quote! {};
+ let mut dep_node_force_stream = quote! {};
+
+ for group in groups.0 {
+ let mut group_stream = quote! {};
+ for mut query in group.queries.0 {
+ let modifiers = process_modifiers(&mut query);
+ let name = &query.name;
+ let arg = &query.arg;
+ let result_full = &query.result;
+ let result = match query.result {
+ ReturnType::Default => quote! { -> () },
+ _ => quote! { #result_full },
+ };
+
+ // Pass on the fatal_cycle modifier
+ let fatal_cycle = if modifiers.fatal_cycle {
+ quote! { fatal_cycle }
+ } else {
+ quote! {}
+ };
+
+ // Add the query to the group
+ group_stream.extend(quote! {
+ [#fatal_cycle] fn #name: #name(#arg) #result,
+ });
+
+ add_query_description_impl(&query, modifiers, &mut query_description_stream);
+
+ // Create a dep node for the query
+ dep_node_def_stream.extend(quote! {
+ [] #name(#arg),
+ });
+
+ // Add a match arm to force the query given the dep node
+ dep_node_force_stream.extend(quote! {
+ DepKind::#name => {
+ if let Some(key) = RecoverKey::recover($tcx, $dep_node) {
+ force_ex!($tcx, #name, key);
+ } else {
+ return false;
+ }
+ }
+ });
+ }
+ let name = &group.name;
+ query_stream.extend(quote! {
+ #name { #group_stream },
+ });
+ }
+ TokenStream::from(quote! {
+ macro_rules! rustc_query_append {
+ ([$($macro:tt)*][$($other:tt)*]) => {
+ $($macro)* {
+ $($other)*
+
+ #query_stream
+
+ }
+ }
+ }
+ macro_rules! rustc_dep_node_append {
+ ([$($macro:tt)*][$($other:tt)*]) => {
+ $($macro)*(
+ $($other)*
+
+ #dep_node_def_stream
+ );
+ }
+ }
+ macro_rules! rustc_dep_node_force {
+ ([$dep_node:expr, $tcx:expr] $($other:tt)*) => {
+ match $dep_node.kind {
+ $($other)*
+
+ #dep_node_force_stream
+ }
+ }
+ }
+ #query_description_stream
+ })
+}
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 6fe00a4..c608c03 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -576,7 +576,8 @@
}).collect(),
adt_kind,
data.ctor_kind,
- attribute_def_id
+ attribute_def_id,
+ false,
)
}
diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs
index b4f6839..14416b5 100644
--- a/src/librustc_metadata/lib.rs
+++ b/src/librustc_metadata/lib.rs
@@ -1,6 +1,7 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
#![feature(box_patterns)]
+#![feature(drain_filter)]
#![feature(libc)]
#![feature(nll)]
#![feature(proc_macro_internals)]
diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs
index 2389838..314c95a 100644
--- a/src/librustc_metadata/native_libs.rs
+++ b/src/librustc_metadata/native_libs.rs
@@ -76,7 +76,7 @@
k => {
struct_span_err!(self.tcx.sess, m.span, E0458,
"unknown kind: `{}`", k)
- .span_label(item.span, "unknown kind").emit();
+ .span_label(item.span(), "unknown kind").emit();
cstore::NativeUnknown
}
};
@@ -199,34 +199,31 @@
}
// Update kind and, optionally, the name of all native libraries
- // (there may be more than one) with the specified name.
+ // (there may be more than one) with the specified name. If any
+ // library is mentioned more than once, keep the latest mention
+ // of it, so that any possible dependent libraries appear before
+ // it. (This ensures that the linker is able to see symbols from
+ // all possible dependent libraries before linking in the library
+ // in question.)
for &(ref name, ref new_name, kind) in &self.tcx.sess.opts.libs {
- let mut found = false;
- for lib in self.libs.iter_mut() {
- let lib_name = match lib.name {
- Some(n) => n,
- None => continue,
- };
- if lib_name == name as &str {
- let mut changed = false;
- if let Some(k) = kind {
- lib.kind = k;
- changed = true;
+ // If we've already added any native libraries with the same
+ // name, they will be pulled out into `existing`, so that we
+ // can move them to the end of the list below.
+ let mut existing = self.libs.drain_filter(|lib| {
+ if let Some(lib_name) = lib.name {
+ if lib_name == name as &str {
+ if let Some(k) = kind {
+ lib.kind = k;
+ }
+ if let &Some(ref new_name) = new_name {
+ lib.name = Some(Symbol::intern(new_name));
+ }
+ return true;
}
- if let &Some(ref new_name) = new_name {
- lib.name = Some(Symbol::intern(new_name));
- changed = true;
- }
- if !changed {
- let msg = format!("redundant linker flag specified for \
- library `{}`", name);
- self.tcx.sess.warn(&msg);
- }
-
- found = true;
}
- }
- if !found {
+ false
+ }).collect::<Vec<_>>();
+ if existing.is_empty() {
// Add if not found
let new_name = new_name.as_ref().map(|s| &**s); // &Option<String> -> Option<&str>
let lib = NativeLibrary {
@@ -237,6 +234,10 @@
wasm_import_module: None,
};
self.register_native_lib(None, lib);
+ } else {
+ // Move all existing libraries with the same name to the
+ // end of the command line.
+ self.libs.append(&mut existing);
}
}
}
diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs
index 8613464..1428938 100644
--- a/src/librustc_mir/borrow_check/error_reporting.rs
+++ b/src/librustc_mir/borrow_check/error_reporting.rs
@@ -1505,10 +1505,10 @@
debug!("add_moved_or_invoked_closure_note: terminator={:?}", terminator);
if let TerminatorKind::Call {
func: Operand::Constant(box Constant {
- literal: ty::LazyConst::Evaluated(ty::Const {
+ literal: ty::Const {
ty: &ty::TyS { sty: ty::TyKind::FnDef(id, _), .. },
..
- }),
+ },
..
}),
args,
diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs
index 65703ad..b8dae98 100644
--- a/src/librustc_mir/borrow_check/mutability_errors.rs
+++ b/src/librustc_mir/borrow_check/mutability_errors.rs
@@ -471,13 +471,13 @@
Terminator {
kind: TerminatorKind::Call {
func: Operand::Constant(box Constant {
- literal: ty::LazyConst::Evaluated(Const {
+ literal: Const {
ty: &TyS {
sty: TyKind::FnDef(id, substs),
..
},
..
- }),
+ },
..
}),
..
diff --git a/src/librustc_mir/borrow_check/nll/renumber.rs b/src/librustc_mir/borrow_check/nll/renumber.rs
index 0a0a88e..58e567c 100644
--- a/src/librustc_mir/borrow_check/nll/renumber.rs
+++ b/src/librustc_mir/borrow_check/nll/renumber.rs
@@ -80,7 +80,7 @@
debug!("visit_region: region={:?}", region);
}
- fn visit_const(&mut self, constant: &mut &'tcx ty::LazyConst<'tcx>, _location: Location) {
+ fn visit_const(&mut self, constant: &mut &'tcx ty::Const<'tcx>, _location: Location) {
*constant = self.renumber_regions(&*constant);
}
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index 5b444ab..25a3160 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -28,7 +28,7 @@
use rustc::infer::outlives::env::RegionBoundPairs;
use rustc::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime, NLLRegionVariableOrigin};
use rustc::infer::type_variable::TypeVariableOrigin;
-use rustc::mir::interpret::EvalErrorKind::BoundsCheck;
+use rustc::mir::interpret::{EvalErrorKind::BoundsCheck, ConstValue};
use rustc::mir::tcx::PlaceTy;
use rustc::mir::visit::{PlaceContext, Visitor, MutatingUseContext, NonMutatingUseContext};
use rustc::mir::*;
@@ -296,37 +296,33 @@
);
}
} else {
- match *constant.literal {
- ty::LazyConst::Unevaluated(def_id, substs) => {
- if let Err(terr) = self.cx.fully_perform_op(
- location.to_locations(),
- ConstraintCategory::Boring,
- self.cx.param_env.and(type_op::ascribe_user_type::AscribeUserType::new(
- constant.ty, def_id, UserSubsts { substs, user_self_ty: None },
- )),
- ) {
- span_mirbug!(
- self,
- constant,
- "bad constant type {:?} ({:?})",
- constant,
- terr
- );
- }
+ if let ConstValue::Unevaluated(def_id, substs) = constant.literal.val {
+ if let Err(terr) = self.cx.fully_perform_op(
+ location.to_locations(),
+ ConstraintCategory::Boring,
+ self.cx.param_env.and(type_op::ascribe_user_type::AscribeUserType::new(
+ constant.ty, def_id, UserSubsts { substs, user_self_ty: None },
+ )),
+ ) {
+ span_mirbug!(
+ self,
+ constant,
+ "bad constant type {:?} ({:?})",
+ constant,
+ terr
+ );
}
- ty::LazyConst::Evaluated(lit) => {
- if let ty::FnDef(def_id, substs) = lit.ty.sty {
- let tcx = self.tcx();
+ }
+ if let ty::FnDef(def_id, substs) = constant.literal.ty.sty {
+ let tcx = self.tcx();
- let instantiated_predicates = tcx
- .predicates_of(def_id)
- .instantiate(tcx, substs);
- self.cx.normalize_and_prove_instantiated_predicates(
- instantiated_predicates,
- location.to_locations(),
- );
- }
- }
+ let instantiated_predicates = tcx
+ .predicates_of(def_id)
+ .instantiate(tcx, substs);
+ self.cx.normalize_and_prove_instantiated_predicates(
+ instantiated_predicates,
+ location.to_locations(),
+ );
}
}
}
@@ -418,10 +414,11 @@
constant, location
);
- let literal = match constant.literal {
- ty::LazyConst::Evaluated(lit) => lit,
- ty::LazyConst::Unevaluated(..) => return,
- };
+ let literal = constant.literal;
+
+ if let ConstValue::Unevaluated(..) = literal.val {
+ return;
+ }
debug!("sanitize_constant: expected_ty={:?}", literal.ty);
diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs
index f1a82ec..9e12a7e 100644
--- a/src/librustc_mir/build/expr/as_rvalue.rs
+++ b/src/librustc_mir/build/expr/as_rvalue.rs
@@ -275,13 +275,13 @@
span: expr_span,
ty: this.hir.tcx().types.u32,
user_ty: None,
- literal: this.hir.tcx().mk_lazy_const(ty::LazyConst::Evaluated(
+ literal: this.hir.tcx().mk_const(
ty::Const::from_bits(
this.hir.tcx(),
0,
ty::ParamEnv::empty().and(this.hir.tcx().types.u32),
),
- )),
+ ),
}));
box AggregateKind::Generator(closure_id, substs, movability)
}
diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs
index d60a094..77978d7 100644
--- a/src/librustc_mir/build/matches/simplify.rs
+++ b/src/librustc_mir/build/matches/simplify.rs
@@ -114,14 +114,12 @@
(Some(('\u{0000}' as u128, '\u{10FFFF}' as u128, Size::from_bits(32))), 0)
}
ty::Int(ity) => {
- // FIXME(49937): refactor these bit manipulations into interpret.
let size = Integer::from_attr(&tcx, SignedInt(ity)).size();
let max = truncate(u128::max_value(), size);
let bias = 1u128 << (size.bits() - 1);
(Some((0, max, size)), bias)
}
ty::Uint(uty) => {
- // FIXME(49937): refactor these bit manipulations into interpret.
let size = Integer::from_attr(&tcx, UnsignedInt(uty)).size();
let max = truncate(u128::max_value(), size);
(Some((0, max, size)), 0)
diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs
index 72b9244..0c93984 100644
--- a/src/librustc_mir/build/matches/test.rs
+++ b/src/librustc_mir/build/matches/test.rs
@@ -299,7 +299,7 @@
}
let eq_def_id = self.hir.tcx().lang_items().eq_trait().unwrap();
let (mty, method) = self.hir.trait_method(eq_def_id, "eq", ty, &[ty.into()]);
- let method = self.hir.tcx().mk_lazy_const(ty::LazyConst::Evaluated(method));
+ let method = self.hir.tcx().mk_const(method);
let re_erased = self.hir.tcx().types.re_erased;
// take the argument by reference
diff --git a/src/librustc_mir/build/misc.rs b/src/librustc_mir/build/misc.rs
index 2692c24..d76d376 100644
--- a/src/librustc_mir/build/misc.rs
+++ b/src/librustc_mir/build/misc.rs
@@ -33,7 +33,7 @@
span,
ty,
user_ty: None,
- literal: self.hir.tcx().mk_lazy_const(ty::LazyConst::Evaluated(literal)),
+ literal: self.hir.tcx().mk_const(literal),
};
Operand::Constant(constant)
}
diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs
index c8e48de..ec8c62b 100644
--- a/src/librustc_mir/build/mod.rs
+++ b/src/librustc_mir/build/mod.rs
@@ -201,7 +201,7 @@
}
}
- fn visit_const(&mut self, constant: &mut &'tcx ty::LazyConst<'tcx>, _: Location) {
+ fn visit_const(&mut self, constant: &mut &'tcx ty::Const<'tcx>, _: Location) {
if let Some(lifted) = self.tcx.lift(constant) {
*constant = lifted;
} else {
diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs
index 43f0190..79a3e0c 100644
--- a/src/librustc_mir/const_eval.rs
+++ b/src/librustc_mir/const_eval.rs
@@ -65,12 +65,12 @@
fn mplace_to_const<'tcx>(
ecx: &CompileTimeEvalContext<'_, '_, 'tcx>,
mplace: MPlaceTy<'tcx>,
-) -> EvalResult<'tcx, ty::Const<'tcx>> {
+) -> ty::Const<'tcx> {
let MemPlace { ptr, align, meta } = *mplace;
// extract alloc-offset pair
assert!(meta.is_none());
- let ptr = ptr.to_ptr()?;
- let alloc = ecx.memory.get(ptr.alloc_id)?;
+ let ptr = ptr.to_ptr().unwrap();
+ let alloc = ecx.memory.get(ptr.alloc_id).unwrap();
assert!(alloc.align >= align);
assert!(alloc.bytes.len() as u64 - ptr.offset.bytes() >= mplace.layout.size.bytes());
let mut alloc = alloc.clone();
@@ -79,16 +79,16 @@
// interned this? I thought that is the entire point of that `FinishStatic` stuff?
let alloc = ecx.tcx.intern_const_alloc(alloc);
let val = ConstValue::ByRef(ptr, alloc);
- Ok(ty::Const { val, ty: mplace.layout.ty })
+ ty::Const { val, ty: mplace.layout.ty }
}
fn op_to_const<'tcx>(
ecx: &CompileTimeEvalContext<'_, '_, 'tcx>,
op: OpTy<'tcx>,
-) -> EvalResult<'tcx, ty::Const<'tcx>> {
- // We do not normalize just any data. Only scalar layout and slices.
+) -> ty::Const<'tcx> {
+ // We do not normalize just any data. Only non-union scalars and slices.
let normalize = match op.layout.abi {
- layout::Abi::Scalar(..) => true,
+ layout::Abi::Scalar(..) => op.layout.ty.ty_adt_def().map_or(true, |adt| !adt.is_union()),
layout::Abi::ScalarPair(..) => op.layout.ty.is_slice(),
_ => false,
};
@@ -100,11 +100,11 @@
let val = match normalized_op {
Ok(mplace) => return mplace_to_const(ecx, mplace),
Err(Immediate::Scalar(x)) =>
- ConstValue::Scalar(x.not_undef()?),
+ ConstValue::Scalar(x.not_undef().unwrap()),
Err(Immediate::ScalarPair(a, b)) =>
- ConstValue::Slice(a.not_undef()?, b.to_usize(ecx)?),
+ ConstValue::Slice(a.not_undef().unwrap(), b.to_usize(ecx).unwrap()),
};
- Ok(ty::Const { val, ty: op.layout.ty })
+ ty::Const { val, ty: op.layout.ty }
}
fn eval_body_and_ecx<'a, 'mir, 'tcx>(
@@ -478,7 +478,7 @@
trace!("const_field: {:?}, {:?}", field, value);
let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env);
// get the operand again
- let op = ecx.const_to_op(value, None).unwrap();
+ let op = ecx.eval_const_to_op(value, None).unwrap();
// downcast
let down = match variant {
None => op,
@@ -488,7 +488,7 @@
let field = ecx.operand_field(down, field.index() as u64).unwrap();
// and finally move back to the const world, always normalizing because
// this is not called for statics.
- op_to_const(&ecx, field).unwrap()
+ op_to_const(&ecx, field)
}
// this function uses `unwrap` copiously, because an already validated constant must have valid
@@ -500,7 +500,7 @@
) -> VariantIdx {
trace!("const_variant_index: {:?}", val);
let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env);
- let op = ecx.const_to_op(val, None).unwrap();
+ let op = ecx.eval_const_to_op(val, None).unwrap();
ecx.read_discriminant(op).unwrap().1
}
@@ -534,9 +534,9 @@
// Now that we validated, turn this into a proper constant.
let def_id = cid.instance.def.def_id();
if tcx.is_static(def_id).is_some() || cid.promoted.is_some() {
- mplace_to_const(&ecx, mplace)
+ Ok(mplace_to_const(&ecx, mplace))
} else {
- op_to_const(&ecx, mplace.into())
+ Ok(op_to_const(&ecx, mplace.into()))
}
})();
diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs
index 03f8ac6..af2cd8f 100644
--- a/src/librustc_mir/dataflow/mod.rs
+++ b/src/librustc_mir/dataflow/mod.rs
@@ -146,7 +146,7 @@
} else {
sess.span_err(
item.span,
- &format!("{} attribute requires a path", item.ident));
+ &format!("{} attribute requires a path", item.path));
return None;
}
}
diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs
index c8c6d73..b83f048 100644
--- a/src/librustc_mir/hair/cx/expr.rs
+++ b/src/librustc_mir/hair/cx/expr.rs
@@ -342,9 +342,9 @@
}
hir::ExprKind::Lit(ref lit) => ExprKind::Literal {
- literal: cx.tcx.mk_lazy_const(ty::LazyConst::Evaluated(
+ literal: cx.tcx.mk_const(
cx.const_eval_literal(&lit.node, expr_ty, lit.span, false)
- )),
+ ),
user_ty: None,
},
@@ -442,9 +442,9 @@
} else {
if let hir::ExprKind::Lit(ref lit) = arg.node {
ExprKind::Literal {
- literal: cx.tcx.mk_lazy_const(ty::LazyConst::Evaluated(
+ literal: cx.tcx.mk_const(
cx.const_eval_literal(&lit.node, expr_ty, lit.span, true)
- )),
+ ),
user_ty: None,
}
} else {
@@ -693,26 +693,29 @@
};
let source = if let Some((did, offset, var_ty)) = var {
- let mk_lazy_const = |literal| Expr {
+ let mk_const = |literal| Expr {
temp_lifetime,
ty: var_ty,
span: expr.span,
kind: ExprKind::Literal {
- literal: cx.tcx.mk_lazy_const(literal),
+ literal: cx.tcx.mk_const(literal),
user_ty: None
},
}.to_ref();
- let offset = mk_lazy_const(ty::LazyConst::Evaluated(ty::Const::from_bits(
+ let offset = mk_const(ty::Const::from_bits(
cx.tcx,
offset as u128,
cx.param_env.and(var_ty),
- )));
+ ));
match did {
Some(did) => {
// in case we are offsetting from a computed discriminant
// and not the beginning of discriminants (which is always `0`)
let substs = InternalSubsts::identity_for_item(cx.tcx(), did);
- let lhs = mk_lazy_const(ty::LazyConst::Unevaluated(did, substs));
+ let lhs = mk_const(ty::Const {
+ val: ConstValue::Unevaluated(did, substs),
+ ty: var_ty,
+ });
let bin = ExprKind::Binary {
op: BinOp::Add,
lhs,
@@ -852,9 +855,9 @@
ty,
span,
kind: ExprKind::Literal {
- literal: cx.tcx().mk_lazy_const(ty::LazyConst::Evaluated(
+ literal: cx.tcx().mk_const(
ty::Const::zero_sized(ty)
- )),
+ ),
user_ty,
},
}
@@ -914,9 +917,9 @@
let user_ty = user_substs_applied_to_def(cx, expr.hir_id, &def);
debug!("convert_path_expr: user_ty={:?}", user_ty);
ExprKind::Literal {
- literal: cx.tcx.mk_lazy_const(ty::LazyConst::Evaluated(ty::Const::zero_sized(
+ literal: cx.tcx.mk_const(ty::Const::zero_sized(
cx.tables().node_type(expr.hir_id),
- ))),
+ )),
user_ty,
}
}
@@ -930,11 +933,11 @@
let name = cx.tcx.hir().name(node_id).as_interned_str();
let val = ConstValue::Param(ty::ParamConst::new(index, name));
ExprKind::Literal {
- literal: cx.tcx.mk_lazy_const(
- ty::LazyConst::Evaluated(ty::Const {
+ literal: cx.tcx.mk_const(
+ ty::Const {
val,
ty: cx.tables().node_type(expr.hir_id),
- })
+ }
),
user_ty: None,
}
@@ -945,7 +948,10 @@
let user_ty = user_substs_applied_to_def(cx, expr.hir_id, &def);
debug!("convert_path_expr: (const) user_ty={:?}", user_ty);
ExprKind::Literal {
- literal: cx.tcx.mk_lazy_const(ty::LazyConst::Unevaluated(def_id, substs)),
+ literal: cx.tcx.mk_const(ty::Const {
+ val: ConstValue::Unevaluated(def_id, substs),
+ ty: cx.tcx.type_of(def_id),
+ }),
user_ty,
}
},
diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs
index c0f3989..71c6489 100644
--- a/src/librustc_mir/hair/cx/mod.rs
+++ b/src/librustc_mir/hair/cx/mod.rs
@@ -106,8 +106,8 @@
self.tcx.types.usize
}
- pub fn usize_literal(&mut self, value: u64) -> &'tcx ty::LazyConst<'tcx> {
- self.tcx.mk_lazy_const(ty::LazyConst::Evaluated(ty::Const::from_usize(self.tcx, value)))
+ pub fn usize_literal(&mut self, value: u64) -> &'tcx ty::Const<'tcx> {
+ self.tcx.mk_const(ty::Const::from_usize(self.tcx, value))
}
pub fn bool_ty(&mut self) -> Ty<'tcx> {
@@ -118,12 +118,12 @@
self.tcx.mk_unit()
}
- pub fn true_literal(&mut self) -> &'tcx ty::LazyConst<'tcx> {
- self.tcx.mk_lazy_const(ty::LazyConst::Evaluated(ty::Const::from_bool(self.tcx, true)))
+ pub fn true_literal(&mut self) -> &'tcx ty::Const<'tcx> {
+ self.tcx.mk_const(ty::Const::from_bool(self.tcx, true))
}
- pub fn false_literal(&mut self) -> &'tcx ty::LazyConst<'tcx> {
- self.tcx.mk_lazy_const(ty::LazyConst::Evaluated(ty::Const::from_bool(self.tcx, false)))
+ pub fn false_literal(&mut self) -> &'tcx ty::Const<'tcx> {
+ self.tcx.mk_const(ty::Const::from_bool(self.tcx, false))
}
pub fn const_eval_literal(
diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs
index 385249e..3a38876 100644
--- a/src/librustc_mir/hair/mod.rs
+++ b/src/librustc_mir/hair/mod.rs
@@ -9,7 +9,7 @@
use rustc::infer::canonical::Canonical;
use rustc::middle::region;
use rustc::ty::subst::SubstsRef;
-use rustc::ty::{AdtDef, UpvarSubsts, Ty, Const, LazyConst, UserType};
+use rustc::ty::{AdtDef, UpvarSubsts, Ty, Const, UserType};
use rustc::ty::layout::VariantIdx;
use rustc::hir;
use syntax_pos::Span;
@@ -289,7 +289,7 @@
movability: Option<hir::GeneratorMovability>,
},
Literal {
- literal: &'tcx LazyConst<'tcx>,
+ literal: &'tcx Const<'tcx>,
user_ty: Option<Canonical<'tcx, UserType<'tcx>>>,
},
InlineAsm {
diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs
index 586a3fd..88d1eb2 100644
--- a/src/librustc_mir/hair/pattern/_match.rs
+++ b/src/librustc_mir/hair/pattern/_match.rs
@@ -172,7 +172,7 @@
use rustc::ty::layout::{Integer, IntegerExt, VariantIdx, Size};
use rustc::mir::Field;
-use rustc::mir::interpret::{ConstValue, Scalar};
+use rustc::mir::interpret::{ConstValue, Scalar, truncate};
use rustc::util::common::ErrorReported;
use syntax::attr::{SignedInt, UnsignedInt};
@@ -222,7 +222,7 @@
assert_eq!(t, u);
ConstValue::Slice(
Scalar::Ptr(p),
- n.map_evaluated(|val| val.val.try_to_scalar())
+ n.val.try_to_scalar()
.unwrap()
.to_usize(&self.tcx)
.unwrap(),
@@ -678,16 +678,14 @@
]
}
ty::Int(ity) => {
- // FIXME(49937): refactor these bit manipulations into interpret.
let bits = Integer::from_attr(&cx.tcx, SignedInt(ity)).size().bits() as u128;
let min = 1u128 << (bits - 1);
- let max = (1u128 << (bits - 1)) - 1;
+ let max = min - 1;
vec![ConstantRange(min, max, pcx.ty, RangeEnd::Included)]
}
ty::Uint(uty) => {
- // FIXME(49937): refactor these bit manipulations into interpret.
- let bits = Integer::from_attr(&cx.tcx, UnsignedInt(uty)).size().bits() as u128;
- let max = !0u128 >> (128 - bits);
+ let size = Integer::from_attr(&cx.tcx, UnsignedInt(uty)).size();
+ let max = truncate(u128::max_value(), size);
vec![ConstantRange(0, max, pcx.ty, RangeEnd::Included)]
}
_ => {
diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs
index ad7b45d..8614be8 100644
--- a/src/librustc_mir/hair/pattern/mod.rs
+++ b/src/librustc_mir/hair/pattern/mod.rs
@@ -13,7 +13,7 @@
use rustc::mir::{fmt_const_val, Field, BorrowKind, Mutability};
use rustc::mir::{UserTypeProjection};
use rustc::mir::interpret::{Scalar, GlobalId, ConstValue, sign_extend};
-use rustc::ty::{self, DefIdTree, Region, TyCtxt, AdtDef, Ty, Lift, UserType};
+use rustc::ty::{self, Region, TyCtxt, AdtDef, Ty, UserType, DefIdTree};
use rustc::ty::{CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations};
use rustc::ty::subst::{SubstsRef, Kind};
use rustc::ty::layout::VariantIdx;
@@ -1233,9 +1233,6 @@
return fallback();
}
- let tcx = tcx.global_tcx();
- let (a, b, ty) = (a, b, ty).lift_to_tcx(tcx).unwrap();
-
// FIXME: This should use assert_bits(ty) instead of use_bits
// but triggers possibly bugs due to mismatching of arrays and slices
if let (Some(a), Some(b)) = (a.to_bits(tcx, ty), b.to_bits(tcx, ty)) {
@@ -1251,11 +1248,12 @@
let r = ::rustc_apfloat::ieee::Double::from_bits(b);
l.partial_cmp(&r)
}
- ty::Int(_) => {
- let layout = tcx.layout_of(ty).ok()?;
- assert!(layout.abi.is_signed());
- let a = sign_extend(a, layout.size);
- let b = sign_extend(b, layout.size);
+ ty::Int(ity) => {
+ use rustc::ty::layout::{Integer, IntegerExt};
+ use syntax::attr::SignedInt;
+ let size = Integer::from_attr(&tcx, SignedInt(ity)).size();
+ let a = sign_extend(a, size);
+ let b = sign_extend(b, size);
Some((a as i128).cmp(&(b as i128)))
}
_ => Some(a.cmp(&b)),
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index 88b936a..6ea200d 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -700,24 +700,29 @@
// relocations overlapping the edges; those would not be handled correctly).
let relocations = {
let relocations = self.get(src.alloc_id)?.relocations(self, src, size);
- let mut new_relocations = Vec::with_capacity(relocations.len() * (length as usize));
- for i in 0..length {
- new_relocations.extend(
- relocations
- .iter()
- .map(|&(offset, reloc)| {
- // compute offset for current repetition
- let dest_offset = dest.offset + (i * size);
- (
- // shift offsets from source allocation to destination allocation
- offset + dest_offset - src.offset,
- reloc,
- )
- })
- );
- }
+ if relocations.is_empty() {
+ // nothing to copy, ignore even the `length` loop
+ Vec::new()
+ } else {
+ let mut new_relocations = Vec::with_capacity(relocations.len() * (length as usize));
+ for i in 0..length {
+ new_relocations.extend(
+ relocations
+ .iter()
+ .map(|&(offset, reloc)| {
+ // compute offset for current repetition
+ let dest_offset = dest.offset + (i * size);
+ (
+ // shift offsets from source allocation to destination allocation
+ offset + dest_offset - src.offset,
+ reloc,
+ )
+ })
+ );
+ }
- new_relocations
+ new_relocations
+ }
};
let tcx = self.tcx.tcx;
@@ -784,20 +789,65 @@
// The bits have to be saved locally before writing to dest in case src and dest overlap.
assert_eq!(size.bytes() as usize as u64, size.bytes());
- let undef_mask = self.get(src.alloc_id)?.undef_mask.clone();
- let dest_allocation = self.get_mut(dest.alloc_id)?;
+ let undef_mask = &self.get(src.alloc_id)?.undef_mask;
- for i in 0..size.bytes() {
- let defined = undef_mask.get(src.offset + Size::from_bytes(i));
+ // Since we are copying `size` bytes from `src` to `dest + i * size` (`for i in 0..repeat`),
+ // a naive undef mask copying algorithm would repeatedly have to read the undef mask from
+ // the source and write it to the destination. Even if we optimized the memory accesses,
+ // we'd be doing all of this `repeat` times.
+ // Therefor we precompute a compressed version of the undef mask of the source value and
+ // then write it back `repeat` times without computing any more information from the source.
- for j in 0..repeat {
- dest_allocation.undef_mask.set(
- dest.offset + Size::from_bytes(i + (size.bytes() * j)),
- defined
- );
+ // a precomputed cache for ranges of defined/undefined bits
+ // 0000010010001110 will become
+ // [5, 1, 2, 1, 3, 3, 1]
+ // where each element toggles the state
+ let mut ranges = smallvec::SmallVec::<[u64; 1]>::new();
+ let first = undef_mask.get(src.offset);
+ let mut cur_len = 1;
+ let mut cur = first;
+ for i in 1..size.bytes() {
+ // FIXME: optimize to bitshift the current undef block's bits and read the top bit
+ if undef_mask.get(src.offset + Size::from_bytes(i)) == cur {
+ cur_len += 1;
+ } else {
+ ranges.push(cur_len);
+ cur_len = 1;
+ cur = !cur;
}
}
+ // now fill in all the data
+ let dest_allocation = self.get_mut(dest.alloc_id)?;
+ // an optimization where we can just overwrite an entire range of definedness bits if
+ // they are going to be uniformly `1` or `0`.
+ if ranges.is_empty() {
+ dest_allocation.undef_mask.set_range_inbounds(
+ dest.offset,
+ dest.offset + size * repeat,
+ first,
+ );
+ return Ok(())
+ }
+
+ // remember to fill in the trailing bits
+ ranges.push(cur_len);
+
+ for mut j in 0..repeat {
+ j *= size.bytes();
+ j += dest.offset.bytes();
+ let mut cur = first;
+ for range in &ranges {
+ let old_j = j;
+ j += range;
+ dest_allocation.undef_mask.set_range_inbounds(
+ Size::from_bytes(old_j),
+ Size::from_bytes(j),
+ cur,
+ );
+ cur = !cur;
+ }
+ }
Ok(())
}
}
diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index 206eaaf..7051107 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/src/librustc_mir/interpret/operand.rs
@@ -547,7 +547,7 @@
Move(ref place) =>
self.eval_place_to_op(place, layout)?,
- Constant(ref constant) => self.eval_lazy_const_to_op(*constant.literal, layout)?,
+ Constant(ref constant) => self.eval_const_to_op(*constant.literal, layout)?,
};
trace!("{:?}: {:?}", mir_op, *op);
Ok(op)
@@ -563,36 +563,13 @@
.collect()
}
- // Used when Miri runs into a constant, and by const propagation.
- crate fn eval_lazy_const_to_op(
- &self,
- val: ty::LazyConst<'tcx>,
- layout: Option<TyLayout<'tcx>>,
- ) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> {
- trace!("const_to_op: {:?}", val);
- match val {
- ty::LazyConst::Unevaluated(def_id, substs) => {
- let instance = self.resolve(def_id, substs)?;
- return Ok(OpTy::from(self.const_eval_raw(GlobalId {
- instance,
- promoted: None,
- })?));
- },
- ty::LazyConst::Evaluated(c) => self.const_to_op(c, layout),
- }
- }
-
// Used when the miri-engine runs into a constant and for extracting information from constants
// in patterns via the `const_eval` module
- crate fn const_to_op(
+ crate fn eval_const_to_op(
&self,
val: ty::Const<'tcx>,
layout: Option<TyLayout<'tcx>>,
) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> {
- let val = self.monomorphize(val)?;
- let layout = from_known_layout(layout, || {
- self.layout_of(val.ty)
- })?;
let op = match val.val {
ConstValue::Param(_) | ConstValue::Infer(_) => bug!(),
ConstValue::ByRef(ptr, alloc) => {
@@ -609,7 +586,17 @@
)).with_default_tag(),
ConstValue::Scalar(x) =>
Operand::Immediate(Immediate::Scalar(x.into())).with_default_tag(),
+ ConstValue::Unevaluated(def_id, substs) => {
+ let instance = self.resolve(def_id, substs)?;
+ return Ok(OpTy::from(self.const_eval_raw(GlobalId {
+ instance,
+ promoted: None,
+ })?));
+ },
};
+ let layout = from_known_layout(layout, || {
+ self.layout_of(self.monomorphize(val.ty)?)
+ })?;
Ok(OpTy {
op,
layout,
diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs
index 0b735b4..c45e694 100644
--- a/src/librustc_mir/lib.rs
+++ b/src/librustc_mir/lib.rs
@@ -14,7 +14,6 @@
#![feature(const_fn)]
#![feature(decl_macro)]
#![feature(exhaustive_patterns)]
-#![feature(range_contains)]
#![feature(rustc_diagnostic_macros)]
#![feature(rustc_attrs)]
#![feature(never_type)]
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index 307cee5..4fe47a9 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -381,7 +381,7 @@
let param_env = ty::ParamEnv::reveal_all();
if let Ok(val) = tcx.const_eval(param_env.and(cid)) {
- collect_const(tcx, val, &mut neighbors);
+ collect_const(tcx, val, InternalSubsts::empty(), &mut neighbors);
}
}
MonoItem::Fn(instance) => {
@@ -468,15 +468,7 @@
instance: Instance<'tcx>)
{
let type_length = instance.substs.types().flat_map(|ty| ty.walk()).count();
- let const_length = instance.substs.consts()
- .flat_map(|ct| {
- let ty = match ct {
- ty::LazyConst::Evaluated(ct) => ct.ty,
- ty::LazyConst::Unevaluated(def_id, _) => tcx.type_of(*def_id),
- };
- ty.walk()
- })
- .count();
+ let const_length = instance.substs.consts().flat_map(|ct| ct.ty.walk()).count();
debug!(" => type length={}, const length={}", type_length, const_length);
// Rust code can easily create exponentially-long types using only a
@@ -606,10 +598,10 @@
self.super_rvalue(rvalue, location);
}
- fn visit_const(&mut self, constant: &&'tcx ty::LazyConst<'tcx>, location: Location) {
+ fn visit_const(&mut self, constant: &&'tcx ty::Const<'tcx>, location: Location) {
debug!("visiting const {:?} @ {:?}", *constant, location);
- collect_lazy_const(self.tcx, constant, self.param_substs, self.output);
+ collect_const(self.tcx, **constant, self.param_substs, self.output);
self.super_const(constant);
}
@@ -1013,7 +1005,7 @@
let param_env = ty::ParamEnv::reveal_all();
if let Ok(val) = self.tcx.const_eval(param_env.and(cid)) {
- collect_const(self.tcx, val, &mut self.output);
+ collect_const(self.tcx, val, InternalSubsts::empty(), &mut self.output);
}
}
hir::ItemKind::Fn(..) => {
@@ -1224,7 +1216,7 @@
promoted: Some(i),
};
match tcx.const_eval(param_env.and(cid)) {
- Ok(val) => collect_const(tcx, val, output),
+ Ok(val) => collect_const(tcx, val, instance.substs, output),
Err(ErrorHandled::Reported) => {},
Err(ErrorHandled::TooGeneric) => span_bug!(
mir.promoted[i].span, "collection encountered polymorphic constant",
@@ -1242,43 +1234,10 @@
output
}
-fn collect_lazy_const<'a, 'tcx>(
- tcx: TyCtxt<'a, 'tcx, 'tcx>,
- constant: &ty::LazyConst<'tcx>,
- param_substs: SubstsRef<'tcx>,
- output: &mut Vec<MonoItem<'tcx>>,
-) {
- let (def_id, substs) = match *constant {
- ty::LazyConst::Evaluated(c) => return collect_const(tcx, c, output),
- ty::LazyConst::Unevaluated(did, substs) => (did, substs),
- };
- let param_env = ty::ParamEnv::reveal_all();
- let substs = tcx.subst_and_normalize_erasing_regions(
- param_substs,
- param_env,
- &substs,
- );
- let instance = ty::Instance::resolve(tcx,
- param_env,
- def_id,
- substs).unwrap();
-
- let cid = GlobalId {
- instance,
- promoted: None,
- };
- match tcx.const_eval(param_env.and(cid)) {
- Ok(val) => collect_const(tcx, val, output),
- Err(ErrorHandled::Reported) => {},
- Err(ErrorHandled::TooGeneric) => span_bug!(
- tcx.def_span(def_id), "collection encountered polymorphic constant",
- ),
- }
-}
-
fn collect_const<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
constant: ty::Const<'tcx>,
+ param_substs: SubstsRef<'tcx>,
output: &mut Vec<MonoItem<'tcx>>,
) {
debug!("visiting const {:?}", constant);
@@ -1292,6 +1251,30 @@
collect_miri(tcx, id, output);
}
}
+ ConstValue::Unevaluated(did, substs) => {
+ let param_env = ty::ParamEnv::reveal_all();
+ let substs = tcx.subst_and_normalize_erasing_regions(
+ param_substs,
+ param_env,
+ &substs,
+ );
+ let instance = ty::Instance::resolve(tcx,
+ param_env,
+ did,
+ substs).unwrap();
+
+ let cid = GlobalId {
+ instance,
+ promoted: None,
+ };
+ match tcx.const_eval(param_env.and(cid)) {
+ Ok(val) => collect_const(tcx, val, param_substs, output),
+ Err(ErrorHandled::Reported) => {},
+ Err(ErrorHandled::TooGeneric) => span_bug!(
+ tcx.def_span(did), "collection encountered polymorphic constant",
+ ),
+ }
+ }
_ => {},
}
}
diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs
index 68d13bf..51ba690 100644
--- a/src/librustc_mir/monomorphize/item.rs
+++ b/src/librustc_mir/monomorphize/item.rs
@@ -3,7 +3,7 @@
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
use rustc::mir::interpret::ConstValue;
use rustc::session::config::OptLevel;
-use rustc::ty::{self, Ty, TyCtxt, Const, ClosureSubsts, GeneratorSubsts, LazyConst, ParamConst};
+use rustc::ty::{self, Ty, TyCtxt, Const, ClosureSubsts, GeneratorSubsts, ParamConst};
use rustc::ty::subst::{SubstsRef, InternalSubsts};
use syntax::ast;
use syntax::attr::InlineAttr;
@@ -395,21 +395,17 @@
}
// FIXME(const_generics): handle debug printing.
- pub fn push_const_name(&self, c: &LazyConst<'tcx>, output: &mut String, debug: bool) {
- match c {
- LazyConst::Unevaluated(..) => output.push_str("_: _"),
- LazyConst::Evaluated(Const { ty, val }) => {
- match val {
- ConstValue::Infer(..) => output.push_str("_"),
- ConstValue::Param(ParamConst { name, .. }) => {
- write!(output, "{}", name).unwrap();
- }
- _ => write!(output, "{:?}", c).unwrap(),
- }
- output.push_str(": ");
- self.push_type_name(ty, output, debug);
+ pub fn push_const_name(&self, c: &Const<'tcx>, output: &mut String, debug: bool) {
+ match c.val {
+ ConstValue::Infer(..) => output.push_str("_"),
+ ConstValue::Param(ParamConst { name, .. }) => {
+ write!(output, "{}", name).unwrap();
}
+ ConstValue::Unevaluated(..) => output.push_str("_: _"),
+ _ => write!(output, "{:?}", c).unwrap(),
}
+ output.push_str(": ");
+ self.push_type_name(c.ty, output, debug);
}
pub fn push_def_path(&self,
diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs
index 1c6b145..f1fbc80 100644
--- a/src/librustc_mir/shim.rs
+++ b/src/librustc_mir/shim.rs
@@ -458,9 +458,9 @@
span: self.span,
ty: func_ty,
user_ty: None,
- literal: tcx.mk_lazy_const(ty::LazyConst::Evaluated(
+ literal: tcx.mk_const(
ty::Const::zero_sized(func_ty),
- )),
+ ),
});
let ref_loc = self.make_place(
@@ -520,9 +520,9 @@
span: self.span,
ty: self.tcx.types.usize,
user_ty: None,
- literal: self.tcx.mk_lazy_const(ty::LazyConst::Evaluated(
+ literal: self.tcx.mk_const(
ty::Const::from_usize(self.tcx, value),
- )),
+ ),
}
}
@@ -762,9 +762,9 @@
span,
ty,
user_ty: None,
- literal: tcx.mk_lazy_const(ty::LazyConst::Evaluated(
+ literal: tcx.mk_const(
ty::Const::zero_sized(ty)
- )),
+ ),
}),
vec![rcvr])
}
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index 23d8138..d816968 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -253,7 +253,7 @@
source_info: SourceInfo,
) -> Option<Const<'tcx>> {
self.ecx.tcx.span = source_info.span;
- match self.ecx.eval_lazy_const_to_op(*c.literal, None) {
+ match self.ecx.eval_const_to_op(*c.literal, None) {
Ok(op) => {
Some((op, c.span))
},
diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs
index 32c027d..d5098bc 100644
--- a/src/librustc_mir/transform/elaborate_drops.rs
+++ b/src/librustc_mir/transform/elaborate_drops.rs
@@ -533,9 +533,9 @@
span,
ty: self.tcx.types.bool,
user_ty: None,
- literal: self.tcx.mk_lazy_const(ty::LazyConst::Evaluated(
+ literal: self.tcx.mk_const(
ty::Const::from_bool(self.tcx, val),
- )),
+ ),
})))
}
diff --git a/src/librustc_mir/transform/erase_regions.rs b/src/librustc_mir/transform/erase_regions.rs
index 9494d4b..a853f8d 100644
--- a/src/librustc_mir/transform/erase_regions.rs
+++ b/src/librustc_mir/transform/erase_regions.rs
@@ -32,7 +32,7 @@
*region = self.tcx.types.re_erased;
}
- fn visit_const(&mut self, constant: &mut &'tcx ty::LazyConst<'tcx>, _: Location) {
+ fn visit_const(&mut self, constant: &mut &'tcx ty::Const<'tcx>, _: Location) {
*constant = self.tcx.erase_regions(constant);
}
diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs
index 1f59802..b22258a 100644
--- a/src/librustc_mir/transform/generator.rs
+++ b/src/librustc_mir/transform/generator.rs
@@ -26,7 +26,7 @@
//! }
//!
//! This pass computes the meaning of the state field and the MIR locals which are live
-//! across a suspension point. There are however two hardcoded generator states:
+//! across a suspension point. There are however three hardcoded generator states:
//! 0 - Generator have not been resumed yet
//! 1 - Generator has returned / is completed
//! 2 - Generator has been poisoned
@@ -144,6 +144,13 @@
Local::new(1)
}
+/// Generator have not been resumed yet
+const UNRESUMED: u32 = 0;
+/// Generator has returned / is completed
+const RETURNED: u32 = 1;
+/// Generator has been poisoned
+const POISONED: u32 = 2;
+
struct SuspensionPoint {
state: u32,
resume: BasicBlock,
@@ -198,11 +205,11 @@
span: source_info.span,
ty: self.tcx.types.u32,
user_ty: None,
- literal: self.tcx.mk_lazy_const(ty::LazyConst::Evaluated(ty::Const::from_bits(
+ literal: self.tcx.mk_const(ty::Const::from_bits(
self.tcx,
state_disc.into(),
ty::ParamEnv::empty().and(self.tcx.types.u32)
- ))),
+ )),
});
Statement {
source_info,
@@ -278,7 +285,7 @@
state
} else { // Return
- 1 // state for returned
+ RETURNED // state for returned
};
data.statements.push(self.set_state(state, source_info));
data.terminator.as_mut().unwrap().kind = TerminatorKind::Return;
@@ -590,8 +597,15 @@
let param_env = tcx.param_env(def_id);
let gen = self_arg();
- for block in mir.basic_blocks().indices() {
- let (target, unwind, source_info) = match mir.basic_blocks()[block].terminator() {
+ let mut elaborator = DropShimElaborator {
+ mir: mir,
+ patch: MirPatch::new(mir),
+ tcx,
+ param_env
+ };
+
+ for (block, block_data) in mir.basic_blocks().iter_enumerated() {
+ let (target, unwind, source_info) = match block_data.terminator() {
&Terminator {
source_info,
kind: TerminatorKind::Drop {
@@ -602,31 +616,22 @@
} if local == gen => (target, unwind, source_info),
_ => continue,
};
- let unwind = if let Some(unwind) = unwind {
- Unwind::To(unwind)
- } else {
+ let unwind = if block_data.is_cleanup {
Unwind::InCleanup
+ } else {
+ Unwind::To(unwind.unwrap_or_else(|| elaborator.patch.resume_block()))
};
- let patch = {
- let mut elaborator = DropShimElaborator {
- mir: &mir,
- patch: MirPatch::new(mir),
- tcx,
- param_env
- };
- elaborate_drop(
- &mut elaborator,
- source_info,
- &Place::Base(PlaceBase::Local(gen)),
- (),
- target,
- unwind,
- block
- );
- elaborator.patch
- };
- patch.apply(mir);
+ elaborate_drop(
+ &mut elaborator,
+ source_info,
+ &Place::Base(PlaceBase::Local(gen)),
+ (),
+ target,
+ unwind,
+ block,
+ );
}
+ elaborator.patch.apply(mir);
}
fn create_generator_drop_shim<'a, 'tcx>(
@@ -643,10 +648,10 @@
let mut cases = create_cases(&mut mir, transform, |point| point.drop);
- cases.insert(0, (0, drop_clean));
+ cases.insert(0, (UNRESUMED, drop_clean));
- // The returned state (1) and the poisoned state (2) falls through to
- // the default case which is just to return
+ // The returned state and the poisoned state fall through to the default
+ // case which is just to return
insert_switch(tcx, &mut mir, cases, &transform, TerminatorKind::Return);
@@ -729,9 +734,9 @@
span: mir.span,
ty: tcx.types.bool,
user_ty: None,
- literal: tcx.mk_lazy_const(ty::LazyConst::Evaluated(
+ literal: tcx.mk_const(
ty::Const::from_bool(tcx, false),
- )),
+ ),
}),
expected: true,
msg: message,
@@ -762,7 +767,7 @@
for block in mir.basic_blocks_mut() {
let source_info = block.terminator().source_info;
if let &TerminatorKind::Resume = &block.terminator().kind {
- block.statements.push(transform.set_state(1, source_info));
+ block.statements.push(transform.set_state(POISONED, source_info));
}
}
@@ -773,12 +778,12 @@
GeneratorResumedAfterReturn,
};
- // Jump to the entry point on the 0 state
- cases.insert(0, (0, BasicBlock::new(0)));
- // Panic when resumed on the returned (1) state
- cases.insert(1, (1, insert_panic_block(tcx, mir, GeneratorResumedAfterReturn)));
- // Panic when resumed on the poisoned (2) state
- cases.insert(2, (2, insert_panic_block(tcx, mir, GeneratorResumedAfterPanic)));
+ // Jump to the entry point on the unresumed
+ cases.insert(0, (UNRESUMED, BasicBlock::new(0)));
+ // Panic when resumed on the returned state
+ cases.insert(1, (RETURNED, insert_panic_block(tcx, mir, GeneratorResumedAfterReturn)));
+ // Panic when resumed on the poisoned state
+ cases.insert(2, (POISONED, insert_panic_block(tcx, mir, GeneratorResumedAfterPanic)));
insert_switch(tcx, mir, cases, &transform, TerminatorKind::Unreachable);
@@ -942,7 +947,7 @@
mir.generator_layout = Some(layout);
// Insert `drop(generator_struct)` which is used to drop upvars for generators in
- // the unresumed (0) state.
+ // the unresumed state.
// This is expanded to a drop ladder in `elaborate_generator_drops`.
let drop_clean = insert_clean_drop(mir);
diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs
index 0cd2cec..8df0d72 100644
--- a/src/librustc_mir/transform/mod.rs
+++ b/src/librustc_mir/transform/mod.rs
@@ -285,6 +285,7 @@
&simplify_branches::SimplifyBranches::new("after-const-prop"),
&deaggregator::Deaggregator,
©_prop::CopyPropagation,
+ &simplify_branches::SimplifyBranches::new("after-copy-prop"),
&remove_noop_landing_pads::RemoveNoopLandingPads,
&simplify::SimplifyCfg::new("final"),
&simplify::SimplifyLocals,
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 001a619..e966898 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -16,6 +16,7 @@
use rustc::ty::cast::CastTy;
use rustc::ty::query::Providers;
use rustc::mir::*;
+use rustc::mir::interpret::ConstValue;
use rustc::mir::traversal::ReversePostorder;
use rustc::mir::visit::{PlaceContext, Visitor, MutatingUseContext, NonMutatingUseContext};
use rustc::middle::lang_items;
@@ -199,12 +200,12 @@
Operand::Move(ref place) => Self::in_place(cx, place),
Operand::Constant(ref constant) => {
- if let ty::LazyConst::Unevaluated(def_id, _) = constant.literal {
+ if let ConstValue::Unevaluated(def_id, _) = constant.literal.val {
// Don't peek inside trait associated constants.
- if cx.tcx.trait_of_item(*def_id).is_some() {
+ if cx.tcx.trait_of_item(def_id).is_some() {
Self::in_any_value_of_ty(cx, constant.ty).unwrap_or(false)
} else {
- let (bits, _) = cx.tcx.at(constant.span).mir_const_qualif(*def_id);
+ let (bits, _) = cx.tcx.at(constant.span).mir_const_qualif(def_id);
let qualif = PerQualif::decode_from_bits(bits).0[Self::IDX];
diff --git a/src/librustc_mir/transform/simplify_branches.rs b/src/librustc_mir/transform/simplify_branches.rs
index 3c4d122..db73e82 100644
--- a/src/librustc_mir/transform/simplify_branches.rs
+++ b/src/librustc_mir/transform/simplify_branches.rs
@@ -30,7 +30,7 @@
discr: Operand::Constant(ref c), switch_ty, ref values, ref targets, ..
} => {
let switch_ty = ParamEnv::empty().and(switch_ty);
- let constant = c.literal.map_evaluated(|c| c.assert_bits(tcx, switch_ty));
+ let constant = c.literal.assert_bits(tcx, switch_ty);
if let Some(constant) = constant {
let (otherwise, targets) = targets.split_last().unwrap();
let mut ret = TerminatorKind::Goto { target: *otherwise };
@@ -47,7 +47,7 @@
},
TerminatorKind::Assert {
target, cond: Operand::Constant(ref c), expected, ..
- } if (c.literal.map_evaluated(|e| e.assert_bool(tcx)) == Some(true)) == expected =>
+ } if (c.literal.assert_bool(tcx) == Some(true)) == expected =>
TerminatorKind::Goto { target },
TerminatorKind::FalseEdges { real_target, .. } => {
TerminatorKind::Goto { target: real_target }
diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs
index 26fa8d6..37b3833 100644
--- a/src/librustc_mir/util/elaborate_drops.rs
+++ b/src/librustc_mir/util/elaborate_drops.rs
@@ -966,9 +966,9 @@
span: self.source_info.span,
ty: self.tcx().types.usize,
user_ty: None,
- literal: self.tcx().mk_lazy_const(ty::LazyConst::Evaluated(
+ literal: self.tcx().mk_const(
ty::Const::from_usize(self.tcx(), val.into())
- )),
+ ),
})
}
diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs
index a76d26a..13bcdc2 100644
--- a/src/librustc_mir/util/pretty.rs
+++ b/src/librustc_mir/util/pretty.rs
@@ -1,4 +1,5 @@
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
+use rustc::hir::def::CtorKind;
use rustc::mir::*;
use rustc::mir::visit::Visitor;
use rustc::ty::{self, TyCtxt};
@@ -316,9 +317,8 @@
let data = &mir[block];
// Basic block label at the top.
- let cleanup_text = if data.is_cleanup { " // cleanup" } else { "" };
- let lbl = format!("{}{:?}: {{", INDENT, block);
- writeln!(w, "{0:1$}{2}", lbl, ALIGN, cleanup_text)?;
+ let cleanup_text = if data.is_cleanup { " (cleanup)" } else { "" };
+ writeln!(w, "{}{:?}{}: {{", INDENT, block, cleanup_text)?;
// List of statements in the middle.
let mut current_location = Location {
@@ -416,21 +416,12 @@
self.push(&format!("+ literal: {:?}", literal));
}
- fn visit_const(&mut self, constant: &&'tcx ty::LazyConst<'tcx>, _: Location) {
+ fn visit_const(&mut self, constant: &&'tcx ty::Const<'tcx>, _: Location) {
self.super_const(constant);
- match constant {
- ty::LazyConst::Evaluated(constant) => {
- let ty::Const { ty, val, .. } = constant;
- self.push("ty::Const");
- self.push(&format!("+ ty: {:?}", ty));
- self.push(&format!("+ val: {:?}", val));
- },
- ty::LazyConst::Unevaluated(did, substs) => {
- self.push("ty::LazyConst::Unevaluated");
- self.push(&format!("+ did: {:?}", did));
- self.push(&format!("+ substs: {:?}", substs));
- },
- }
+ let ty::Const { ty, val, .. } = constant;
+ self.push("ty::Const");
+ self.push(&format!("+ ty: {:?}", ty));
+ self.push(&format!("+ val: {:?}", val));
}
fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
@@ -596,7 +587,8 @@
trace!("write_mir_sig: {:?}", src.instance);
let descr = tcx.describe_def(src.def_id());
let is_function = match descr {
- Some(Def::Fn(_)) | Some(Def::Method(_)) | Some(Def::StructCtor(..)) => true,
+ Some(Def::Fn(_)) | Some(Def::Method(_)) | Some(Def::Variant(..)) |
+ Some(Def::StructCtor(_, CtorKind::Fn)) => true,
_ => tcx.is_closure(src.def_id()),
};
match (descr, src.promoted) {
diff --git a/src/librustc_passes/layout_test.rs b/src/librustc_passes/layout_test.rs
index 7fe3f5a..373bcf7 100644
--- a/src/librustc_passes/layout_test.rs
+++ b/src/librustc_passes/layout_test.rs
@@ -53,9 +53,7 @@
// The `..` are the names of fields to dump.
let meta_items = attr.meta_item_list().unwrap_or_default();
for meta_item in meta_items {
- let name = meta_item.word().map(|mi| mi.name().as_str());
- let name = name.as_ref().map(|s| &s[..]).unwrap_or("");
-
+ let name = meta_item.ident_str().unwrap_or("");
match name {
"abi" => {
self.tcx
@@ -88,7 +86,7 @@
_ => {
self.tcx.sess.span_err(
- meta_item.span,
+ meta_item.span(),
&format!("unrecognized field name `{}`", name),
);
}
diff --git a/src/librustc_plugin/load.rs b/src/librustc_plugin/load.rs
index 1b88cf0..bd11e0c 100644
--- a/src/librustc_plugin/load.rs
+++ b/src/librustc_plugin/load.rs
@@ -56,10 +56,10 @@
for plugin in plugins {
// plugins must have a name and can't be key = value
- match plugin.name() {
+ match plugin.ident_str() {
Some(name) if !plugin.is_value_str() => {
let args = plugin.meta_item_list().map(ToOwned::to_owned);
- loader.load_plugin(plugin.span, &name.as_str(), args.unwrap_or_default());
+ loader.load_plugin(plugin.span(), name, args.unwrap_or_default());
},
_ => call_malformed_plugin_attribute(sess, attr.span),
}
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 5c99270..6fad4b2 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -463,10 +463,9 @@
if let Some(attr) = attr::find_by_name(&item.attrs, "proc_macro_derive") {
if let Some(trait_attr) =
attr.meta_item_list().and_then(|list| list.get(0).cloned()) {
- if let Some(ident) = trait_attr.name().map(Ident::with_empty_ctxt) {
- let sp = trait_attr.span;
+ if let Some(ident) = trait_attr.ident() {
let def = Def::Macro(def.def_id(), MacroKind::ProcMacroStub);
- self.define(parent, ident, MacroNS, (def, vis, sp, expansion));
+ self.define(parent, ident, MacroNS, (def, vis, ident.span, expansion));
}
}
}
@@ -636,10 +635,9 @@
// but metadata cannot encode gensyms currently, so we create it here.
// This is only a guess, two equivalent idents may incorrectly get different gensyms here.
let ident = ident.gensym_if_underscore();
- let def_id = def.def_id();
let expansion = Mark::root(); // FIXME(jseyfried) intercrate hygiene
match def {
- Def::Mod(..) | Def::Enum(..) => {
+ Def::Mod(def_id) | Def::Enum(def_id) => {
let module = self.new_module(parent,
ModuleKind::Def(def, ident.name),
def_id,
@@ -647,13 +645,14 @@
span);
self.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, expansion));
}
- Def::Variant(..) | Def::TyAlias(..) | Def::ForeignTy(..) => {
+ Def::Variant(..) | Def::TyAlias(..) | Def::ForeignTy(..) | Def::Existential(..) |
+ Def::TraitAlias(..) | Def::PrimTy(..) | Def::ToolMod => {
self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, expansion));
}
Def::Fn(..) | Def::Static(..) | Def::Const(..) | Def::VariantCtor(..) => {
self.define(parent, ident, ValueNS, (def, vis, DUMMY_SP, expansion));
}
- Def::StructCtor(..) => {
+ Def::StructCtor(def_id, ..) => {
self.define(parent, ident, ValueNS, (def, vis, DUMMY_SP, expansion));
if let Some(struct_def_id) =
@@ -662,7 +661,7 @@
self.struct_constructors.insert(struct_def_id, (def, vis));
}
}
- Def::Trait(..) => {
+ Def::Trait(def_id) => {
let module_kind = ModuleKind::Def(def, ident.name);
let module = self.new_module(parent,
module_kind,
@@ -683,18 +682,14 @@
}
module.populated.set(true);
}
- Def::Existential(..) |
- Def::TraitAlias(..) => {
- self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, expansion));
- }
- Def::Struct(..) | Def::Union(..) => {
+ Def::Struct(def_id) | Def::Union(def_id) => {
self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, expansion));
// Record field names for error reporting.
let field_names = self.cstore.struct_field_names_untracked(def_id);
self.insert_field_names(def_id, field_names);
}
- Def::Macro(..) => {
+ Def::Macro(..) | Def::NonMacroAttr(..) => {
self.define(parent, ident, MacroNS, (def, vis, DUMMY_SP, expansion));
}
_ => bug!("unexpected definition: {:?}", def)
@@ -812,14 +807,14 @@
break;
}
MetaItemKind::List(nested_metas) => for nested_meta in nested_metas {
- match nested_meta.word() {
- Some(word) => single_imports.push((word.name(), word.span)),
- None => ill_formed(nested_meta.span),
+ match nested_meta.ident() {
+ Some(ident) if nested_meta.is_word() => single_imports.push(ident),
+ _ => ill_formed(nested_meta.span()),
}
}
MetaItemKind::NameValue(..) => ill_formed(meta.span),
}
- None => ill_formed(attr.span()),
+ None => ill_formed(attr.span),
}
}
}
@@ -850,23 +845,23 @@
self.legacy_import_macro(ident.name, imported_binding, span, allow_shadowing);
});
} else {
- for (name, span) in single_imports.iter().cloned() {
- let ident = Ident::with_empty_ctxt(name);
+ for ident in single_imports.iter().cloned() {
let result = self.resolve_ident_in_module(
ModuleOrUniformRoot::Module(module),
ident,
MacroNS,
None,
false,
- span,
+ ident.span,
);
if let Ok(binding) = result {
- let directive = macro_use_directive(span);
+ let directive = macro_use_directive(ident.span);
self.potentially_unused_imports.push(directive);
let imported_binding = self.import(binding, directive);
- self.legacy_import_macro(name, imported_binding, span, allow_shadowing);
+ self.legacy_import_macro(ident.name, imported_binding,
+ ident.span, allow_shadowing);
} else {
- span_err!(self.session, span, E0469, "imported macro not found");
+ span_err!(self.session, ident.span, E0469, "imported macro not found");
}
}
}
diff --git a/src/librustc_resolve/error_reporting.rs b/src/librustc_resolve/error_reporting.rs
index cd771d9..828ffc6 100644
--- a/src/librustc_resolve/error_reporting.rs
+++ b/src/librustc_resolve/error_reporting.rs
@@ -293,13 +293,20 @@
(Def::Enum(..), PathSource::TupleStruct)
| (Def::Enum(..), PathSource::Expr(..)) => {
if let Some(variants) = self.collect_enum_variants(def) {
- err.note(&format!("did you mean to use one \
- of the following variants?\n{}",
- variants.iter()
- .map(|suggestion| path_names_to_string(suggestion))
- .map(|suggestion| format!("- `{}`", suggestion))
- .collect::<Vec<_>>()
- .join("\n")));
+ if !variants.is_empty() {
+ let msg = if variants.len() == 1 {
+ "try using the enum's variant"
+ } else {
+ "try using one of the enum's variants"
+ };
+
+ err.span_suggestions(
+ span,
+ msg,
+ variants.iter().map(path_names_to_string),
+ Applicability::MaybeIncorrect,
+ );
+ }
} else {
err.note("did you mean to use one of the enum's variants?");
}
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index 3fea515..01bb643 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -481,8 +481,8 @@
};
let (value, fields) = match item.node {
- ast::ItemKind::Struct(ast::VariantData::Struct(ref fields, _), _) |
- ast::ItemKind::Union(ast::VariantData::Struct(ref fields, _), _) => {
+ ast::ItemKind::Struct(ast::VariantData::Struct(ref fields, ..), _) |
+ ast::ItemKind::Union(ast::VariantData::Struct(ref fields, ..), _) => {
let include_priv_fields = !self.save_ctxt.config.pub_only;
let fields_str = fields
.iter()
@@ -560,7 +560,7 @@
let name_span = variant.node.ident.span;
match variant.node.data {
- ast::VariantData::Struct(ref fields, _) => {
+ ast::VariantData::Struct(ref fields, ..) => {
let fields_str = fields
.iter()
.enumerate()
diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs
index 64a2c92..6e47ae6 100644
--- a/src/librustc_save_analysis/sig.rs
+++ b/src/librustc_save_analysis/sig.rs
@@ -703,7 +703,7 @@
fn make(&self, offset: usize, _parent_id: Option<NodeId>, scx: &SaveContext<'_, '_>) -> Result {
let mut text = self.ident.to_string();
match self.data {
- ast::VariantData::Struct(ref fields, id) => {
+ ast::VariantData::Struct(ref fields, id, r) => {
let name_def = SigElement {
id: id_from_node_id(id, scx),
start: offset,
@@ -712,12 +712,16 @@
text.push_str(" { ");
let mut defs = vec![name_def];
let mut refs = vec![];
- for f in fields {
- let field_sig = f.make(offset + text.len(), Some(id), scx)?;
- text.push_str(&field_sig.text);
- text.push_str(", ");
- defs.extend(field_sig.defs.into_iter());
- refs.extend(field_sig.refs.into_iter());
+ if r {
+ text.push_str("/* parse error */ ");
+ } else {
+ for f in fields {
+ let field_sig = f.make(offset + text.len(), Some(id), scx)?;
+ text.push_str(&field_sig.text);
+ text.push_str(", ");
+ defs.extend(field_sig.defs.into_iter());
+ refs.extend(field_sig.refs.into_iter());
+ }
}
text.push('}');
Ok(Signature { text, defs, refs })
diff --git a/src/librustc_target/spec/mipsisa32r6_unknown_linux_gnu.rs b/src/librustc_target/spec/mipsisa32r6_unknown_linux_gnu.rs
new file mode 100644
index 0000000..f472914
--- /dev/null
+++ b/src/librustc_target/spec/mipsisa32r6_unknown_linux_gnu.rs
@@ -0,0 +1,23 @@
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+
+pub fn target() -> TargetResult {
+ Ok(Target {
+ llvm_target: "mipsisa32r6-unknown-linux-gnu".to_string(),
+ target_endian: "big".to_string(),
+ target_pointer_width: "32".to_string(),
+ target_c_int_width: "32".to_string(),
+ data_layout: "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".to_string(),
+ arch: "mips".to_string(),
+ target_os: "linux".to_string(),
+ target_env: "gnu".to_string(),
+ target_vendor: "unknown".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
+ options: TargetOptions {
+ cpu: "mips32r6".to_string(),
+ features: "+mips32r6".to_string(),
+ max_atomic_width: Some(32),
+
+ ..super::linux_base::opts()
+ },
+ })
+}
diff --git a/src/librustc_target/spec/mipsisa32r6el_unknown_linux_gnu.rs b/src/librustc_target/spec/mipsisa32r6el_unknown_linux_gnu.rs
new file mode 100644
index 0000000..f4f98d3
--- /dev/null
+++ b/src/librustc_target/spec/mipsisa32r6el_unknown_linux_gnu.rs
@@ -0,0 +1,24 @@
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+
+pub fn target() -> TargetResult {
+ Ok(Target {
+ llvm_target: "mipsisa32r6el-unknown-linux-gnu".to_string(),
+ target_endian: "little".to_string(),
+ target_pointer_width: "32".to_string(),
+ target_c_int_width: "32".to_string(),
+ data_layout: "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".to_string(),
+ arch: "mips".to_string(),
+ target_os: "linux".to_string(),
+ target_env: "gnu".to_string(),
+ target_vendor: "unknown".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
+
+ options: TargetOptions {
+ cpu: "mips32r6".to_string(),
+ features: "+mips32r6".to_string(),
+ max_atomic_width: Some(32),
+
+ ..super::linux_base::opts()
+ },
+ })
+}
diff --git a/src/librustc_target/spec/mipsisa64r6_unknown_linux_gnuabi64.rs b/src/librustc_target/spec/mipsisa64r6_unknown_linux_gnuabi64.rs
new file mode 100644
index 0000000..7faed3a
--- /dev/null
+++ b/src/librustc_target/spec/mipsisa64r6_unknown_linux_gnuabi64.rs
@@ -0,0 +1,24 @@
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+
+pub fn target() -> TargetResult {
+ Ok(Target {
+ llvm_target: "mipsisa64r6-unknown-linux-gnuabi64".to_string(),
+ target_endian: "big".to_string(),
+ target_pointer_width: "64".to_string(),
+ target_c_int_width: "32".to_string(),
+ data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
+ arch: "mips64".to_string(),
+ target_os: "linux".to_string(),
+ target_env: "gnu".to_string(),
+ target_vendor: "unknown".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
+ options: TargetOptions {
+ // NOTE(mips64r6) matches C toolchain
+ cpu: "mips64r6".to_string(),
+ features: "+mips64r6".to_string(),
+ max_atomic_width: Some(64),
+
+ ..super::linux_base::opts()
+ },
+ })
+}
diff --git a/src/librustc_target/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs b/src/librustc_target/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs
new file mode 100644
index 0000000..58a814a
--- /dev/null
+++ b/src/librustc_target/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs
@@ -0,0 +1,24 @@
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+
+pub fn target() -> TargetResult {
+ Ok(Target {
+ llvm_target: "mipsisa64r6el-unknown-linux-gnuabi64".to_string(),
+ target_endian: "little".to_string(),
+ target_pointer_width: "64".to_string(),
+ target_c_int_width: "32".to_string(),
+ data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
+ arch: "mips64".to_string(),
+ target_os: "linux".to_string(),
+ target_env: "gnu".to_string(),
+ target_vendor: "unknown".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
+ options: TargetOptions {
+ // NOTE(mips64r6) matches C toolchain
+ cpu: "mips64r6".to_string(),
+ features: "+mips64r6".to_string(),
+ max_atomic_width: Some(64),
+
+ ..super::linux_base::opts()
+ },
+ })
+}
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index 2824d9c..fdb1db6 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -335,6 +335,10 @@
("mips-unknown-linux-gnu", mips_unknown_linux_gnu),
("mips64-unknown-linux-gnuabi64", mips64_unknown_linux_gnuabi64),
("mips64el-unknown-linux-gnuabi64", mips64el_unknown_linux_gnuabi64),
+ ("mipsisa32r6-unknown-linux-gnu", mipsisa32r6_unknown_linux_gnu),
+ ("mipsisa32r6el-unknown-linux-gnu", mipsisa32r6el_unknown_linux_gnu),
+ ("mipsisa64r6-unknown-linux-gnuabi64", mipsisa64r6_unknown_linux_gnuabi64),
+ ("mipsisa64r6el-unknown-linux-gnuabi64", mipsisa64r6el_unknown_linux_gnuabi64),
("mipsel-unknown-linux-gnu", mipsel_unknown_linux_gnu),
("powerpc-unknown-linux-gnu", powerpc_unknown_linux_gnu),
("powerpc-unknown-linux-gnuspe", powerpc_unknown_linux_gnuspe),
diff --git a/src/librustc_target/spec/uefi_base.rs b/src/librustc_target/spec/uefi_base.rs
index 631966c..956767a 100644
--- a/src/librustc_target/spec/uefi_base.rs
+++ b/src/librustc_target/spec/uefi_base.rs
@@ -59,7 +59,7 @@
singlethread: true,
emit_debug_gdb_scripts: false,
- linker: Some("lld-link".to_string()),
+ linker: Some("rust-lld".to_string()),
lld_flavor: LldFlavor::Link,
pre_link_args,
diff --git a/src/librustc_traits/chalk_context/mod.rs b/src/librustc_traits/chalk_context/mod.rs
index 6420f20..334f510 100644
--- a/src/librustc_traits/chalk_context/mod.rs
+++ b/src/librustc_traits/chalk_context/mod.rs
@@ -288,13 +288,10 @@
}
_ => false,
},
- UnpackedKind::Const(ct) => match ct {
- ty::LazyConst::Evaluated(ty::Const {
- val: ConstValue::Infer(InferConst::Canonical(debruijn, bound_ct)),
- ..
- }) => {
- debug_assert_eq!(*debruijn, ty::INNERMOST);
- cvar == *bound_ct
+ UnpackedKind::Const(ct) => match ct.val {
+ ConstValue::Infer(InferConst::Canonical(debruijn, bound_ct)) => {
+ debug_assert_eq!(debruijn, ty::INNERMOST);
+ cvar == bound_ct
}
_ => false,
}
diff --git a/src/librustc_traits/chalk_context/program_clauses.rs b/src/librustc_traits/chalk_context/program_clauses.rs
index 3f88d0e..8d5d2b8 100644
--- a/src/librustc_traits/chalk_context/program_clauses.rs
+++ b/src/librustc_traits/chalk_context/program_clauses.rs
@@ -239,7 +239,7 @@
fn wf_clause_for_array<'tcx>(
tcx: ty::TyCtxt<'_, '_, 'tcx>,
- length: &'tcx ty::LazyConst<'tcx>
+ length: &'tcx ty::Const<'tcx>
) -> Clauses<'tcx> {
let ty = generic_types::bound(tcx, 0);
let array_ty = tcx.mk_ty(ty::Array(ty, length));
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 22fa3dc..e470748 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -1485,37 +1485,34 @@
segment.with_generic_args(|generic_args| {
let (mut err_for_lt, mut err_for_ty, mut err_for_ct) = (false, false, false);
for arg in &generic_args.args {
- let (mut span_err, span, kind) = match arg {
- // FIXME(varkor): unify E0109, E0110 and E0111.
+ let (span, kind) = match arg {
hir::GenericArg::Lifetime(lt) => {
if err_for_lt { continue }
err_for_lt = true;
has_err = true;
- (struct_span_err!(self.tcx().sess, lt.span, E0110,
- "lifetime arguments are not allowed on this entity"),
- lt.span,
- "lifetime")
+ (lt.span, "lifetime")
}
hir::GenericArg::Type(ty) => {
if err_for_ty { continue }
err_for_ty = true;
has_err = true;
- (struct_span_err!(self.tcx().sess, ty.span, E0109,
- "type arguments are not allowed on this entity"),
- ty.span,
- "type")
+ (ty.span, "type")
}
hir::GenericArg::Const(ct) => {
if err_for_ct { continue }
err_for_ct = true;
- (struct_span_err!(self.tcx().sess, ct.span, E0111,
- "const parameters are not allowed on this type"),
- ct.span,
- "const")
+ (ct.span, "const")
}
};
- span_err.span_label(span, format!("{} argument not allowed", kind))
- .emit();
+ let mut err = struct_span_err!(
+ self.tcx().sess,
+ span,
+ E0109,
+ "{} arguments are not allowed for this type",
+ kind,
+ );
+ err.span_label(span, format!("{} argument not allowed", kind));
+ err.emit();
if err_for_lt && err_for_ty && err_for_ct {
break;
}
@@ -1869,16 +1866,19 @@
&self,
ast_const: &hir::AnonConst,
ty: Ty<'tcx>
- ) -> &'tcx ty::LazyConst<'tcx> {
+ ) -> &'tcx ty::Const<'tcx> {
debug!("ast_const_to_const(id={:?}, ast_const={:?})", ast_const.hir_id, ast_const);
let tcx = self.tcx();
let def_id = tcx.hir().local_def_id_from_hir_id(ast_const.hir_id);
- let mut lazy_const = ty::LazyConst::Unevaluated(
- def_id,
- InternalSubsts::identity_for_item(tcx, def_id),
- );
+ let mut const_ = ty::Const {
+ val: ConstValue::Unevaluated(
+ def_id,
+ InternalSubsts::identity_for_item(tcx, def_id),
+ ),
+ ty,
+ };
let expr = &tcx.hir().body(ast_const.body).value;
if let ExprKind::Path(ref qpath) = expr.node {
@@ -1890,15 +1890,12 @@
let generics = tcx.generics_of(item_def_id);
let index = generics.param_def_id_to_index[&tcx.hir().local_def_id(node_id)];
let name = tcx.hir().name(node_id).as_interned_str();
- lazy_const = ty::LazyConst::Evaluated(ty::Const {
- val: ConstValue::Param(ty::ParamConst::new(index, name)),
- ty,
- })
+ const_.val = ConstValue::Param(ty::ParamConst::new(index, name));
}
}
};
- tcx.mk_lazy_const(lazy_const)
+ tcx.mk_const(const_)
}
pub fn impl_trait_ty_to_ty(
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index c6b6639..c30b9d6 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -918,14 +918,16 @@
pat_ty
}
- fn check_struct_pat_fields(&self,
- adt_ty: Ty<'tcx>,
- pat_id: hir::HirId,
- span: Span,
- variant: &'tcx ty::VariantDef,
- fields: &'gcx [Spanned<hir::FieldPat>],
- etc: bool,
- def_bm: ty::BindingMode) -> bool {
+ fn check_struct_pat_fields(
+ &self,
+ adt_ty: Ty<'tcx>,
+ pat_id: hir::HirId,
+ span: Span,
+ variant: &'tcx ty::VariantDef,
+ fields: &'gcx [Spanned<hir::FieldPat>],
+ etc: bool,
+ def_bm: ty::BindingMode,
+ ) -> bool {
let tcx = self.tcx;
let (substs, adt) = match adt_ty.sty {
@@ -985,7 +987,7 @@
.map(|field| field.ident.modern())
.filter(|ident| !used_fields.contains_key(&ident))
.collect::<Vec<_>>();
- if inexistent_fields.len() > 0 {
+ if inexistent_fields.len() > 0 && !variant.recovered {
let (field_names, t, plural) = if inexistent_fields.len() == 1 {
(format!("a field named `{}`", inexistent_fields[0].1), "this", "")
} else {
diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs
index 0a4c0eb..15ae396 100644
--- a/src/librustc_typeck/check/callee.rs
+++ b/src/librustc_typeck/check/callee.rs
@@ -2,7 +2,7 @@
use super::method::MethodCallee;
use super::{Expectation, FnCtxt, Needs, TupleArgumentsFlag};
-use errors::Applicability;
+use errors::{Applicability, DiagnosticBuilder};
use hir::def::Def;
use hir::def_id::{DefId, LOCAL_CRATE};
use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
@@ -232,6 +232,32 @@
None
}
+ /// Give appropriate suggestion when encountering `||{/* not callable */}()`, where the
+ /// likely intention is to call the closure, suggest `(||{})()`. (#55851)
+ fn identify_bad_closure_def_and_call(
+ &self,
+ err: &mut DiagnosticBuilder<'a>,
+ hir_id: hir::HirId,
+ callee_node: &hir::ExprKind,
+ callee_span: Span,
+ ) {
+ let hir_id = self.tcx.hir().get_parent_node_by_hir_id(hir_id);
+ let parent_node = self.tcx.hir().get_by_hir_id(hir_id);
+ if let (
+ hir::Node::Expr(hir::Expr { node: hir::ExprKind::Closure(_, _, _, sp, ..), .. }),
+ hir::ExprKind::Block(..),
+ ) = (parent_node, callee_node) {
+ let start = sp.shrink_to_lo();
+ let end = self.tcx.sess.source_map().next_point(callee_span);
+ err.multipart_suggestion(
+ "if you meant to create this closure and immediately call it, surround the \
+ closure with parenthesis",
+ vec![(start, "(".to_string()), (end, ")".to_string())],
+ Applicability::MaybeIncorrect,
+ );
+ }
+ }
+
fn confirm_builtin_call(
&self,
call_expr: &hir::Expr,
@@ -268,6 +294,13 @@
}
);
+ self.identify_bad_closure_def_and_call(
+ &mut err,
+ call_expr.hir_id,
+ &callee.node,
+ callee.span,
+ );
+
if let Some(ref path) = unit_variant {
err.span_suggestion(
call_expr.span,
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 5088c50..f872caa 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -334,44 +334,61 @@
// If the method name is the name of a field with a function or closure type,
// give a helping note that it has to be called as `(x.f)(...)`.
if let SelfSource::MethodCall(expr) = source {
- for (ty, _) in self.autoderef(span, rcvr_ty) {
- if let ty::Adt(def, substs) = ty.sty {
- if !def.is_enum() {
+ let field_receiver = self
+ .autoderef(span, rcvr_ty)
+ .find_map(|(ty, _)| match ty.sty {
+ ty::Adt(def, substs) if !def.is_enum() => {
let variant = &def.non_enum_variant();
- if let Some(index) = self.tcx.find_field_index(item_name, variant) {
+ self.tcx.find_field_index(item_name, variant).map(|index| {
let field = &variant.fields[index];
- let snippet = tcx.sess.source_map().span_to_snippet(expr.span);
- let expr_string = match snippet {
- Ok(expr_string) => expr_string,
- _ => "s".into(), // Default to a generic placeholder for the
- // expression when we can't generate a
- // string snippet.
- };
-
let field_ty = field.ty(tcx, substs);
- let scope = self.tcx.hir().get_module_parent_by_hir_id(
- self.body_id);
- if field.vis.is_accessible_from(scope, self.tcx) {
- if self.is_fn_ty(&field_ty, span) {
- err.help(&format!("use `({0}.{1})(...)` if you \
- meant to call the function \
- stored in the `{1}` field",
- expr_string,
- item_name));
- } else {
- err.help(&format!("did you mean to write `{0}.{1}` \
- instead of `{0}.{1}(...)`?",
- expr_string,
- item_name));
- }
- err.span_label(span, "field, not a method");
- } else {
- err.span_label(span, "private field, not a method");
- }
- break;
- }
+ (field, field_ty)
+ })
+ }
+ _ => None,
+ });
+
+ if let Some((field, field_ty)) = field_receiver {
+ let scope = self.tcx.hir().get_module_parent_by_hir_id(self.body_id);
+ let is_accessible = field.vis.is_accessible_from(scope, self.tcx);
+
+ if is_accessible {
+ if self.is_fn_ty(&field_ty, span) {
+ let expr_span = expr.span.to(item_name.span);
+ err.multipart_suggestion(
+ &format!(
+ "to call the function stored in `{}`, \
+ surround the field access with parentheses",
+ item_name,
+ ),
+ vec![
+ (expr_span.shrink_to_lo(), '('.to_string()),
+ (expr_span.shrink_to_hi(), ')'.to_string()),
+ ],
+ Applicability::MachineApplicable,
+ );
+ } else {
+ let call_expr = self.tcx.hir().expect_expr_by_hir_id(
+ self.tcx.hir().get_parent_node_by_hir_id(expr.hir_id),
+ );
+
+ let span = call_expr.span.trim_start(item_name.span).unwrap();
+
+ err.span_suggestion(
+ span,
+ "remove the arguments",
+ String::new(),
+ Applicability::MaybeIncorrect,
+ );
}
}
+
+ let field_kind = if is_accessible {
+ "field"
+ } else {
+ "private field"
+ };
+ err.span_label(item_name.span, format!("{}, not a method", field_kind));
}
} else {
err.span_label(span, format!("{} not found in `{}`", item_kind, ty_str));
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 1383bf2..ab0e4b0 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -2424,7 +2424,7 @@
ty
}
- pub fn to_const(&self, ast_c: &hir::AnonConst, ty: Ty<'tcx>) -> &'tcx ty::LazyConst<'tcx> {
+ pub fn to_const(&self, ast_c: &hir::AnonConst, ty: Ty<'tcx>) -> &'tcx ty::Const<'tcx> {
AstConv::ast_const_to_const(self, ast_c, ty)
}
@@ -3463,8 +3463,22 @@
// We won't diverge unless both branches do (or the condition does).
self.diverges.set(cond_diverges | then_diverges & else_diverges);
} else {
+ // If this `if` expr is the parent's function return expr, the cause of the type
+ // coercion is the return type, point at it. (#25228)
+ let ret_reason = self.maybe_get_coercion_reason(then_expr.hir_id, sp);
+
let else_cause = self.cause(sp, ObligationCauseCode::IfExpressionWithNoElse);
- coerce.coerce_forced_unit(self, &else_cause, &mut |_| (), true);
+ coerce.coerce_forced_unit(self, &else_cause, &mut |err| {
+ if let Some((sp, msg)) = &ret_reason {
+ err.span_label(*sp, msg.as_str());
+ } else if let ExprKind::Block(block, _) = &then_expr.node {
+ if let Some(expr) = &block.expr {
+ err.span_label(expr.span, "found here".to_string());
+ }
+ }
+ err.note("`if` expressions without `else` evaluate to `()`");
+ err.help("consider adding an `else` block that evaluates to the expected type");
+ }, ret_reason.is_none());
// If the condition is false we can't diverge.
self.diverges.set(cond_diverges);
@@ -3478,6 +3492,37 @@
}
}
+ fn maybe_get_coercion_reason(&self, hir_id: hir::HirId, sp: Span) -> Option<(Span, String)> {
+ let node = self.tcx.hir().get_by_hir_id(self.tcx.hir().get_parent_node_by_hir_id(
+ self.tcx.hir().get_parent_node_by_hir_id(hir_id),
+ ));
+ if let Node::Block(block) = node {
+ // check that the body's parent is an fn
+ let parent = self.tcx.hir().get_by_hir_id(
+ self.tcx.hir().get_parent_node_by_hir_id(
+ self.tcx.hir().get_parent_node_by_hir_id(block.hir_id),
+ ),
+ );
+ if let (Some(expr), Node::Item(hir::Item {
+ node: hir::ItemKind::Fn(..), ..
+ })) = (&block.expr, parent) {
+ // check that the `if` expr without `else` is the fn body's expr
+ if expr.span == sp {
+ return self.get_fn_decl(hir_id).map(|(fn_decl, _)| (
+ fn_decl.output.span(),
+ format!("expected `{}` because of this return type", fn_decl.output),
+ ));
+ }
+ }
+ }
+ if let Node::Local(hir::Local {
+ ty: Some(_), pat, ..
+ }) = node {
+ return Some((pat.span, "expected because of this assignment".to_string()));
+ }
+ None
+ }
+
// Check field access expressions
fn check_field(&self,
expr: &'gcx hir::Expr,
@@ -3689,12 +3734,17 @@
field, expr_t)
}
- fn report_unknown_field(&self,
- ty: Ty<'tcx>,
- variant: &'tcx ty::VariantDef,
- field: &hir::Field,
- skip_fields: &[hir::Field],
- kind_name: &str) {
+ fn report_unknown_field(
+ &self,
+ ty: Ty<'tcx>,
+ variant: &'tcx ty::VariantDef,
+ field: &hir::Field,
+ skip_fields: &[hir::Field],
+ kind_name: &str,
+ ) {
+ if variant.recovered {
+ return;
+ }
let mut err = self.type_error_struct_with_diag(
field.ident.span,
|actual| match ty.sty {
@@ -4594,7 +4644,7 @@
if element_ty.references_error() {
tcx.types.err
} else if let Ok(count) = count {
- tcx.mk_ty(ty::Array(t, tcx.mk_lazy_const(ty::LazyConst::Evaluated(count))))
+ tcx.mk_ty(ty::Array(t, tcx.mk_const(count)))
} else {
tcx.types.err
}
@@ -5288,6 +5338,53 @@
Some(original_span.with_lo(original_span.hi() - BytePos(1)))
}
+ // Rewrite `SelfCtor` to `StructCtor`
+ pub fn rewrite_self_ctor(&self, def: Def, span: Span) -> (Def, DefId, Ty<'tcx>) {
+ let tcx = self.tcx;
+ if let Def::SelfCtor(impl_def_id) = def {
+ let ty = self.impl_self_ty(span, impl_def_id).ty;
+ let adt_def = ty.ty_adt_def();
+
+ match adt_def {
+ Some(adt_def) if adt_def.has_ctor() => {
+ let variant = adt_def.non_enum_variant();
+ let def = Def::StructCtor(variant.did, variant.ctor_kind);
+ (def, variant.did, tcx.type_of(variant.did))
+ }
+ _ => {
+ let mut err = tcx.sess.struct_span_err(span,
+ "the `Self` constructor can only be used with tuple or unit structs");
+ if let Some(adt_def) = adt_def {
+ match adt_def.adt_kind() {
+ AdtKind::Enum => {
+ err.help("did you mean to use one of the enum's variants?");
+ },
+ AdtKind::Struct |
+ AdtKind::Union => {
+ err.span_suggestion(
+ span,
+ "use curly brackets",
+ String::from("Self { /* fields */ }"),
+ Applicability::HasPlaceholders,
+ );
+ }
+ }
+ }
+ err.emit();
+
+ (def, impl_def_id, tcx.types.err)
+ }
+ }
+ } else {
+ let def_id = def.def_id();
+
+ // The things we are substituting into the type should not contain
+ // escaping late-bound regions, and nor should the base type scheme.
+ let ty = tcx.type_of(def_id);
+ (def, def_id, ty)
+ }
+ }
+
// Instantiates the given path, which must refer to an item with the given
// number of type parameters and type.
pub fn instantiate_value_path(&self,
@@ -5307,6 +5404,18 @@
let tcx = self.tcx;
+ match def {
+ Def::Local(nid) | Def::Upvar(nid, ..) => {
+ let hid = self.tcx.hir().node_to_hir_id(nid);
+ let ty = self.local_ty(span, hid).decl_ty;
+ let ty = self.normalize_associated_types_in(span, &ty);
+ self.write_ty(hir_id, ty);
+ return (ty, def);
+ }
+ _ => {}
+ }
+
+ let (def, def_id, ty) = self.rewrite_self_ctor(def, span);
let path_segs = AstConv::def_ids_for_path_segments(self, segments, self_ty, def);
let mut user_self_ty = None;
@@ -5368,17 +5477,6 @@
user_self_ty = None;
}
- match def {
- Def::Local(nid) | Def::Upvar(nid, ..) => {
- let hid = self.tcx.hir().node_to_hir_id(nid);
- let ty = self.local_ty(span, hid).decl_ty;
- let ty = self.normalize_associated_types_in(span, &ty);
- self.write_ty(hir_id, ty);
- return (ty, def);
- }
- _ => {}
- }
-
// Now we have to compare the types that the user *actually*
// provided against the types that were *expected*. If the user
// did not provide any types, then we want to substitute inference
@@ -5411,53 +5509,6 @@
tcx.generics_of(*def_id).has_self
}).unwrap_or(false);
- let mut new_def = def;
- let (def_id, ty) = match def {
- Def::SelfCtor(impl_def_id) => {
- let ty = self.impl_self_ty(span, impl_def_id).ty;
- let adt_def = ty.ty_adt_def();
-
- match adt_def {
- Some(adt_def) if adt_def.has_ctor() => {
- let variant = adt_def.non_enum_variant();
- new_def = Def::StructCtor(variant.did, variant.ctor_kind);
- (variant.did, tcx.type_of(variant.did))
- }
- _ => {
- let mut err = tcx.sess.struct_span_err(span,
- "the `Self` constructor can only be used with tuple or unit structs");
- if let Some(adt_def) = adt_def {
- match adt_def.adt_kind() {
- AdtKind::Enum => {
- err.help("did you mean to use one of the enum's variants?");
- },
- AdtKind::Struct |
- AdtKind::Union => {
- err.span_suggestion(
- span,
- "use curly brackets",
- String::from("Self { /* fields */ }"),
- Applicability::HasPlaceholders,
- );
- }
- }
- }
- err.emit();
-
- (impl_def_id, tcx.types.err)
- }
- }
- }
- _ => {
- let def_id = def.def_id();
-
- // The things we are substituting into the type should not contain
- // escaping late-bound regions, and nor should the base type scheme.
- let ty = tcx.type_of(def_id);
- (def_id, ty)
- }
- };
-
let substs = AstConv::create_substs_for_generic_args(
tcx,
def_id,
@@ -5573,7 +5624,7 @@
ty_substituted);
self.write_substs(hir_id, substs);
- (ty_substituted, new_def)
+ (ty_substituted, def)
}
fn check_rustc_args_require_const(&self,
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index 1f7e05d..0675fea 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -506,11 +506,8 @@
true
}
- fn visit_const(&mut self, c: &'tcx ty::LazyConst<'tcx>) -> bool {
- if let ty::LazyConst::Evaluated(ty::Const {
- val: ConstValue::Param(param),
- ..
- }) = c {
+ fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> bool {
+ if let ConstValue::Param(param) = c.val {
self.params.insert(param.index);
}
c.super_visit_with(self)
@@ -678,11 +675,8 @@
}
}
- ty::subst::UnpackedKind::Const(ct) => match ct {
- ty::LazyConst::Evaluated(ty::Const {
- val: ConstValue::Param(_),
- ..
- }) => {}
+ ty::subst::UnpackedKind::Const(ct) => match ct.val {
+ ConstValue::Param(_) => {}
_ => {
tcx.sess
.struct_span_err(
diff --git a/src/librustc_typeck/coherence/inherent_impls_overlap.rs b/src/librustc_typeck/coherence/inherent_impls_overlap.rs
index 832c172..d0156db 100644
--- a/src/librustc_typeck/coherence/inherent_impls_overlap.rs
+++ b/src/librustc_typeck/coherence/inherent_impls_overlap.rs
@@ -25,7 +25,7 @@
let name_and_namespace = |def_id| {
let item = self.tcx.associated_item(def_id);
- (item.ident, Namespace::from(item.kind))
+ (item.ident.modern(), Namespace::from(item.kind))
};
let impl_items1 = self.tcx.associated_item_def_ids(impl1);
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index afe6587..c0739db 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -598,6 +598,10 @@
}
})
.collect();
+ let recovered = match def {
+ hir::VariantData::Struct(_, _, r) => *r,
+ _ => false,
+ };
ty::VariantDef::new(tcx,
did,
ident,
@@ -605,7 +609,8 @@
fields,
adt_kind,
CtorKind::from_hir(def),
- attribute_def_id
+ attribute_def_id,
+ recovered,
)
}
@@ -2326,7 +2331,7 @@
if !item.check_name("enable") {
let msg = "#[target_feature(..)] only accepts sub-keys of `enable` \
currently";
- tcx.sess.span_err(item.span, &msg);
+ tcx.sess.span_err(item.span(), &msg);
continue;
}
@@ -2336,7 +2341,7 @@
None => {
let msg = "#[target_feature] attribute must be of the form \
#[target_feature(enable = \"..\")]";
- tcx.sess.span_err(item.span, &msg);
+ tcx.sess.span_err(item.span(), &msg);
continue;
}
};
@@ -2352,7 +2357,7 @@
this target",
feature
);
- let mut err = tcx.sess.struct_span_err(item.span, &msg);
+ let mut err = tcx.sess.struct_span_err(item.span(), &msg);
if feature.starts_with("+") {
let valid = whitelist.contains_key(&feature[1..]);
@@ -2387,7 +2392,7 @@
feature_gate::emit_feature_err(
&tcx.sess.parse_sess,
feature_gate.as_ref().unwrap(),
- item.span,
+ item.span(),
feature_gate::GateIssue::Language,
&format!("the target feature `{}` is currently unstable", feature),
);
@@ -2549,7 +2554,7 @@
} else {
span_err!(
tcx.sess.diagnostic(),
- items[0].span,
+ items[0].span(),
E0535,
"invalid argument"
);
@@ -2583,7 +2588,7 @@
} else if list_contains_name(&items[..], "speed") {
OptimizeAttr::Speed
} else {
- err(items[0].span, "invalid argument");
+ err(items[0].span(), "invalid argument");
OptimizeAttr::None
}
}
diff --git a/src/librustc_typeck/constrained_type_params.rs b/src/librustc_typeck/constrained_type_params.rs
index 4b922c3..c8687f5 100644
--- a/src/librustc_typeck/constrained_type_params.rs
+++ b/src/librustc_typeck/constrained_type_params.rs
@@ -78,12 +78,9 @@
false
}
- fn visit_const(&mut self, c: &'tcx ty::LazyConst<'tcx>) -> bool {
- if let ty::LazyConst::Evaluated(ty::Const {
- val: ConstValue::Param(data),
- ..
- }) = c {
- self.parameters.push(Parameter::from(*data));
+ fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> bool {
+ if let ConstValue::Param(data) = c.val {
+ self.parameters.push(Parameter::from(data));
}
false
}
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs
index 399cd6f..cde37fb 100644
--- a/src/librustc_typeck/diagnostics.rs
+++ b/src/librustc_typeck/diagnostics.rs
@@ -1290,45 +1290,34 @@
"##,
E0109: r##"
-You tried to give a type parameter to a type which doesn't need it. Erroneous
-code example:
+You tried to provide a generic argument to a type which doesn't need it.
+Erroneous code example:
```compile_fail,E0109
-type X = u32<i32>; // error: type arguments are not allowed on this entity
+type X = u32<i32>; // error: type arguments are not allowed for this type
+type Y = bool<'static>; // error: lifetime parameters are not allowed on
+ // this type
```
-Please check that you used the correct type and recheck its definition. Perhaps
-it doesn't need the type parameter.
+Check that you used the correct argument and that the definition is correct.
Example:
```
-type X = u32; // this compiles
+type X = u32; // ok!
+type Y = bool; // ok!
```
-Note that type parameters for enum-variant constructors go after the variant,
-not after the enum (`Option::None::<u32>`, not `Option::<u32>::None`).
+Note that generic arguments for enum variant constructors go after the variant,
+not after the enum. For example, you would write `Option::None::<u32>`,
+rather than `Option::<u32>::None`.
"##,
E0110: r##"
-You tried to give a lifetime parameter to a type which doesn't need it.
-Erroneous code example:
+#### Note: this error code is no longer emitted by the compiler.
-```compile_fail,E0110
-type X = u32<'static>; // error: lifetime parameters are not allowed on
- // this type
-```
-
-Please check that the correct type was used and recheck its definition; perhaps
-it doesn't need the lifetime parameter. Example:
-
-```
-type X = u32; // ok!
-```
-"##,
-
-E0111: r##"
-You tried to give a const parameter to a type which doesn't need it.
+You tried to provide a lifetime to a type which doesn't need it.
+See `E0109` for more details.
"##,
E0116: r##"
diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs
index c18f9fd..20eae5d 100644
--- a/src/librustc_typeck/variance/constraints.rs
+++ b/src/librustc_typeck/variance/constraints.rs
@@ -452,7 +452,7 @@
fn add_constraints_from_const(
&mut self,
current: &CurrentItem,
- ct: &ty::LazyConst<'tcx>,
+ ct: &ty::Const<'tcx>,
variance: VarianceTermPtr<'a>
) {
debug!(
@@ -461,11 +461,9 @@
variance
);
- if let ty::LazyConst::Evaluated(ct) = ct {
- self.add_constraints_from_ty(current, ct.ty, variance);
- if let ConstValue::Param(ref data) = ct.val {
- self.add_constraint(current, data.index, variance);
- }
+ self.add_constraints_from_ty(current, ct.ty, variance);
+ if let ConstValue::Param(ref data) = ct.val {
+ self.add_constraint(current, data.index, variance);
}
}
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index 20fa600..adbe73b 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -435,7 +435,7 @@
let new_ty = match &poly_trait.trait_ {
&Type::ResolvedPath {
ref path,
- ref typarams,
+ ref param_names,
ref did,
ref is_generic,
} => {
@@ -444,7 +444,13 @@
.expect("segments were empty");
let (old_input, old_output) = match last_segment.args {
- GenericArgs::AngleBracketed { types, .. } => (types, None),
+ GenericArgs::AngleBracketed { args, .. } => {
+ let types = args.iter().filter_map(|arg| match arg {
+ GenericArg::Type(ty) => Some(ty.clone()),
+ _ => None,
+ }).collect();
+ (types, None)
+ }
GenericArgs::Parenthesized { inputs, output, .. } => {
(inputs, output)
}
@@ -469,7 +475,7 @@
Type::ResolvedPath {
path: new_path,
- typarams: typarams.clone(),
+ param_names: param_names.clone(),
did: did.clone(),
is_generic: *is_generic,
}
@@ -669,7 +675,7 @@
match **trait_ {
Type::ResolvedPath {
path: ref trait_path,
- ref typarams,
+ ref param_names,
ref did,
ref is_generic,
} => {
@@ -724,7 +730,7 @@
PolyTrait {
trait_: Type::ResolvedPath {
path: new_trait_path,
- typarams: typarams.clone(),
+ param_names: param_names.clone(),
did: did.clone(),
is_generic: *is_generic,
},
diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs
index 45e1ea2..6944545 100644
--- a/src/librustdoc/clean/cfg.rs
+++ b/src/librustdoc/clean/cfg.rs
@@ -8,7 +8,7 @@
use std::ops;
use syntax::symbol::Symbol;
-use syntax::ast::{MetaItem, MetaItemKind, NestedMetaItem, NestedMetaItemKind, LitKind};
+use syntax::ast::{MetaItem, MetaItemKind, NestedMetaItem, LitKind};
use syntax::parse::ParseSess;
use syntax::feature_gate::Features;
@@ -41,9 +41,9 @@
impl Cfg {
/// Parses a `NestedMetaItem` into a `Cfg`.
fn parse_nested(nested_cfg: &NestedMetaItem) -> Result<Cfg, InvalidCfgError> {
- match nested_cfg.node {
- NestedMetaItemKind::MetaItem(ref cfg) => Cfg::parse(cfg),
- NestedMetaItemKind::Literal(ref lit) => Err(InvalidCfgError {
+ match nested_cfg {
+ NestedMetaItem::MetaItem(ref cfg) => Cfg::parse(cfg),
+ NestedMetaItem::Literal(ref lit) => Err(InvalidCfgError {
msg: "unexpected literal",
span: lit.span,
}),
@@ -58,7 +58,13 @@
/// If the content is not properly formatted, it will return an error indicating what and where
/// the error is.
pub fn parse(cfg: &MetaItem) -> Result<Cfg, InvalidCfgError> {
- let name = cfg.name();
+ let name = match cfg.ident() {
+ Some(ident) => ident.name,
+ None => return Err(InvalidCfgError {
+ msg: "expected a single identifier",
+ span: cfg.span
+ }),
+ };
match cfg.node {
MetaItemKind::Word => Ok(Cfg::Cfg(name, None)),
MetaItemKind::NameValue(ref lit) => match lit.node {
@@ -424,7 +430,7 @@
fn dummy_meta_item_word(name: &str) -> MetaItem {
MetaItem {
- ident: Path::from_ident(Ident::from_str(name)),
+ path: Path::from_ident(Ident::from_str(name)),
node: MetaItemKind::Word,
span: DUMMY_SP,
}
@@ -433,12 +439,12 @@
macro_rules! dummy_meta_item_list {
($name:ident, [$($list:ident),* $(,)?]) => {
MetaItem {
- ident: Path::from_ident(Ident::from_str(stringify!($name))),
+ path: Path::from_ident(Ident::from_str(stringify!($name))),
node: MetaItemKind::List(vec![
$(
- dummy_spanned(NestedMetaItemKind::MetaItem(
+ NestedMetaItem::MetaItem(
dummy_meta_item_word(stringify!($list)),
- )),
+ ),
)*
]),
span: DUMMY_SP,
@@ -447,10 +453,10 @@
($name:ident, [$($list:expr),* $(,)?]) => {
MetaItem {
- ident: Path::from_ident(Ident::from_str(stringify!($name))),
+ path: Path::from_ident(Ident::from_str(stringify!($name))),
node: MetaItemKind::List(vec![
$(
- dummy_spanned(NestedMetaItemKind::MetaItem($list)),
+ NestedMetaItem::MetaItem($list),
)*
]),
span: DUMMY_SP,
@@ -587,7 +593,7 @@
assert_eq!(Cfg::parse(&mi), Ok(word_cfg("all")));
let mi = MetaItem {
- ident: Path::from_ident(Ident::from_str("all")),
+ path: Path::from_ident(Ident::from_str("all")),
node: MetaItemKind::NameValue(dummy_spanned(LitKind::Str(
Symbol::intern("done"),
StrStyle::Cooked,
@@ -622,7 +628,7 @@
fn test_parse_err() {
with_globals(|| {
let mi = MetaItem {
- ident: Path::from_ident(Ident::from_str("foo")),
+ path: Path::from_ident(Ident::from_str("foo")),
node: MetaItemKind::NameValue(dummy_spanned(LitKind::Bool(false))),
span: DUMMY_SP,
};
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index c80fd8f..ba44817 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -16,12 +16,12 @@
use rustc::middle::resolve_lifetime as rl;
use rustc::middle::lang_items;
use rustc::middle::stability;
-use rustc::mir::interpret::GlobalId;
-use rustc::hir::{self, GenericArg, HirVec};
+use rustc::mir::interpret::{GlobalId, ConstValue};
+use rustc::hir::{self, HirVec};
use rustc::hir::def::{self, Def, CtorKind};
use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc::hir::map::DisambiguatedDefPathData;
-use rustc::ty::subst::{Kind, InternalSubsts, SubstsRef};
+use rustc::ty::subst::{Kind, InternalSubsts, SubstsRef, UnpackedKind};
use rustc::ty::{self, DefIdTree, TyCtxt, Region, RegionVid, Ty, AdtKind};
use rustc::ty::fold::TypeFolder;
use rustc::ty::layout::VariantIdx;
@@ -492,7 +492,7 @@
pub fn is_non_exhaustive(&self) -> bool {
self.attrs.other_attrs.iter()
- .any(|a| a.name().as_str() == "non_exhaustive")
+ .any(|a| a.check_name("non_exhaustive"))
}
/// Returns a documentation-level item type from the item.
@@ -508,6 +508,18 @@
.as_ref()
.or_else(|| self.stability.as_ref().and_then(|s| s.deprecation.as_ref()))
}
+ pub fn is_default(&self) -> bool {
+ match self.inner {
+ ItemEnum::MethodItem(ref meth) => {
+ if let Some(defaultness) = meth.defaultness {
+ defaultness.has_value() && !defaultness.is_final()
+ } else {
+ false
+ }
+ }
+ _ => false,
+ }
+ }
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
@@ -777,15 +789,15 @@
impl Attributes {
/// Extracts the content from an attribute `#[doc(cfg(content))]`.
fn extract_cfg(mi: &ast::MetaItem) -> Option<&ast::MetaItem> {
- use syntax::ast::NestedMetaItemKind::MetaItem;
+ use syntax::ast::NestedMetaItem::MetaItem;
if let ast::MetaItemKind::List(ref nmis) = mi.node {
if nmis.len() == 1 {
- if let MetaItem(ref cfg_mi) = nmis[0].node {
+ if let MetaItem(ref cfg_mi) = nmis[0] {
if cfg_mi.check_name("cfg") {
if let ast::MetaItemKind::List(ref cfg_nmis) = cfg_mi.node {
if cfg_nmis.len() == 1 {
- if let MetaItem(ref content_mi) = cfg_nmis[0].node {
+ if let MetaItem(ref content_mi) = cfg_nmis[0] {
return Some(content_mi);
}
}
@@ -1045,7 +1057,7 @@
GenericBound::TraitBound(PolyTrait {
trait_: ResolvedPath {
path,
- typarams: None,
+ param_names: None,
did,
is_generic: false,
},
@@ -1089,24 +1101,37 @@
}
}
-fn external_generic_args(cx: &DocContext<'_>, trait_did: Option<DefId>, has_self: bool,
- bindings: Vec<TypeBinding>, substs: SubstsRef<'_>) -> GenericArgs {
- let lifetimes = substs.regions().filter_map(|v| v.clean(cx)).collect();
- let types = substs.types().skip(has_self as usize).collect::<Vec<_>>();
+fn external_generic_args(
+ cx: &DocContext<'_>,
+ trait_did: Option<DefId>,
+ has_self: bool,
+ bindings: Vec<TypeBinding>,
+ substs: SubstsRef<'_>,
+) -> GenericArgs {
+ let mut skip_self = has_self;
+ let mut ty_sty = None;
+ let args: Vec<_> = substs.iter().filter_map(|kind| match kind.unpack() {
+ UnpackedKind::Lifetime(lt) => {
+ lt.clean(cx).and_then(|lt| Some(GenericArg::Lifetime(lt)))
+ }
+ UnpackedKind::Type(_) if skip_self => {
+ skip_self = false;
+ None
+ }
+ UnpackedKind::Type(ty) => {
+ ty_sty = Some(&ty.sty);
+ Some(GenericArg::Type(ty.clean(cx)))
+ }
+ UnpackedKind::Const(ct) => Some(GenericArg::Const(ct.clean(cx))),
+ }).collect();
match trait_did {
// Attempt to sugar an external path like Fn<(A, B,), C> to Fn(A, B) -> C
Some(did) if cx.tcx.lang_items().fn_trait_kind(did).is_some() => {
- assert_eq!(types.len(), 1);
- let inputs = match types[0].sty {
- ty::Tuple(ref tys) => tys.iter().map(|t| t.clean(cx)).collect(),
- _ => {
- return GenericArgs::AngleBracketed {
- lifetimes,
- types: types.clean(cx),
- bindings,
- }
- }
+ assert!(ty_sty.is_some());
+ let inputs = match ty_sty {
+ Some(ty::Tuple(ref tys)) => tys.iter().map(|t| t.clean(cx)).collect(),
+ _ => return GenericArgs::AngleBracketed { args, bindings },
};
let output = None;
// FIXME(#20299) return type comes from a projection now
@@ -1114,17 +1139,10 @@
// ty::Tuple(ref v) if v.is_empty() => None, // -> ()
// _ => Some(types[1].clean(cx))
// };
- GenericArgs::Parenthesized {
- inputs,
- output,
- }
+ GenericArgs::Parenthesized { inputs, output }
},
_ => {
- GenericArgs::AngleBracketed {
- lifetimes,
- types: types.clean(cx),
- bindings,
- }
+ GenericArgs::AngleBracketed { args, bindings }
}
}
}
@@ -1176,7 +1194,7 @@
PolyTrait {
trait_: ResolvedPath {
path,
- typarams: None,
+ param_names: None,
did: trait_ref.def_id,
is_generic: false,
},
@@ -1462,14 +1480,14 @@
}
}
-impl<'tcx> Clean<GenericParamDef> for ty::GenericParamDef {
+impl Clean<GenericParamDef> for ty::GenericParamDef {
fn clean(&self, cx: &DocContext<'_>) -> GenericParamDef {
let (name, kind) = match self.kind {
ty::GenericParamDefKind::Lifetime => {
(self.name.to_string(), GenericParamDefKind::Lifetime)
}
ty::GenericParamDefKind::Type { has_default, .. } => {
- cx.renderinfo.borrow_mut().external_typarams
+ cx.renderinfo.borrow_mut().external_param_names
.insert(self.def_id, self.name.clean(cx));
let default = if has_default {
Some(cx.tcx.type_of(self.def_id).clean(cx))
@@ -1484,7 +1502,10 @@
})
}
ty::GenericParamDefKind::Const { .. } => {
- unimplemented!() // FIXME(const_generics)
+ (self.name.clean(cx), GenericParamDefKind::Const {
+ did: self.def_id,
+ ty: cx.tcx.type_of(self.def_id).clean(cx),
+ })
}
};
@@ -1685,9 +1706,7 @@
.flat_map(|param| match param.kind {
ty::GenericParamDefKind::Lifetime => Some(param.clean(cx)),
ty::GenericParamDefKind::Type { .. } => None,
- ty::GenericParamDefKind::Const { .. } => {
- unimplemented!() // FIXME(const_generics)
- }
+ ty::GenericParamDefKind::Const { .. } => Some(param.clean(cx)),
}).chain(simplify::ty_params(stripped_typarams).into_iter())
.collect(),
where_predicates: simplify::where_clauses(cx, where_predicates),
@@ -1700,9 +1719,11 @@
pub generics: Generics,
pub decl: FnDecl,
pub header: hir::FnHeader,
+ pub defaultness: Option<hir::Defaultness>,
}
-impl<'a> Clean<Method> for (&'a hir::MethodSig, &'a hir::Generics, hir::BodyId) {
+impl<'a> Clean<Method> for (&'a hir::MethodSig, &'a hir::Generics, hir::BodyId,
+ Option<hir::Defaultness>) {
fn clean(&self, cx: &DocContext<'_>) -> Method {
let (generics, decl) = enter_impl_trait(cx, || {
(self.1.clean(cx), (&*self.0.decl, self.2).clean(cx))
@@ -1711,6 +1732,7 @@
decl,
generics,
header: self.0.header,
+ defaultness: self.3,
}
}
}
@@ -2016,7 +2038,7 @@
default.map(|e| print_const_expr(cx, e)))
}
hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) => {
- MethodItem((sig, &self.generics, body).clean(cx))
+ MethodItem((sig, &self.generics, body, None).clean(cx))
}
hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Required(ref names)) => {
let (generics, decl) = enter_impl_trait(cx, || {
@@ -2054,7 +2076,7 @@
Some(print_const_expr(cx, expr)))
}
hir::ImplItemKind::Method(ref sig, body) => {
- MethodItem((sig, &self.generics, body).clean(cx))
+ MethodItem((sig, &self.generics, body, Some(self.defaultness)).clean(cx))
}
hir::ImplItemKind::Type(ref ty) => TypedefItem(Typedef {
type_: ty.clean(cx),
@@ -2137,7 +2159,8 @@
abi: sig.abi(),
constness,
asyncness: hir::IsAsync::NotAsync,
- }
+ },
+ defaultness: Some(self.defaultness),
})
} else {
TyMethodItem(TyMethod {
@@ -2244,7 +2267,7 @@
/// Structs/enums/traits (most that'd be an `hir::TyKind::Path`).
ResolvedPath {
path: Path,
- typarams: Option<Vec<GenericBound>>,
+ param_names: Option<Vec<GenericBound>>,
did: DefId,
/// `true` if is a `T::Name` path for associated types.
is_generic: bool,
@@ -2365,12 +2388,15 @@
}
}
- pub fn generics(&self) -> Option<&[Type]> {
+ pub fn generics(&self) -> Option<Vec<Type>> {
match *self {
ResolvedPath { ref path, .. } => {
path.segments.last().and_then(|seg| {
- if let GenericArgs::AngleBracketed { ref types, .. } = seg.args {
- Some(&**types)
+ if let GenericArgs::AngleBracketed { ref args, .. } = seg.args {
+ Some(args.iter().filter_map(|arg| match arg {
+ GenericArg::Type(ty) => Some(ty.clone()),
+ _ => None,
+ }).collect())
} else {
None
}
@@ -2551,7 +2577,7 @@
promoted: None
};
let length = match cx.tcx.const_eval(param_env.and(cid)) {
- Ok(length) => print_const(cx, ty::LazyConst::Evaluated(length)),
+ Ok(length) => print_const(cx, length),
Err(_) => "_".to_string(),
};
Array(box ty.clean(cx), length)
@@ -2706,7 +2732,7 @@
}
TyKind::TraitObject(ref bounds, ref lifetime) => {
match bounds[0].clean(cx).trait_ {
- ResolvedPath { path, typarams: None, did, is_generic } => {
+ ResolvedPath { path, param_names: None, did, is_generic } => {
let mut bounds: Vec<self::GenericBound> = bounds[1..].iter().map(|bound| {
self::GenericBound::TraitBound(bound.clean(cx),
hir::TraitBoundModifier::None)
@@ -2714,7 +2740,7 @@
if !lifetime.is_elided() {
bounds.push(self::GenericBound::Outlives(lifetime.clean(cx)));
}
- ResolvedPath { path, typarams: Some(bounds), did, is_generic, }
+ ResolvedPath { path, param_names: Some(bounds), did, is_generic, }
}
_ => Infer // shouldn't happen
}
@@ -2739,14 +2765,14 @@
ty::Slice(ty) => Slice(box ty.clean(cx)),
ty::Array(ty, n) => {
let mut n = *cx.tcx.lift(&n).expect("array lift failed");
- if let ty::LazyConst::Unevaluated(def_id, substs) = n {
+ if let ConstValue::Unevaluated(def_id, substs) = n.val {
let param_env = cx.tcx.param_env(def_id);
let cid = GlobalId {
instance: ty::Instance::new(def_id, substs),
promoted: None
};
if let Ok(new_n) = cx.tcx.const_eval(param_env.and(cid)) {
- n = ty::LazyConst::Evaluated(new_n);
+ n = new_n;
}
};
let n = print_const(cx, n);
@@ -2781,7 +2807,7 @@
None, false, vec![], substs);
ResolvedPath {
path,
- typarams: None,
+ param_names: None,
did,
is_generic: false,
}
@@ -2792,7 +2818,7 @@
None, false, vec![], InternalSubsts::empty());
ResolvedPath {
path: path,
- typarams: None,
+ param_names: None,
did: did,
is_generic: false,
}
@@ -2813,8 +2839,8 @@
inline::record_extern_fqn(cx, did, TypeKind::Trait);
- let mut typarams = vec![];
- reg.clean(cx).map(|b| typarams.push(GenericBound::Outlives(b)));
+ let mut param_names = vec![];
+ reg.clean(cx).map(|b| param_names.push(GenericBound::Outlives(b)));
for did in dids {
let empty = cx.tcx.intern_substs(&[]);
let path = external_path(cx, &cx.tcx.item_name(did).as_str(),
@@ -2823,13 +2849,13 @@
let bound = GenericBound::TraitBound(PolyTrait {
trait_: ResolvedPath {
path,
- typarams: None,
+ param_names: None,
did,
is_generic: false,
},
generic_params: Vec::new(),
}, hir::TraitBoundModifier::None);
- typarams.push(bound);
+ param_names.push(bound);
}
let mut bindings = vec![];
@@ -2844,7 +2870,7 @@
false, bindings, substs);
ResolvedPath {
path,
- typarams: Some(typarams),
+ param_names: Some(param_names),
did,
is_generic: false,
}
@@ -2921,6 +2947,15 @@
}
}
+impl<'tcx> Clean<Constant> for ty::Const<'tcx> {
+ fn clean(&self, cx: &DocContext<'_>) -> Constant {
+ Constant {
+ type_: self.ty.clean(cx),
+ expr: format!("{:?}", self.val), // FIXME(const_generics)
+ }
+ }
+}
+
impl Clean<Item> for hir::StructField {
fn clean(&self, cx: &DocContext<'_>) -> Item {
let local_did = cx.tcx.hir().local_def_id_from_hir_id(self.hir_id);
@@ -3229,10 +3264,26 @@
}
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+pub enum GenericArg {
+ Lifetime(Lifetime),
+ Type(Type),
+ Const(Constant),
+}
+
+impl fmt::Display for GenericArg {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self {
+ GenericArg::Lifetime(lt) => lt.fmt(f),
+ GenericArg::Type(ty) => ty.fmt(f),
+ GenericArg::Const(ct) => ct.fmt(f),
+ }
+ }
+}
+
+#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
pub enum GenericArgs {
AngleBracketed {
- lifetimes: Vec<Lifetime>,
- types: Vec<Type>,
+ args: Vec<GenericArg>,
bindings: Vec<TypeBinding>,
},
Parenthesized {
@@ -3250,27 +3301,19 @@
output: if output != Type::Tuple(Vec::new()) { Some(output) } else { None }
}
} else {
- let (mut lifetimes, mut types) = (vec![], vec![]);
- let mut elided_lifetimes = true;
- for arg in &self.args {
- match arg {
- GenericArg::Lifetime(lt) => {
- if !lt.is_elided() {
- elided_lifetimes = false;
- }
- lifetimes.push(lt.clean(cx));
- }
- GenericArg::Type(ty) => {
- types.push(ty.clean(cx));
- }
- GenericArg::Const(..) => {
- unimplemented!() // FIXME(const_generics)
- }
- }
- }
+ let elide_lifetimes = self.args.iter().all(|arg| match arg {
+ hir::GenericArg::Lifetime(lt) => lt.is_elided(),
+ _ => true,
+ });
GenericArgs::AngleBracketed {
- lifetimes: if elided_lifetimes { vec![] } else { lifetimes },
- types,
+ args: self.args.iter().filter_map(|arg| match arg {
+ hir::GenericArg::Lifetime(lt) if !elide_lifetimes => {
+ Some(GenericArg::Lifetime(lt.clean(cx)))
+ }
+ hir::GenericArg::Lifetime(_) => None,
+ hir::GenericArg::Type(ty) => Some(GenericArg::Type(ty.clean(cx))),
+ hir::GenericArg::Const(ct) => Some(GenericArg::Const(ct.clean(cx))),
+ }).collect(),
bindings: self.bindings.clean(cx),
}
}
@@ -3294,8 +3337,8 @@
fn strip_type(ty: Type) -> Type {
match ty {
- Type::ResolvedPath { path, typarams, did, is_generic } => {
- Type::ResolvedPath { path: strip_path(&path), typarams, did, is_generic }
+ Type::ResolvedPath { path, param_names, did, is_generic } => {
+ Type::ResolvedPath { path: strip_path(&path), param_names, did, is_generic }
}
Type::Tuple(inner_tys) => {
Type::Tuple(inner_tys.iter().map(|t| strip_type(t.clone())).collect())
@@ -3322,9 +3365,8 @@
PathSegment {
name: s.name.clone(),
args: GenericArgs::AngleBracketed {
- lifetimes: Vec::new(),
- types: Vec::new(),
- bindings: Vec::new(),
+ args: vec![],
+ bindings: vec![],
}
}
}).collect();
@@ -3475,7 +3517,7 @@
}
}
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
pub struct Constant {
pub type_: Type,
pub expr: String,
@@ -3683,7 +3725,7 @@
fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> {
let please_inline = self.vis.node.is_pub() && self.attrs.iter().any(|a| {
- a.name() == "doc" && match a.meta_item_list() {
+ a.check_name("doc") && match a.meta_item_list() {
Some(l) => attr::list_contains_name(&l, "inline"),
None => false,
}
@@ -3722,7 +3764,7 @@
// #[doc(no_inline)] attribute is present.
// Don't inline doc(hidden) imports so they can be stripped at a later stage.
let mut denied = !self.vis.node.is_pub() || self.attrs.iter().any(|a| {
- a.name() == "doc" && match a.meta_item_list() {
+ a.check_name("doc") && match a.meta_item_list() {
Some(l) => attr::list_contains_name(&l, "no_inline") ||
attr::list_contains_name(&l, "hidden"),
None => false,
@@ -3900,16 +3942,16 @@
}
}
-fn print_const(cx: &DocContext<'_>, n: ty::LazyConst<'_>) -> String {
- match n {
- ty::LazyConst::Unevaluated(def_id, _) => {
+fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String {
+ match n.val {
+ ConstValue::Unevaluated(def_id, _) => {
if let Some(hir_id) = cx.tcx.hir().as_local_hir_id(def_id) {
print_const_expr(cx, cx.tcx.hir().body_owned_by(hir_id))
} else {
inline::print_inlined_const(cx, def_id)
}
},
- ty::LazyConst::Evaluated(n) => {
+ _ => {
let mut s = String::new();
::rustc::mir::fmt_const_val(&mut s, n).expect("fmt_const_val failed");
// array lengths are obviously usize
@@ -3955,7 +3997,7 @@
_ => false,
};
let did = register_def(&*cx, path.def);
- ResolvedPath { path: path, typarams: None, did: did, is_generic: is_generic }
+ ResolvedPath { path: path, param_names: None, did: did, is_generic: is_generic }
}
pub fn register_def(cx: &DocContext<'_>, def: Def) -> DefId {
@@ -4381,9 +4423,9 @@
match bound.clone() {
GenericBound::Outlives(l) => SimpleBound::Outlives(l),
GenericBound::TraitBound(t, mod_) => match t.trait_ {
- Type::ResolvedPath { path, typarams, .. } => {
+ Type::ResolvedPath { path, param_names, .. } => {
SimpleBound::TraitBound(path.segments,
- typarams
+ param_names
.map_or_else(|| Vec::new(), |v| v.iter()
.map(|p| SimpleBound::from(p.clone()))
.collect()),
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 47dbbc2..1982a16 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -236,8 +236,16 @@
ty::GenericParamDefKind::Type { .. } => {
args.push(hir::GenericArg::Type(self.ty_param_to_ty(param.clone())));
}
- ty::GenericParamDefKind::Const { .. } => {
- unimplemented!() // FIXME(const_generics)
+ ty::GenericParamDefKind::Const => {
+ args.push(hir::GenericArg::Const(hir::ConstArg {
+ value: hir::AnonConst {
+ hir_id: hir::DUMMY_HIR_ID,
+ body: hir::BodyId {
+ hir_id: hir::DUMMY_HIR_ID,
+ }
+ },
+ span: DUMMY_SP,
+ }))
}
}
}
@@ -521,8 +529,7 @@
for attr in krate.module.as_ref().unwrap().attrs.lists("doc") {
let diag = ctxt.sess().diagnostic();
- let name = attr.name().map(|s| s.as_str());
- let name = name.as_ref().map(|s| &s[..]);
+ let name = attr.ident_str();
if attr.is_word() {
if name == Some("no_default_passes") {
report_deprecated_attr("no_default_passes", diag);
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index d204a17..3d8af7c 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -45,6 +45,7 @@
/// Wrapper struct for emitting a comma-separated list of items
pub struct CommaSep<'a, T>(pub &'a [T]);
pub struct AbiSpace(pub Abi);
+pub struct DefaultSpace(pub bool);
/// Wrapper struct for properly emitting a function or method declaration.
pub struct Function<'a> {
@@ -259,6 +260,14 @@
}
}
+impl fmt::Display for clean::Constant {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt::Display::fmt(&self.expr, f)?;
+ f.write_str(": ")?;
+ fmt::Display::fmt(&self.type_, f)
+ }
+}
+
impl fmt::Display for clean::PolyTrait {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if !self.generic_params.is_empty() {
@@ -300,32 +309,23 @@
impl fmt::Display for clean::GenericArgs {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
- clean::GenericArgs::AngleBracketed {
- ref lifetimes, ref types, ref bindings
- } => {
- if !lifetimes.is_empty() || !types.is_empty() || !bindings.is_empty() {
+ clean::GenericArgs::AngleBracketed { ref args, ref bindings } => {
+ if !args.is_empty() || !bindings.is_empty() {
if f.alternate() {
f.write_str("<")?;
} else {
f.write_str("<")?;
}
let mut comma = false;
- for lifetime in lifetimes {
- if comma {
- f.write_str(", ")?;
- }
- comma = true;
- write!(f, "{}", *lifetime)?;
- }
- for ty in types {
+ for arg in args {
if comma {
f.write_str(", ")?;
}
comma = true;
if f.alternate() {
- write!(f, "{:#}", *ty)?;
+ write!(f, "{:#}", *arg)?;
} else {
- write!(f, "{}", *ty)?;
+ write!(f, "{}", *arg)?;
}
}
for binding in bindings {
@@ -521,8 +521,8 @@
/// Helper to render type parameters
fn tybounds(w: &mut fmt::Formatter<'_>,
- typarams: &Option<Vec<clean::GenericBound>>) -> fmt::Result {
- match *typarams {
+ param_names: &Option<Vec<clean::GenericBound>>) -> fmt::Result {
+ match *param_names {
Some(ref params) => {
for param in params {
write!(w, " + ")?;
@@ -559,13 +559,13 @@
clean::Generic(ref name) => {
f.write_str(name)
}
- clean::ResolvedPath{ did, ref typarams, ref path, is_generic } => {
- if typarams.is_some() {
+ clean::ResolvedPath{ did, ref param_names, ref path, is_generic } => {
+ if param_names.is_some() {
f.write_str("dyn ")?;
}
// Paths like T::Output and Self::Output should be rendered with all segments
resolved_path(f, did, path, is_generic, use_absolute)?;
- tybounds(f, typarams)
+ tybounds(f, param_names)
}
clean::Infer => write!(f, "_"),
clean::Primitive(prim) => primitive_link(f, prim, prim.as_str()),
@@ -663,7 +663,7 @@
}
}
}
- clean::ResolvedPath { typarams: Some(ref v), .. } if !v.is_empty() => {
+ clean::ResolvedPath { param_names: Some(ref v), .. } if !v.is_empty() => {
write!(f, "{}{}{}(", amp, lt, m)?;
fmt_type(&ty, f, use_absolute)?;
write!(f, ")")
@@ -717,7 +717,7 @@
// the ugliness comes from inlining across crates where
// everything comes in as a fully resolved QPath (hard to
// look at).
- box clean::ResolvedPath { did, ref typarams, .. } => {
+ box clean::ResolvedPath { did, ref param_names, .. } => {
match href(did) {
Some((ref url, _, ref path)) if !f.alternate() => {
write!(f,
@@ -731,8 +731,8 @@
_ => write!(f, "{}", name)?,
}
- // FIXME: `typarams` are not rendered, and this seems bad?
- drop(typarams);
+ // FIXME: `param_names` are not rendered, and this seems bad?
+ drop(param_names);
Ok(())
}
_ => {
@@ -771,7 +771,7 @@
fmt::Display::fmt(ty, f)?;
} else {
match *ty {
- clean::ResolvedPath { typarams: None, ref path, is_generic: false, .. } => {
+ clean::ResolvedPath { param_names: None, ref path, is_generic: false, .. } => {
let last = path.segments.last().unwrap();
fmt::Display::fmt(&last.name, f)?;
fmt::Display::fmt(&last.args, f)?;
@@ -1057,3 +1057,13 @@
}
}
}
+
+impl fmt::Display for DefaultSpace {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ if self.0 {
+ write!(f, "default ")
+ } else {
+ Ok(())
+ }
+ }
+}
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index d711e45..445ce06 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -61,7 +61,7 @@
use crate::fold::DocFolder;
use crate::html::escape::Escape;
use crate::html::format::{AsyncSpace, ConstnessSpace};
-use crate::html::format::{GenericBounds, WhereClause, href, AbiSpace};
+use crate::html::format::{GenericBounds, WhereClause, href, AbiSpace, DefaultSpace};
use crate::html::format::{VisSpace, Function, UnsafetySpace, MutableSpace};
use crate::html::format::fmt_impl_for_trait_page;
use crate::html::item_type::ItemType;
@@ -271,7 +271,7 @@
/// Mapping of typaram ids to the name of the type parameter. This is used
/// when pretty-printing a type (so pretty-printing doesn't have to
/// painfully maintain a context like this)
- pub typarams: FxHashMap<DefId, String>,
+ pub param_names: FxHashMap<DefId, String>,
/// Maps a type ID to all known implementations for that type. This is only
/// recognized for intra-crate `ResolvedPath` types, and is used to print
@@ -368,7 +368,7 @@
pub struct RenderInfo {
pub inlined: FxHashSet<DefId>,
pub external_paths: crate::core::ExternalPaths,
- pub external_typarams: FxHashMap<DefId, String>,
+ pub external_param_names: FxHashMap<DefId, String>,
pub exact_paths: FxHashMap<DefId, Vec<String>>,
pub access_levels: AccessLevels<DefId>,
pub deref_trait_did: Option<DefId>,
@@ -562,8 +562,7 @@
// going to emit HTML
if let Some(attrs) = krate.module.as_ref().map(|m| &m.attrs) {
for attr in attrs.lists("doc") {
- let name = attr.name().map(|s| s.as_str());
- match (name.as_ref().map(|s| &s[..]), attr.value_str()) {
+ match (attr.ident_str(), attr.value_str()) {
(Some("html_favicon_url"), Some(s)) => {
scx.layout.favicon = s.to_string();
}
@@ -602,7 +601,7 @@
let RenderInfo {
inlined: _,
external_paths,
- external_typarams,
+ external_param_names,
exact_paths,
access_levels,
deref_trait_did,
@@ -636,7 +635,7 @@
deref_mut_trait_did,
owned_box_did,
masked_crates: mem::replace(&mut krate.masked_crates, Default::default()),
- typarams: external_typarams,
+ param_names: external_param_names,
aliases: Default::default(),
};
@@ -1117,11 +1116,7 @@
// with rustdoc running in parallel.
all_indexes.sort();
let mut w = try_err!(File::create(&dst), &dst);
- if options.enable_minification {
- try_err!(writeln!(&mut w, "var N=null,E=\"\",T=\"t\",U=\"u\",searchIndex={{}};"), &dst);
- } else {
- try_err!(writeln!(&mut w, "var searchIndex={{}};"), &dst);
- }
+ try_err!(writeln!(&mut w, "var N=null,E=\"\",T=\"t\",U=\"u\",searchIndex={{}};"), &dst);
try_err!(write_minify_replacer(&mut w,
&format!("{}\n{}", variables.join(""), all_indexes.join("\n")),
options.enable_minification),
@@ -1756,7 +1751,7 @@
clean::GenericParamDefKind::Lifetime => {}
clean::GenericParamDefKind::Type { did, .. } |
clean::GenericParamDefKind::Const { did, .. } => {
- self.typarams.insert(did, param.name.clone());
+ self.param_names.insert(did, param.name.clone());
}
}
}
@@ -3434,11 +3429,12 @@
}
};
let mut header_len = format!(
- "{}{}{}{}{:#}fn {}{:#}",
+ "{}{}{}{}{}{:#}fn {}{:#}",
VisSpace(&meth.visibility),
ConstnessSpace(header.constness),
UnsafetySpace(header.unsafety),
AsyncSpace(header.asyncness),
+ DefaultSpace(meth.is_default()),
AbiSpace(header.abi),
name,
*g
@@ -3450,12 +3446,13 @@
(0, true)
};
render_attributes(w, meth)?;
- write!(w, "{}{}{}{}{}fn <a href='{href}' class='fnname'>{name}</a>\
+ write!(w, "{}{}{}{}{}{}fn <a href='{href}' class='fnname'>{name}</a>\
{generics}{decl}{where_clause}",
VisSpace(&meth.visibility),
ConstnessSpace(header.constness),
UnsafetySpace(header.unsafety),
AsyncSpace(header.asyncness),
+ DefaultSpace(meth.is_default()),
AbiSpace(header.abi),
href = href,
name = name,
@@ -3718,19 +3715,19 @@
}
fn render_attribute(attr: &ast::MetaItem) -> Option<String> {
- let name = attr.name();
+ let path = attr.path.to_string();
if attr.is_word() {
- Some(name.to_string())
+ Some(path)
} else if let Some(v) = attr.value_str() {
- Some(format!("{} = {:?}", name, v.as_str()))
+ Some(format!("{} = {:?}", path, v.as_str()))
} else if let Some(values) = attr.meta_item_list() {
let display: Vec<_> = values.iter().filter_map(|attr| {
attr.meta_item().and_then(|mi| render_attribute(mi))
}).collect();
if display.len() > 0 {
- Some(format!("{}({})", name, display.join(", ")))
+ Some(format!("{}({})", path, display.join(", ")))
} else {
None
}
@@ -3754,8 +3751,7 @@
let mut attrs = String::new();
for attr in &it.attrs.other_attrs {
- let name = attr.name();
- if !ATTRIBUTE_WHITELIST.contains(&&*name.as_str()) {
+ if !attr.ident_str().map_or(false, |name| ATTRIBUTE_WHITELIST.contains(&name)) {
continue;
}
if let Some(s) = render_attribute(&attr.meta().unwrap()) {
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 1849e53..fef6910 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -2077,16 +2077,22 @@
}
var toggle = createSimpleToggle(false);
+ var hideMethodDocs = getCurrentValue("rustdoc-method-docs") !== "false";
+ var pageId = getPageId();
var func = function(e) {
var next = e.nextElementSibling;
if (!next) {
return;
}
- if (hasClass(next, "docblock") ||
- (hasClass(next, "stability") &&
- hasClass(next.nextElementSibling, "docblock"))) {
- insertAfter(toggle.cloneNode(true), e.childNodes[e.childNodes.length - 1]);
+ if (hasClass(next, "docblock") === true ||
+ (hasClass(next, "stability") === true &&
+ hasClass(next.nextElementSibling, "docblock") === true)) {
+ var newToggle = toggle.cloneNode(true);
+ insertAfter(newToggle, e.childNodes[e.childNodes.length - 1]);
+ if (hideMethodDocs === true && hasClass(e, "method") === true) {
+ collapseDocs(newToggle, "hide", pageId);
+ }
}
};
@@ -2107,17 +2113,16 @@
onEachLazy(document.getElementsByClassName("associatedconstant"), func);
onEachLazy(document.getElementsByClassName("impl"), funcImpl);
var impl_call = function() {};
- if (getCurrentValue("rustdoc-method-docs") !== "false") {
+ if (hideMethodDocs === true) {
impl_call = function(e, newToggle, pageId) {
if (e.id.match(/^impl(?:-\d+)?$/) === null) {
// Automatically minimize all non-inherent impls
- if (hasClass(e, "impl")) {
+ if (hasClass(e, "impl") === true) {
collapseDocs(newToggle, "hide", pageId);
}
}
};
}
- var pageId = getPageId();
var newToggle = document.createElement("a");
newToggle.href = "javascript:void(0)";
newToggle.className = "collapse-toggle hidden-default collapsed";
@@ -2163,7 +2168,7 @@
var inner_toggle = newToggle.cloneNode(true);
inner_toggle.onclick = toggleClicked;
e.insertBefore(inner_toggle, e.firstChild);
- impl_call(e, inner_toggle, pageId);
+ impl_call(e.previousSibling, inner_toggle, pageId);
}
});
@@ -2265,30 +2270,6 @@
onEachLazy(document.getElementsByClassName("docblock"), buildToggleWrapper);
onEachLazy(document.getElementsByClassName("sub-variant"), buildToggleWrapper);
- // In the search display, allows to switch between tabs.
- function printTab(nb) {
- if (nb === 0 || nb === 1 || nb === 2) {
- currentTab = nb;
- }
- var nb_copy = nb;
- onEachLazy(document.getElementById("titles").childNodes, function(elem) {
- if (nb_copy === 0) {
- addClass(elem, "selected");
- } else {
- removeClass(elem, "selected");
- }
- nb_copy -= 1;
- });
- onEachLazy(document.getElementById("results").childNodes, function(elem) {
- if (nb === 0) {
- elem.style.display = "";
- } else {
- elem.style.display = "none";
- }
- nb -= 1;
- });
- }
-
function createToggleWrapper(tog) {
var span = document.createElement("span");
span.className = "toggle-label";
@@ -2374,6 +2355,30 @@
};
});
+ // In the search display, allows to switch between tabs.
+ function printTab(nb) {
+ if (nb === 0 || nb === 1 || nb === 2) {
+ currentTab = nb;
+ }
+ var nb_copy = nb;
+ onEachLazy(document.getElementById("titles").childNodes, function(elem) {
+ if (nb_copy === 0) {
+ addClass(elem, "selected");
+ } else {
+ removeClass(elem, "selected");
+ }
+ nb_copy -= 1;
+ });
+ onEachLazy(document.getElementById("results").childNodes, function(elem) {
+ if (nb === 0) {
+ elem.style.display = "";
+ } else {
+ elem.style.display = "none";
+ }
+ nb -= 1;
+ });
+ }
+
function putBackSearch(search_input) {
if (search_input.value !== "") {
addClass(main, "hidden");
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index fefff1f..7c1a614 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -1,7 +1,8 @@
-use rustc::lint as lint;
-use rustc::hir;
-use rustc::hir::def::Def;
+use errors::Applicability;
+use rustc::hir::def::{Def, Namespace::{self, *}, PerNS};
use rustc::hir::def_id::DefId;
+use rustc::hir;
+use rustc::lint as lint;
use rustc::ty;
use syntax;
use syntax::ast::{self, Ident};
@@ -35,22 +36,9 @@
}
}
-#[derive(Debug)]
-enum PathKind {
- /// Either a value or type, but not a macro
- Unknown,
- /// Macro
- Macro,
- /// Values, functions, consts, statics (everything in the value namespace)
- Value,
- /// Types, traits (everything in the type namespace)
- Type,
-}
-
struct LinkCollector<'a, 'tcx> {
cx: &'a DocContext<'tcx>,
mod_ids: Vec<ast::NodeId>,
- is_nightly_build: bool,
}
impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
@@ -58,16 +46,14 @@
LinkCollector {
cx,
mod_ids: Vec::new(),
- is_nightly_build: UnstableFeatures::from_environment().is_nightly_build(),
}
}
- /// Resolves a given string as a path, along with whether or not it is
- /// in the value namespace. Also returns an optional URL fragment in the case
- /// of variants and methods.
+ /// Resolves a string as a path within a particular namespace. Also returns an optional
+ /// URL fragment in the case of variants and methods.
fn resolve(&self,
path_str: &str,
- is_val: bool,
+ ns: Namespace,
current_item: &Option<String>,
parent_id: Option<ast::NodeId>)
-> Result<(Def, Option<String>), ()>
@@ -78,11 +64,11 @@
// path.
if let Some(id) = parent_id.or(self.mod_ids.last().cloned()) {
// FIXME: `with_scope` requires the `NodeId` of a module.
- let result = cx.enter_resolver(|resolver| resolver.with_scope(id,
- |resolver| {
- resolver.resolve_str_path_error(DUMMY_SP,
- &path_str, is_val)
- }));
+ let result = cx.enter_resolver(|resolver| {
+ resolver.with_scope(id, |resolver| {
+ resolver.resolve_str_path_error(DUMMY_SP, &path_str, ns == ValueNS)
+ })
+ });
if let Ok(result) = result {
// In case this is a trait item, skip the
@@ -95,16 +81,16 @@
_ => return Ok((result.def, None))
};
- if value != is_val {
+ if value != (ns == ValueNS) {
return Err(())
}
- } else if let Some(prim) = is_primitive(path_str, is_val) {
+ } else if let Some(prim) = is_primitive(path_str, ns) {
return Ok((prim, Some(path_str.to_owned())))
} else {
// If resolution failed, it may still be a method
// because methods are not handled by the resolver
// If so, bail when we're not looking for a value.
- if !is_val {
+ if ns != ValueNS {
return Err(())
}
}
@@ -128,7 +114,7 @@
path = name.clone();
}
}
- if let Some(prim) = is_primitive(&path, false) {
+ if let Some(prim) = is_primitive(&path, TypeNS) {
let did = primitive_impl(cx, &path).ok_or(())?;
return cx.tcx.associated_items(did)
.find(|item| item.ident.name == item_name)
@@ -152,8 +138,8 @@
.find(|item| item.ident.name == item_name);
if let Some(item) = item {
let out = match item.kind {
- ty::AssociatedKind::Method if is_val => "method",
- ty::AssociatedKind::Const if is_val => "associatedconstant",
+ ty::AssociatedKind::Method if ns == ValueNS => "method",
+ ty::AssociatedKind::Const if ns == ValueNS => "associatedconstant",
_ => return Err(())
};
Ok((ty.def, Some(format!("{}.{}", out, item_name))))
@@ -190,9 +176,9 @@
.find(|item| item.ident.name == item_name);
if let Some(item) = item {
let kind = match item.kind {
- ty::AssociatedKind::Const if is_val => "associatedconstant",
- ty::AssociatedKind::Type if !is_val => "associatedtype",
- ty::AssociatedKind::Method if is_val => {
+ ty::AssociatedKind::Const if ns == ValueNS => "associatedconstant",
+ ty::AssociatedKind::Type if ns == TypeNS => "associatedtype",
+ ty::AssociatedKind::Method if ns == ValueNS => {
if item.defaultness.has_value() {
"method"
} else {
@@ -279,39 +265,41 @@
look_for_tests(&cx, &dox, &item, true);
- if !self.is_nightly_build {
- return None;
- }
-
for (ori_link, link_range) in markdown_links(&dox) {
// Bail early for real links.
if ori_link.contains('/') {
continue;
}
+
+ // [] is mostly likely not supposed to be a link
+ if ori_link.is_empty() {
+ continue;
+ }
+
let link = ori_link.replace("`", "");
let (def, fragment) = {
- let mut kind = PathKind::Unknown;
+ let mut kind = None;
let path_str = if let Some(prefix) =
["struct@", "enum@", "type@",
"trait@", "union@"].iter()
.find(|p| link.starts_with(**p)) {
- kind = PathKind::Type;
+ kind = Some(TypeNS);
link.trim_start_matches(prefix)
} else if let Some(prefix) =
["const@", "static@",
"value@", "function@", "mod@",
"fn@", "module@", "method@"]
.iter().find(|p| link.starts_with(**p)) {
- kind = PathKind::Value;
+ kind = Some(ValueNS);
link.trim_start_matches(prefix)
} else if link.ends_with("()") {
- kind = PathKind::Value;
+ kind = Some(ValueNS);
link.trim_end_matches("()")
} else if link.starts_with("macro@") {
- kind = PathKind::Macro;
+ kind = Some(MacroNS);
link.trim_start_matches("macro@")
} else if link.ends_with('!') {
- kind = PathKind::Macro;
+ kind = Some(MacroNS);
link.trim_end_matches('!')
} else {
&link[..]
@@ -323,8 +311,8 @@
}
match kind {
- PathKind::Value => {
- if let Ok(def) = self.resolve(path_str, true, ¤t_item, parent_node) {
+ Some(ns @ ValueNS) => {
+ if let Ok(def) = self.resolve(path_str, ns, ¤t_item, parent_node) {
def
} else {
resolution_failure(cx, &item.attrs, path_str, &dox, link_range);
@@ -334,8 +322,8 @@
continue;
}
}
- PathKind::Type => {
- if let Ok(def) = self.resolve(path_str, false, ¤t_item, parent_node) {
+ Some(ns @ TypeNS) => {
+ if let Ok(def) = self.resolve(path_str, ns, ¤t_item, parent_node) {
def
} else {
resolution_failure(cx, &item.attrs, path_str, &dox, link_range);
@@ -343,62 +331,49 @@
continue;
}
}
- PathKind::Unknown => {
+ None => {
// Try everything!
- if let Some(macro_def) = macro_resolve(cx, path_str) {
- if let Ok(type_def) =
- self.resolve(path_str, false, ¤t_item, parent_node)
- {
- let (type_kind, article, type_disambig)
- = type_ns_kind(type_def.0, path_str);
- ambiguity_error(cx, &item.attrs, path_str,
- article, type_kind, &type_disambig,
- "a", "macro", &format!("macro@{}", path_str));
- continue;
- } else if let Ok(value_def) =
- self.resolve(path_str, true, ¤t_item, parent_node)
- {
- let (value_kind, value_disambig)
- = value_ns_kind(value_def.0, path_str)
- .expect("struct and mod cases should have been \
- caught in previous branch");
- ambiguity_error(cx, &item.attrs, path_str,
- "a", value_kind, &value_disambig,
- "a", "macro", &format!("macro@{}", path_str));
- }
- (macro_def, None)
- } else if let Ok(type_def) =
- self.resolve(path_str, false, ¤t_item, parent_node)
- {
- // It is imperative we search for not-a-value first
- // Otherwise we will find struct ctors for when we are looking
- // for structs, and the link won't work if there is something in
- // both namespaces.
- if let Ok(value_def) =
- self.resolve(path_str, true, ¤t_item, parent_node)
- {
- let kind = value_ns_kind(value_def.0, path_str);
- if let Some((value_kind, value_disambig)) = kind {
- let (type_kind, article, type_disambig)
- = type_ns_kind(type_def.0, path_str);
- ambiguity_error(cx, &item.attrs, path_str,
- article, type_kind, &type_disambig,
- "a", value_kind, &value_disambig);
- continue;
- }
- }
- type_def
- } else if let Ok(value_def) =
- self.resolve(path_str, true, ¤t_item, parent_node)
- {
- value_def
- } else {
+ let candidates = PerNS {
+ macro_ns: macro_resolve(cx, path_str).map(|def| (def, None)),
+ type_ns: self
+ .resolve(path_str, TypeNS, ¤t_item, parent_node)
+ .ok(),
+ value_ns: self
+ .resolve(path_str, ValueNS, ¤t_item, parent_node)
+ .ok()
+ .and_then(|(def, fragment)| {
+ // Constructors are picked up in the type namespace.
+ match def {
+ Def::StructCtor(..)
+ | Def::VariantCtor(..)
+ | Def::SelfCtor(..) => None,
+ _ => Some((def, fragment))
+ }
+ }),
+ };
+
+ if candidates.is_empty() {
resolution_failure(cx, &item.attrs, path_str, &dox, link_range);
// this could just be a normal link
continue;
}
+
+ let is_unambiguous = candidates.clone().present_items().count() == 1;
+ if is_unambiguous {
+ candidates.present_items().next().unwrap()
+ } else {
+ ambiguity_error(
+ cx,
+ &item.attrs,
+ path_str,
+ &dox,
+ link_range,
+ candidates.map(|candidate| candidate.map(|(def, _)| def)),
+ );
+ continue;
+ }
}
- PathKind::Macro => {
+ Some(MacroNS) => {
if let Some(def) = macro_resolve(cx, path_str) {
(def, None)
} else {
@@ -505,59 +480,114 @@
diag.emit();
}
-fn ambiguity_error(cx: &DocContext<'_>, attrs: &Attributes,
- path_str: &str,
- article1: &str, kind1: &str, disambig1: &str,
- article2: &str, kind2: &str, disambig2: &str) {
+fn ambiguity_error(
+ cx: &DocContext<'_>,
+ attrs: &Attributes,
+ path_str: &str,
+ dox: &str,
+ link_range: Option<Range<usize>>,
+ candidates: PerNS<Option<Def>>,
+) {
let sp = span_of_attrs(attrs);
- cx.sess()
- .struct_span_warn(sp,
- &format!("`{}` is both {} {} and {} {}",
- path_str, article1, kind1,
- article2, kind2))
- .help(&format!("try `{}` if you want to select the {}, \
- or `{}` if you want to \
- select the {}",
- disambig1, kind1, disambig2,
- kind2))
- .emit();
-}
-/// Given a def, returns its name and disambiguator
-/// for a value namespace.
-///
-/// Returns `None` for things which cannot be ambiguous since
-/// they exist in both namespaces (structs and modules).
-fn value_ns_kind(def: Def, path_str: &str) -> Option<(&'static str, String)> {
- match def {
- // Structs, variants, and mods exist in both namespaces; skip them.
- Def::StructCtor(..) | Def::Mod(..) | Def::Variant(..) |
- Def::VariantCtor(..) | Def::SelfCtor(..)
- => None,
- Def::Fn(..)
- => Some(("function", format!("{}()", path_str))),
- Def::Method(..)
- => Some(("method", format!("{}()", path_str))),
- Def::Const(..)
- => Some(("const", format!("const@{}", path_str))),
- Def::Static(..)
- => Some(("static", format!("static@{}", path_str))),
- _ => Some(("value", format!("value@{}", path_str))),
+ let mut msg = format!("`{}` is ", path_str);
+
+ let candidates = [TypeNS, ValueNS, MacroNS].iter().filter_map(|&ns| {
+ candidates[ns].map(|def| (def, ns))
+ }).collect::<Vec<_>>();
+ match candidates.as_slice() {
+ [(first_def, _), (second_def, _)] => {
+ msg += &format!(
+ "both {} {} and {} {}",
+ first_def.article(),
+ first_def.kind_name(),
+ second_def.article(),
+ second_def.kind_name(),
+ );
+ }
+ _ => {
+ let mut candidates = candidates.iter().peekable();
+ while let Some((def, _)) = candidates.next() {
+ if candidates.peek().is_some() {
+ msg += &format!("{} {}, ", def.article(), def.kind_name());
+ } else {
+ msg += &format!("and {} {}", def.article(), def.kind_name());
+ }
+ }
+ }
}
-}
-/// Given a def, returns its name, the article to be used, and a disambiguator
-/// for the type namespace.
-fn type_ns_kind(def: Def, path_str: &str) -> (&'static str, &'static str, String) {
- let (kind, article) = match def {
- // We can still have non-tuple structs.
- Def::Struct(..) => ("struct", "a"),
- Def::Enum(..) => ("enum", "an"),
- Def::Trait(..) => ("trait", "a"),
- Def::Union(..) => ("union", "a"),
- _ => ("type", "a"),
- };
- (kind, article, format!("{}@{}", kind, path_str))
+ let mut diag = cx.tcx.struct_span_lint_hir(
+ lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE,
+ hir::CRATE_HIR_ID,
+ sp,
+ &msg,
+ );
+
+ if let Some(link_range) = link_range {
+ if let Some(sp) = super::source_span_for_markdown_range(cx, dox, &link_range, attrs) {
+ diag.set_span(sp);
+ diag.span_label(sp, "ambiguous link");
+
+ for (def, ns) in candidates {
+ let (action, mut suggestion) = match def {
+ Def::Method(..) | Def::Fn(..) => {
+ ("add parentheses", format!("{}()", path_str))
+ }
+ Def::Macro(..) => {
+ ("add an exclamation mark", format!("{}!", path_str))
+ }
+ _ => {
+ let type_ = match (def, ns) {
+ (Def::Const(..), _) => "const",
+ (Def::Static(..), _) => "static",
+ (Def::Struct(..), _) => "struct",
+ (Def::Enum(..), _) => "enum",
+ (Def::Union(..), _) => "union",
+ (Def::Trait(..), _) => "trait",
+ (Def::Mod(..), _) => "module",
+ (_, TypeNS) => "type",
+ (_, ValueNS) => "value",
+ (_, MacroNS) => "macro",
+ };
+
+ // FIXME: if this is an implied shortcut link, it's bad style to suggest `@`
+ ("prefix with the item type", format!("{}@{}", type_, path_str))
+ }
+ };
+
+ if dox.bytes().nth(link_range.start) == Some(b'`') {
+ suggestion = format!("`{}`", suggestion);
+ }
+
+ diag.span_suggestion(
+ sp,
+ &format!("to link to the {}, {}", def.kind_name(), action),
+ suggestion,
+ Applicability::MaybeIncorrect,
+ );
+ }
+ } else {
+ // blah blah blah\nblah\nblah [blah] blah blah\nblah blah
+ // ^ ~~~~
+ // | link_range
+ // last_new_line_offset
+ let last_new_line_offset = dox[..link_range.start].rfind('\n').map_or(0, |n| n + 1);
+ let line = dox[last_new_line_offset..].lines().next().unwrap_or("");
+
+ // Print the line containing the `link_range` and manually mark it with '^'s.
+ diag.note(&format!(
+ "the link appears in this line:\n\n{line}\n\
+ {indicator: <before$}{indicator:^<found$}",
+ line=line,
+ indicator="",
+ before=link_range.start - last_new_line_offset,
+ found=link_range.len(),
+ ));
+ }
+ }
+
+ diag.emit();
}
/// Given an enum variant's def, return the def of its enum and the associated fragment.
@@ -594,11 +624,11 @@
("char", Def::PrimTy(hir::PrimTy::Char)),
];
-fn is_primitive(path_str: &str, is_val: bool) -> Option<Def> {
- if is_val {
- None
- } else {
+fn is_primitive(path_str: &str, ns: Namespace) -> Option<Def> {
+ if ns == TypeNS {
PRIMITIVES.iter().find(|x| x.0 == path_str).map(|x| x.1)
+ } else {
+ None
}
}
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 0c99f6d..b4db121 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -178,9 +178,10 @@
Some(kind) => {
let name = if kind == MacroKind::Derive {
item.attrs.lists("proc_macro_derive")
- .filter_map(|mi| mi.name())
+ .filter_map(|mi| mi.ident())
.next()
.expect("proc-macro derives require a name")
+ .name
} else {
name
};
@@ -193,8 +194,8 @@
if let Some(list) = mi.meta_item_list() {
for inner_mi in list {
- if let Some(name) = inner_mi.name() {
- helpers.push(name);
+ if let Some(ident) = inner_mi.ident() {
+ helpers.push(ident.name);
}
}
}
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index 928de29..1d45df4 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -19,7 +19,7 @@
use super::table::BucketState::{Empty, Full};
use super::table::Fallibility::{Fallible, Infallible};
-const MIN_NONZERO_RAW_CAPACITY: usize = 32; // must be a power of two
+const MIN_NONZERO_RAW_CAPACITY: usize = 32; // must be a power of two
/// The default behavior of HashMap implements a maximum load factor of 90.9%.
#[derive(Clone)]
diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs
index f2111f2..c026de3 100644
--- a/src/libstd/collections/hash/set.rs
+++ b/src/libstd/collections/hash/set.rs
@@ -8,7 +8,7 @@
use super::map::{self, HashMap, Keys, RandomState};
// Future Optimization (FIXME!)
-// =============================
+// ============================
//
// Iteration over zero sized values is a noop. There is no need
// for `bucket.val` in the case of HashSet. I suppose we would need HKT
diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs
index a2b12d0..688d9c1 100644
--- a/src/libstd/f32.rs
+++ b/src/libstd/f32.rs
@@ -32,11 +32,13 @@
/// # Examples
///
/// ```
- /// let f = 3.99_f32;
+ /// let f = 3.7_f32;
/// let g = 3.0_f32;
+ /// let h = -3.7_f32;
///
/// assert_eq!(f.floor(), 3.0);
/// assert_eq!(g.floor(), 3.0);
+ /// assert_eq!(h.floor(), -4.0);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
@@ -104,11 +106,13 @@
/// # Examples
///
/// ```
- /// let f = 3.3_f32;
- /// let g = -3.7_f32;
+ /// let f = 3.7_f32;
+ /// let g = 3.0_f32;
+ /// let h = -3.7_f32;
///
/// assert_eq!(f.trunc(), 3.0);
- /// assert_eq!(g.trunc(), -3.0);
+ /// assert_eq!(g.trunc(), 3.0);
+ /// assert_eq!(h.trunc(), -3.0);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
@@ -966,6 +970,7 @@
/// assert!((-3.0f32).clamp(-2.0f32, 1.0f32) == -2.0f32);
/// assert!((0.0f32).clamp(-2.0f32, 1.0f32) == 0.0f32);
/// assert!((2.0f32).clamp(-2.0f32, 1.0f32) == 1.0f32);
+ /// assert!((std::f32::NAN).clamp(-2.0f32, 1.0f32).is_nan());
/// ```
#[unstable(feature = "clamp", issue = "44095")]
#[inline]
@@ -1577,4 +1582,22 @@
assert_eq!(f32::from_bits(masked_nan1).to_bits(), masked_nan1);
assert_eq!(f32::from_bits(masked_nan2).to_bits(), masked_nan2);
}
+
+ #[test]
+ #[should_panic]
+ fn test_clamp_min_greater_than_max() {
+ 1.0f32.clamp(3.0, 1.0);
+ }
+
+ #[test]
+ #[should_panic]
+ fn test_clamp_min_is_nan() {
+ 1.0f32.clamp(NAN, 1.0);
+ }
+
+ #[test]
+ #[should_panic]
+ fn test_clamp_max_is_nan() {
+ 1.0f32.clamp(3.0, NAN);
+ }
}
diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs
index be5cd92..b171e1c 100644
--- a/src/libstd/f64.rs
+++ b/src/libstd/f64.rs
@@ -32,11 +32,13 @@
/// # Examples
///
/// ```
- /// let f = 3.99_f64;
+ /// let f = 3.7_f64;
/// let g = 3.0_f64;
+ /// let h = -3.7_f64;
///
/// assert_eq!(f.floor(), 3.0);
/// assert_eq!(g.floor(), 3.0);
+ /// assert_eq!(h.floor(), -4.0);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
@@ -84,11 +86,13 @@
/// # Examples
///
/// ```
- /// let f = 3.3_f64;
- /// let g = -3.7_f64;
+ /// let f = 3.7_f64;
+ /// let g = 3.0_f64;
+ /// let h = -3.7_f64;
///
/// assert_eq!(f.trunc(), 3.0);
- /// assert_eq!(g.trunc(), -3.0);
+ /// assert_eq!(g.trunc(), 3.0);
+ /// assert_eq!(h.trunc(), -3.0);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
@@ -888,6 +892,7 @@
/// assert!((-3.0f64).clamp(-2.0f64, 1.0f64) == -2.0f64);
/// assert!((0.0f64).clamp(-2.0f64, 1.0f64) == 0.0f64);
/// assert!((2.0f64).clamp(-2.0f64, 1.0f64) == 1.0f64);
+ /// assert!((std::f64::NAN).clamp(-2.0f64, 1.0f64).is_nan());
/// ```
#[unstable(feature = "clamp", issue = "44095")]
#[inline]
@@ -1518,4 +1523,22 @@
assert_eq!(f64::from_bits(masked_nan1).to_bits(), masked_nan1);
assert_eq!(f64::from_bits(masked_nan2).to_bits(), masked_nan2);
}
+
+ #[test]
+ #[should_panic]
+ fn test_clamp_min_greater_than_max() {
+ 1.0f64.clamp(3.0, 1.0);
+ }
+
+ #[test]
+ #[should_panic]
+ fn test_clamp_min_is_nan() {
+ 1.0f64.clamp(NAN, 1.0);
+ }
+
+ #[test]
+ #[should_panic]
+ fn test_clamp_max_is_nan() {
+ 1.0f64.clamp(3.0, NAN);
+ }
}
diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs
index 25f2dd7..8c3d0da 100644
--- a/src/libstd/fs.rs
+++ b/src/libstd/fs.rs
@@ -211,7 +211,7 @@
recursive: bool,
}
-/// How large a buffer to pre-allocate before reading the entire file.
+/// Indicates 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`
@@ -1581,7 +1581,8 @@
/// `O_CLOEXEC` is set for returned file descriptors.
/// On Windows, this function currently corresponds to `CopyFileEx`. Alternate
/// NTFS streams are copied but only the size of the main stream is returned by
-/// this function.
+/// this function. On MacOS, this function corresponds to `copyfile` with
+/// `COPYFILE_ALL`.
/// Note that, this [may change in the future][changes].
///
/// [changes]: ../io/index.html#platform-specific-behavior
@@ -2837,6 +2838,26 @@
}
#[test]
+ fn copy_file_follows_dst_symlink() {
+ let tmp = tmpdir();
+ if !got_symlink_permission(&tmp) { return };
+
+ let in_path = tmp.join("in.txt");
+ let out_path = tmp.join("out.txt");
+ let out_path_symlink = tmp.join("out_symlink.txt");
+
+ check!(fs::write(&in_path, "foo"));
+ check!(fs::write(&out_path, "bar"));
+ check!(symlink_file(&out_path, &out_path_symlink));
+
+ check!(fs::copy(&in_path, &out_path_symlink));
+
+ assert!(check!(out_path_symlink.symlink_metadata()).file_type().is_symlink());
+ assert_eq!(check!(fs::read(&out_path_symlink)), b"foo".to_vec());
+ assert_eq!(check!(fs::read(&out_path)), b"foo".to_vec());
+ }
+
+ #[test]
fn symlinks_work() {
let tmpdir = tmpdir();
if !got_symlink_permission(&tmpdir) { return };
diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index a14c10d..4668e3e 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -193,6 +193,13 @@
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn into_inner(self) -> R { self.inner }
+
+ /// Invalidates all data in the internal buffer.
+ #[inline]
+ fn discard_buffer(&mut self) {
+ self.pos = 0;
+ self.cap = 0;
+ }
}
impl<R: Seek> BufReader<R> {
@@ -227,6 +234,7 @@
// (larger than our internal buffer), bypass our internal buffer
// entirely.
if self.pos == self.cap && buf.len() >= self.buf.len() {
+ self.discard_buffer();
return self.inner.read(buf);
}
let nread = {
@@ -240,6 +248,7 @@
fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
let total_len = bufs.iter().map(|b| b.len()).sum::<usize>();
if self.pos == self.cap && total_len >= self.buf.len() {
+ self.discard_buffer();
return self.inner.read_vectored(bufs);
}
let nread = {
@@ -325,14 +334,14 @@
} else {
// seek backwards by our remainder, and then by the offset
self.inner.seek(SeekFrom::Current(-remainder))?;
- self.pos = self.cap; // empty the buffer
+ self.discard_buffer();
result = self.inner.seek(SeekFrom::Current(n))?;
}
} else {
// Seeking with Start/End doesn't care about our buffer length.
result = self.inner.seek(pos)?;
}
- self.pos = self.cap; // empty the buffer
+ self.discard_buffer();
Ok(result)
}
}
@@ -1069,6 +1078,40 @@
}
#[test]
+ fn test_buffered_reader_invalidated_after_read() {
+ let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
+ let mut reader = BufReader::with_capacity(3, io::Cursor::new(inner));
+
+ assert_eq!(reader.fill_buf().ok(), Some(&[5, 6, 7][..]));
+ reader.consume(3);
+
+ let mut buffer = [0, 0, 0, 0, 0];
+ assert_eq!(reader.read(&mut buffer).ok(), Some(5));
+ assert_eq!(buffer, [0, 1, 2, 3, 4]);
+
+ assert!(reader.seek_relative(-2).is_ok());
+ let mut buffer = [0, 0];
+ assert_eq!(reader.read(&mut buffer).ok(), Some(2));
+ assert_eq!(buffer, [3, 4]);
+ }
+
+ #[test]
+ fn test_buffered_reader_invalidated_after_seek() {
+ let inner: &[u8] = &[5, 6, 7, 0, 1, 2, 3, 4];
+ let mut reader = BufReader::with_capacity(3, io::Cursor::new(inner));
+
+ assert_eq!(reader.fill_buf().ok(), Some(&[5, 6, 7][..]));
+ reader.consume(3);
+
+ assert!(reader.seek(SeekFrom::Current(5)).is_ok());
+
+ assert!(reader.seek_relative(-2).is_ok());
+ let mut buffer = [0, 0];
+ assert_eq!(reader.read(&mut buffer).ok(), Some(2));
+ assert_eq!(buffer, [3, 4]);
+ }
+
+ #[test]
fn test_buffered_reader_seek_underflow() {
// gimmick reader that yields its position modulo 256 for each byte
struct PositionReader {
diff --git a/src/libstd/io/cursor.rs b/src/libstd/io/cursor.rs
index 873da08..247d45c 100644
--- a/src/libstd/io/cursor.rs
+++ b/src/libstd/io/cursor.rs
@@ -212,6 +212,14 @@
"invalid seek to a negative or overflowing position"))
}
}
+
+ fn stream_len(&mut self) -> io::Result<u64> {
+ Ok(self.inner.as_ref().len() as u64)
+ }
+
+ fn stream_position(&mut self) -> io::Result<u64> {
+ Ok(self.pos)
+ }
}
#[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index e3e2754..7147b64 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -390,6 +390,28 @@
ret
}
+pub(crate) fn default_read_vectored<F>(read: F, bufs: &mut [IoVecMut<'_>]) -> Result<usize>
+where
+ F: FnOnce(&mut [u8]) -> Result<usize>
+{
+ let buf = bufs
+ .iter_mut()
+ .find(|b| !b.is_empty())
+ .map_or(&mut [][..], |b| &mut **b);
+ read(buf)
+}
+
+pub(crate) fn default_write_vectored<F>(write: F, bufs: &[IoVec<'_>]) -> Result<usize>
+where
+ F: FnOnce(&[u8]) -> Result<usize>
+{
+ let buf = bufs
+ .iter()
+ .find(|b| !b.is_empty())
+ .map_or(&[][..], |b| &**b);
+ write(buf)
+}
+
/// The `Read` trait allows for reading bytes from a source.
///
/// Implementors of the `Read` trait are called 'readers'.
@@ -528,14 +550,11 @@
/// written to possibly being only partially filled. This method must behave
/// as a single call to `read` with the buffers concatenated would.
///
- /// The default implementation simply passes the first nonempty buffer to
- /// `read`.
+ /// The default implementation calls `read` with either the first nonempty
+ /// buffer provided, or an empty one if none exists.
#[unstable(feature = "iovec", issue = "58452")]
fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> Result<usize> {
- match bufs.iter_mut().find(|b| !b.is_empty()) {
- Some(buf) => self.read(buf),
- None => Ok(0),
- }
+ default_read_vectored(|b| self.read(b), bufs)
}
/// Determines if this `Read`er can work with buffers of uninitialized
@@ -1107,14 +1126,11 @@
/// read from possibly being only partially consumed. This method must
/// behave as a call to `write` with the buffers concatenated would.
///
- /// The default implementation simply passes the first nonempty buffer to
- /// `write`.
+ /// The default implementation calls `write` with either the first nonempty
+ /// buffer provided, or an empty one if none exists.
#[unstable(feature = "iovec", issue = "58452")]
fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> Result<usize> {
- match bufs.iter().find(|b| !b.is_empty()) {
- Some(buf) => self.write(buf),
- None => Ok(0),
- }
+ default_write_vectored(|b| self.write(b), bufs)
}
/// Flush this output stream, ensuring that all intermediately buffered
@@ -1329,6 +1345,85 @@
/// [`SeekFrom::Start`]: enum.SeekFrom.html#variant.Start
#[stable(feature = "rust1", since = "1.0.0")]
fn seek(&mut self, pos: SeekFrom) -> Result<u64>;
+
+ /// Returns the length of this stream (in bytes).
+ ///
+ /// This method is implemented using up to three seek operations. If this
+ /// method returns successfully, the seek position is unchanged (i.e. the
+ /// position before calling this method is the same as afterwards).
+ /// However, if this method returns an error, the seek position is
+ /// unspecified.
+ ///
+ /// If you need to obtain the length of *many* streams and you don't care
+ /// about the seek position afterwards, you can reduce the number of seek
+ /// operations by simply calling `seek(SeekFrom::End(0))` and using its
+ /// return value (it is also the stream length).
+ ///
+ /// Note that length of a stream can change over time (for example, when
+ /// data is appended to a file). So calling this method multiple times does
+ /// not necessarily return the same length each time.
+ ///
+ ///
+ /// # Example
+ ///
+ /// ```no_run
+ /// #![feature(seek_convenience)]
+ /// use std::{
+ /// io::{self, Seek},
+ /// fs::File,
+ /// };
+ ///
+ /// fn main() -> io::Result<()> {
+ /// let mut f = File::open("foo.txt")?;
+ ///
+ /// let len = f.stream_len()?;
+ /// println!("The file is currently {} bytes long", len);
+ /// Ok(())
+ /// }
+ /// ```
+ #[unstable(feature = "seek_convenience", issue = "59359")]
+ fn stream_len(&mut self) -> Result<u64> {
+ let old_pos = self.stream_position()?;
+ let len = self.seek(SeekFrom::End(0))?;
+
+ // Avoid seeking a third time when we were already at the end of the
+ // stream. The branch is usually way cheaper than a seek operation.
+ if old_pos != len {
+ self.seek(SeekFrom::Start(old_pos))?;
+ }
+
+ Ok(len)
+ }
+
+ /// Returns the current seek position from the start of the stream.
+ ///
+ /// This is equivalent to `self.seek(SeekFrom::Current(0))`.
+ ///
+ ///
+ /// # Example
+ ///
+ /// ```no_run
+ /// #![feature(seek_convenience)]
+ /// use std::{
+ /// io::{self, BufRead, BufReader, Seek},
+ /// fs::File,
+ /// };
+ ///
+ /// fn main() -> io::Result<()> {
+ /// let mut f = BufReader::new(File::open("foo.txt")?);
+ ///
+ /// let before = f.stream_position()?;
+ /// f.read_line(&mut String::new())?;
+ /// let after = f.stream_position()?;
+ ///
+ /// println!("The first line was {} bytes long", after - before);
+ /// Ok(())
+ /// }
+ /// ```
+ #[unstable(feature = "seek_convenience", issue = "59359")]
+ fn stream_position(&mut self) -> Result<u64> {
+ self.seek(SeekFrom::Current(0))
+ }
}
/// Enumeration of possible methods to seek within an I/O object.
@@ -2157,8 +2252,7 @@
mod tests {
use crate::io::prelude::*;
use crate::io;
- use super::Cursor;
- use super::repeat;
+ use super::{Cursor, SeekFrom, repeat};
#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
@@ -2380,4 +2474,50 @@
super::read_to_end(&mut lr, &mut vec)
});
}
+
+ #[test]
+ fn seek_len() -> io::Result<()> {
+ let mut c = Cursor::new(vec![0; 15]);
+ assert_eq!(c.stream_len()?, 15);
+
+ c.seek(SeekFrom::End(0))?;
+ let old_pos = c.stream_position()?;
+ assert_eq!(c.stream_len()?, 15);
+ assert_eq!(c.stream_position()?, old_pos);
+
+ c.seek(SeekFrom::Start(7))?;
+ c.seek(SeekFrom::Current(2))?;
+ let old_pos = c.stream_position()?;
+ assert_eq!(c.stream_len()?, 15);
+ assert_eq!(c.stream_position()?, old_pos);
+
+ Ok(())
+ }
+
+ #[test]
+ fn seek_position() -> io::Result<()> {
+ // All `asserts` are duplicated here to make sure the method does not
+ // change anything about the seek state.
+ let mut c = Cursor::new(vec![0; 15]);
+ assert_eq!(c.stream_position()?, 0);
+ assert_eq!(c.stream_position()?, 0);
+
+ c.seek(SeekFrom::End(0))?;
+ assert_eq!(c.stream_position()?, 15);
+ assert_eq!(c.stream_position()?, 15);
+
+
+ c.seek(SeekFrom::Start(7))?;
+ c.seek(SeekFrom::Current(2))?;
+ assert_eq!(c.stream_position()?, 9);
+ assert_eq!(c.stream_position()?, 9);
+
+ c.seek(SeekFrom::End(-3))?;
+ c.seek(SeekFrom::Current(1))?;
+ c.seek(SeekFrom::Current(-5))?;
+ assert_eq!(c.stream_position()?, 8);
+ assert_eq!(c.stream_position()?, 8);
+
+ Ok(())
+ }
}
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index b830c90..296c4c8 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -221,7 +221,7 @@
#![cfg_attr(test, feature(print_internals, set_stdio, test, update_panic_count))]
#![cfg_attr(all(target_vendor = "fortanix", target_env = "sgx"),
- feature(global_asm, range_contains, slice_index_methods,
+ feature(global_asm, slice_index_methods,
decl_macro, coerce_unsized, sgx_platform, ptr_wrapping_offset_from))]
// std is implemented with unstable features, many of which are internal
@@ -301,6 +301,7 @@
#![feature(stmt_expr_attributes)]
#![feature(str_internals)]
#![feature(thread_local)]
+#![feature(todo_macro)]
#![feature(toowned_clone_into)]
#![feature(try_reserve)]
#![feature(unboxed_closures)]
@@ -323,7 +324,7 @@
#[stable(feature = "rust1", since = "1.0.0")]
pub use core::{assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_ne};
#[stable(feature = "rust1", since = "1.0.0")]
-pub use core::{unreachable, unimplemented, write, writeln, r#try};
+pub use core::{unreachable, unimplemented, write, writeln, r#try, todo};
#[allow(unused_imports)] // macros from `alloc` are not used on all platforms
#[macro_use]
diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs
index 9d0eb2e..d5dc5f7 100644
--- a/src/libstd/macros.rs
+++ b/src/libstd/macros.rs
@@ -305,10 +305,16 @@
/// let _ = dbg!(a); // <-- `a` is moved again; error!
/// ```
///
+/// You can also use `dbg!()` without a value to just print the
+/// file and line whenever it's reached.
+///
/// [stderr]: https://en.wikipedia.org/wiki/Standard_streams#Standard_error_(stderr)
#[macro_export]
#[stable(feature = "dbg_macro", since = "1.32.0")]
macro_rules! dbg {
+ () => {
+ eprintln!("[{}:{}]", file!(), line!());
+ };
($val:expr) => {
// Use of `match` here is intentional because it affects the lifetimes
// of temporaries - https://stackoverflow.com/a/48732525/1063961
diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs
index edc9d66..b42a812 100644
--- a/src/libstd/net/udp.rs
+++ b/src/libstd/net/udp.rs
@@ -180,6 +180,37 @@
}
}
+ /// Returns the socket address of the remote peer this socket was connected to.
+ ///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// #![feature(udp_peer_addr)]
+ /// use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, UdpSocket};
+ ///
+ /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
+ /// socket.connect("192.168.0.1:41203").expect("couldn't connect to address");
+ /// assert_eq!(socket.peer_addr().unwrap(),
+ /// SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(192, 168, 0, 1), 41203)));
+ /// ```
+ ///
+ /// If the socket isn't connected, it will return a [`NotConnected`] error.
+ ///
+ /// [`NotConnected`]: ../../std/io/enum.ErrorKind.html#variant.NotConnected
+ ///
+ /// ```no_run
+ /// #![feature(udp_peer_addr)]
+ /// use std::net::UdpSocket;
+ ///
+ /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
+ /// assert_eq!(socket.peer_addr().unwrap_err().kind(),
+ /// ::std::io::ErrorKind::NotConnected);
+ /// ```
+ #[unstable(feature = "udp_peer_addr", issue = "59127")]
+ pub fn peer_addr(&self) -> io::Result<SocketAddr> {
+ self.0.peer_addr()
+ }
+
/// Returns the socket address that this socket was created from.
///
/// # Examples
@@ -865,7 +896,7 @@
}
#[test]
- fn socket_name_ip4() {
+ fn socket_name() {
each_ip(&mut |addr, _| {
let server = t!(UdpSocket::bind(&addr));
assert_eq!(addr, t!(server.local_addr()));
@@ -873,6 +904,16 @@
}
#[test]
+ fn socket_peer() {
+ each_ip(&mut |addr1, addr2| {
+ let server = t!(UdpSocket::bind(&addr1));
+ assert_eq!(server.peer_addr().unwrap_err().kind(), ErrorKind::NotConnected);
+ t!(server.connect(&addr2));
+ assert_eq!(addr2, t!(server.peer_addr()));
+ })
+ }
+
+ #[test]
fn udp_clone_smoke() {
each_ip(&mut |addr1, addr2| {
let sock1 = t!(UdpSocket::bind(&addr1));
diff --git a/src/libstd/os/fortanix_sgx/mod.rs b/src/libstd/os/fortanix_sgx/mod.rs
index bca22e7..4e30b1e 100644
--- a/src/libstd/os/fortanix_sgx/mod.rs
+++ b/src/libstd/os/fortanix_sgx/mod.rs
@@ -43,3 +43,8 @@
}
pub use crate::sys::ext::{io, arch, ffi};
+
+/// Functions for querying thread-related information.
+pub mod thread {
+ pub use crate::sys::abi::thread::current;
+}
diff --git a/src/libstd/process.rs b/src/libstd/process.rs
index 5684000..ad86acb 100644
--- a/src/libstd/process.rs
+++ b/src/libstd/process.rs
@@ -8,7 +8,7 @@
//!
//! The [`Command`] struct is used to configure and spawn processes:
//!
-//! ```
+//! ```no_run
//! use std::process::Command;
//!
//! let output = Command::new("echo")
diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs
index 5ebb617..c383f21 100644
--- a/src/libstd/sync/condvar.rs
+++ b/src/libstd/sync/condvar.rs
@@ -190,7 +190,7 @@
/// // Wait for the thread to start up.
/// let &(ref lock, ref cvar) = &*pair;
/// let mut started = lock.lock().unwrap();
- /// // As long as the value inside the `Mutex` is false, we wait.
+ /// // As long as the value inside the `Mutex<bool>` is `false`, we wait.
/// while !*started {
/// started = cvar.wait(started).unwrap();
/// }
@@ -254,7 +254,7 @@
///
/// // Wait for the thread to start up.
/// let &(ref lock, ref cvar) = &*pair;
- /// // As long as the value inside the `Mutex` is false, we wait.
+ /// // As long as the value inside the `Mutex<bool>` is `false`, we wait.
/// let _guard = cvar.wait_until(lock.lock().unwrap(), |started| { *started }).unwrap();
/// ```
#[unstable(feature = "wait_until", issue = "47960")]
@@ -311,7 +311,7 @@
/// // Wait for the thread to start up.
/// let &(ref lock, ref cvar) = &*pair;
/// let mut started = lock.lock().unwrap();
- /// // As long as the value inside the `Mutex` is false, we wait.
+ /// // As long as the value inside the `Mutex<bool>` is `false`, we wait.
/// loop {
/// let result = cvar.wait_timeout_ms(started, 10).unwrap();
/// // 10 milliseconds have passed, or maybe the value changed!
@@ -384,7 +384,7 @@
/// // wait for the thread to start up
/// let &(ref lock, ref cvar) = &*pair;
/// let mut started = lock.lock().unwrap();
- /// // as long as the value inside the `Mutex` is false, we wait
+ /// // as long as the value inside the `Mutex<bool>` is `false`, we wait
/// loop {
/// let result = cvar.wait_timeout(started, Duration::from_millis(10)).unwrap();
/// // 10 milliseconds have passed, or maybe the value changed!
@@ -518,7 +518,7 @@
/// // Wait for the thread to start up.
/// let &(ref lock, ref cvar) = &*pair;
/// let mut started = lock.lock().unwrap();
- /// // As long as the value inside the `Mutex` is false, we wait.
+ /// // As long as the value inside the `Mutex<bool>` is `false`, we wait.
/// while !*started {
/// started = cvar.wait(started).unwrap();
/// }
@@ -558,7 +558,7 @@
/// // Wait for the thread to start up.
/// let &(ref lock, ref cvar) = &*pair;
/// let mut started = lock.lock().unwrap();
- /// // As long as the value inside the `Mutex` is false, we wait.
+ /// // As long as the value inside the `Mutex<bool>` is `false`, we wait.
/// while !*started {
/// started = cvar.wait(started).unwrap();
/// }
diff --git a/src/libstd/sys/cloudabi/mod.rs b/src/libstd/sys/cloudabi/mod.rs
index 47c90fd..3f8e67a 100644
--- a/src/libstd/sys/cloudabi/mod.rs
+++ b/src/libstd/sys/cloudabi/mod.rs
@@ -14,8 +14,6 @@
pub mod memchr;
pub mod mutex;
pub mod os;
-#[path = "../unix/os_str.rs"]
-pub mod os_str;
pub mod rwlock;
pub mod stack_overflow;
pub mod stdio;
@@ -24,6 +22,8 @@
pub mod thread_local;
pub mod time;
+pub use crate::sys_common::os_str_bytes as os_str;
+
mod abi;
mod shims;
diff --git a/src/libstd/sys/cloudabi/shims/net.rs b/src/libstd/sys/cloudabi/shims/net.rs
index 6d2a496..4364a13 100644
--- a/src/libstd/sys/cloudabi/shims/net.rs
+++ b/src/libstd/sys/cloudabi/shims/net.rs
@@ -159,6 +159,10 @@
unsupported()
}
+ pub fn peer_addr(&self) -> io::Result<SocketAddr> {
+ match self.0 {}
+ }
+
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
match self.0 {}
}
diff --git a/src/libstd/sys/redox/ext/ffi.rs b/src/libstd/sys/redox/ext/ffi.rs
index 671498b..974d7b8 100644
--- a/src/libstd/sys/redox/ext/ffi.rs
+++ b/src/libstd/sys/redox/ext/ffi.rs
@@ -1,55 +1,38 @@
//! Redox-specific extension to the primitives in the `std::ffi` module.
+//!
+//! # Examples
+//!
+//! ```
+//! use std::ffi::OsString;
+//! use std::os::redox::ffi::OsStringExt;
+//!
+//! let bytes = b"foo".to_vec();
+//!
+//! // OsStringExt::from_vec
+//! let os_string = OsString::from_vec(bytes);
+//! assert_eq!(os_string.to_str(), Some("foo"));
+//!
+//! // OsStringExt::into_vec
+//! let bytes = os_string.into_vec();
+//! assert_eq!(bytes, b"foo");
+//! ```
+//!
+//! ```
+//! use std::ffi::OsStr;
+//! use std::os::redox::ffi::OsStrExt;
+//!
+//! let bytes = b"foo";
+//!
+//! // OsStrExt::from_bytes
+//! let os_str = OsStr::from_bytes(bytes);
+//! assert_eq!(os_str.to_str(), Some("foo"));
+//!
+//! // OsStrExt::as_bytes
+//! let bytes = os_str.as_bytes();
+//! assert_eq!(bytes, b"foo");
+//! ```
#![stable(feature = "rust1", since = "1.0.0")]
-use crate::ffi::{OsStr, OsString};
-use crate::mem;
-use crate::sys::os_str::Buf;
-use crate::sys_common::{FromInner, IntoInner, AsInner};
-
-/// Redox-specific extensions to [`OsString`].
-///
-/// [`OsString`]: ../../../../std/ffi/struct.OsString.html
#[stable(feature = "rust1", since = "1.0.0")]
-pub trait OsStringExt {
- /// Creates an `OsString` from a byte vector.
- #[stable(feature = "rust1", since = "1.0.0")]
- fn from_vec(vec: Vec<u8>) -> Self;
-
- /// Yields the underlying byte vector of this `OsString`.
- #[stable(feature = "rust1", since = "1.0.0")]
- fn into_vec(self) -> Vec<u8>;
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl OsStringExt for OsString {
- fn from_vec(vec: Vec<u8>) -> OsString {
- FromInner::from_inner(Buf { inner: vec })
- }
- fn into_vec(self) -> Vec<u8> {
- self.into_inner().inner
- }
-}
-
-/// Redox-specific extensions to [`OsStr`].
-///
-/// [`OsStr`]: ../../../../std/ffi/struct.OsStr.html
-#[stable(feature = "rust1", since = "1.0.0")]
-pub trait OsStrExt {
- #[stable(feature = "rust1", since = "1.0.0")]
- fn from_bytes(slice: &[u8]) -> &Self;
-
- /// Gets the underlying byte view of the `OsStr` slice.
- #[stable(feature = "rust1", since = "1.0.0")]
- fn as_bytes(&self) -> &[u8];
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl OsStrExt for OsStr {
- fn from_bytes(slice: &[u8]) -> &OsStr {
- unsafe { mem::transmute(slice) }
- }
- fn as_bytes(&self) -> &[u8] {
- &self.as_inner().inner
- }
-}
+pub use crate::sys_common::os_str_bytes::*;
diff --git a/src/libstd/sys/redox/mod.rs b/src/libstd/sys/redox/mod.rs
index 7f3ac1f..0e8ed8e 100644
--- a/src/libstd/sys/redox/mod.rs
+++ b/src/libstd/sys/redox/mod.rs
@@ -22,7 +22,6 @@
pub mod mutex;
pub mod net;
pub mod os;
-pub mod os_str;
pub mod path;
pub mod pipe;
pub mod process;
@@ -35,6 +34,8 @@
pub mod thread_local;
pub mod time;
+pub use crate::sys_common::os_str_bytes as os_str;
+
#[cfg(not(test))]
pub fn init() {}
diff --git a/src/libstd/sys/redox/net/tcp.rs b/src/libstd/sys/redox/net/tcp.rs
index 5081c3d..3f2f616 100644
--- a/src/libstd/sys/redox/net/tcp.rs
+++ b/src/libstd/sys/redox/net/tcp.rs
@@ -35,10 +35,7 @@
}
pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
- match bufs.iter_mut().find(|b| !b.is_empty()) {
- Some(buf) => self.read(buf),
- None => Ok(0),
- }
+ io::default_read_vectored(|b| self.read(b), bufs)
}
pub fn write(&self, buf: &[u8]) -> Result<usize> {
@@ -46,10 +43,7 @@
}
pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
- match bufs.iter().find(|b| !b.is_empty()) {
- Some(buf) => self.write(buf),
- None => Ok(0),
- }
+ io::default_write_vectored(|b| self.write(b), bufs)
}
pub fn take_error(&self) -> Result<Option<Error>> {
diff --git a/src/libstd/sys/redox/net/udp.rs b/src/libstd/sys/redox/net/udp.rs
index b1a60b1..274123d 100644
--- a/src/libstd/sys/redox/net/udp.rs
+++ b/src/libstd/sys/redox/net/udp.rs
@@ -72,6 +72,11 @@
Ok(None)
}
+ pub fn peer_addr(&self) -> Result<SocketAddr> {
+ let path = self.0.path()?;
+ Ok(path_to_peer_addr(path.to_str().unwrap_or("")))
+ }
+
pub fn socket_addr(&self) -> Result<SocketAddr> {
let path = self.0.path()?;
Ok(path_to_local_addr(path.to_str().unwrap_or("")))
diff --git a/src/libstd/sys/sgx/abi/thread.rs b/src/libstd/sys/sgx/abi/thread.rs
index 86fe09d..c17fa2d 100644
--- a/src/libstd/sys/sgx/abi/thread.rs
+++ b/src/libstd/sys/sgx/abi/thread.rs
@@ -4,6 +4,7 @@
/// all currently running threads in the enclave, and it is guaranteed to be
/// constant for the lifetime of the thread. More specifically for SGX, there
/// is a one-to-one correspondence of the ID to the address of the TCS.
+#[unstable(feature = "sgx_platform", issue = "56975")]
pub fn current() -> Tcs {
extern "C" { fn get_tcs_addr() -> Tcs; }
unsafe { get_tcs_addr() }
diff --git a/src/libstd/sys/sgx/ext/ffi.rs b/src/libstd/sys/sgx/ext/ffi.rs
index ad7ade9..63fc5ff 100644
--- a/src/libstd/sys/sgx/ext/ffi.rs
+++ b/src/libstd/sys/sgx/ext/ffi.rs
@@ -1,109 +1,38 @@
//! SGX-specific extension to the primitives in the `std::ffi` module
+//!
+//! # Examples
+//!
+//! ```
+//! use std::ffi::OsString;
+//! use std::os::fortanix_sgx::ffi::OsStringExt;
+//!
+//! let bytes = b"foo".to_vec();
+//!
+//! // OsStringExt::from_vec
+//! let os_string = OsString::from_vec(bytes);
+//! assert_eq!(os_string.to_str(), Some("foo"));
+//!
+//! // OsStringExt::into_vec
+//! let bytes = os_string.into_vec();
+//! assert_eq!(bytes, b"foo");
+//! ```
+//!
+//! ```
+//! use std::ffi::OsStr;
+//! use std::os::fortanix_sgx::ffi::OsStrExt;
+//!
+//! let bytes = b"foo";
+//!
+//! // OsStrExt::from_bytes
+//! let os_str = OsStr::from_bytes(bytes);
+//! assert_eq!(os_str.to_str(), Some("foo"));
+//!
+//! // OsStrExt::as_bytes
+//! let bytes = os_str.as_bytes();
+//! assert_eq!(bytes, b"foo");
+//! ```
#![unstable(feature = "sgx_platform", issue = "56975")]
-use crate::ffi::{OsStr, OsString};
-use crate::mem;
-use crate::sys::os_str::Buf;
-use crate::sys_common::{FromInner, IntoInner, AsInner};
-
-/// SGX-specific extensions to [`OsString`].
-///
-/// [`OsString`]: ../../../../std/ffi/struct.OsString.html
#[unstable(feature = "sgx_platform", issue = "56975")]
-pub trait OsStringExt {
- /// Creates an [`OsString`] from a byte vector.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::ffi::OsString;
- /// use std::os::unix::ffi::OsStringExt;
- ///
- /// let bytes = b"foo".to_vec();
- /// let os_string = OsString::from_vec(bytes);
- /// assert_eq!(os_string.to_str(), Some("foo"));
- /// ```
- ///
- /// [`OsString`]: ../../../ffi/struct.OsString.html
- #[unstable(feature = "sgx_platform", issue = "56975")]
- fn from_vec(vec: Vec<u8>) -> Self;
-
- /// Yields the underlying byte vector of this [`OsString`].
- ///
- /// # Examples
- ///
- /// ```
- /// use std::ffi::OsString;
- /// use std::os::unix::ffi::OsStringExt;
- ///
- /// let mut os_string = OsString::new();
- /// os_string.push("foo");
- /// let bytes = os_string.into_vec();
- /// assert_eq!(bytes, b"foo");
- /// ```
- ///
- /// [`OsString`]: ../../../ffi/struct.OsString.html
- #[unstable(feature = "sgx_platform", issue = "56975")]
- fn into_vec(self) -> Vec<u8>;
-}
-
-#[unstable(feature = "sgx_platform", issue = "56975")]
-impl OsStringExt for OsString {
- fn from_vec(vec: Vec<u8>) -> OsString {
- FromInner::from_inner(Buf { inner: vec })
- }
- fn into_vec(self) -> Vec<u8> {
- self.into_inner().inner
- }
-}
-
-/// SGX-specific extensions to [`OsStr`].
-///
-/// [`OsStr`]: ../../../../std/ffi/struct.OsStr.html
-#[unstable(feature = "sgx_platform", issue = "56975")]
-pub trait OsStrExt {
- #[unstable(feature = "sgx_platform", issue = "56975")]
- /// Creates an [`OsStr`] from a byte slice.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::ffi::OsStr;
- /// use std::os::unix::ffi::OsStrExt;
- ///
- /// let bytes = b"foo";
- /// let os_str = OsStr::from_bytes(bytes);
- /// assert_eq!(os_str.to_str(), Some("foo"));
- /// ```
- ///
- /// [`OsStr`]: ../../../ffi/struct.OsStr.html
- fn from_bytes(slice: &[u8]) -> &Self;
-
- /// Gets the underlying byte view of the [`OsStr`] slice.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::ffi::OsStr;
- /// use std::os::unix::ffi::OsStrExt;
- ///
- /// let mut os_str = OsStr::new("foo");
- /// let bytes = os_str.as_bytes();
- /// assert_eq!(bytes, b"foo");
- /// ```
- ///
- /// [`OsStr`]: ../../../ffi/struct.OsStr.html
- #[unstable(feature = "sgx_platform", issue = "56975")]
- fn as_bytes(&self) -> &[u8];
-}
-
-#[unstable(feature = "sgx_platform", issue = "56975")]
-impl OsStrExt for OsStr {
- fn from_bytes(slice: &[u8]) -> &OsStr {
- unsafe { mem::transmute(slice) }
- }
- fn as_bytes(&self) -> &[u8] {
- &self.as_inner().inner
- }
-}
+pub use crate::sys_common::os_str_bytes::*;
diff --git a/src/libstd/sys/sgx/mod.rs b/src/libstd/sys/sgx/mod.rs
index 325df76..dc51a93 100644
--- a/src/libstd/sys/sgx/mod.rs
+++ b/src/libstd/sys/sgx/mod.rs
@@ -25,7 +25,6 @@
pub mod mutex;
pub mod net;
pub mod os;
-pub mod os_str;
pub mod path;
pub mod pipe;
pub mod process;
@@ -36,6 +35,8 @@
pub mod time;
pub mod stdio;
+pub use crate::sys_common::os_str_bytes as os_str;
+
#[cfg(not(test))]
pub fn init() {
}
diff --git a/src/libstd/sys/sgx/net.rs b/src/libstd/sys/sgx/net.rs
index e5e42e3..81f33c1 100644
--- a/src/libstd/sys/sgx/net.rs
+++ b/src/libstd/sys/sgx/net.rs
@@ -103,24 +103,16 @@
self.inner.inner.read(buf)
}
- pub fn read_vectored(&self, buf: &mut [IoVecMut<'_>]) -> io::Result<usize> {
- let buf = match buf.get_mut(0) {
- Some(buf) => buf,
- None => return Ok(0),
- };
- self.read(buf)
+ pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
+ io::default_read_vectored(|b| self.read(b), bufs)
}
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
self.inner.inner.write(buf)
}
- pub fn write_vectored(&self, buf: &[IoVec<'_>]) -> io::Result<usize> {
- let buf = match buf.get(0) {
- Some(buf) => buf,
- None => return Ok(0),
- };
- self.write(buf)
+ pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
+ io::default_write_vectored(|b| self.write(b), bufs)
}
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
@@ -257,6 +249,10 @@
unsupported()
}
+ pub fn peer_addr(&self) -> io::Result<SocketAddr> {
+ match self.0 {}
+ }
+
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
match self.0 {}
}
diff --git a/src/libstd/sys/sgx/os_str.rs b/src/libstd/sys/sgx/os_str.rs
deleted file mode 100644
index 79b4345..0000000
--- a/src/libstd/sys/sgx/os_str.rs
+++ /dev/null
@@ -1,180 +0,0 @@
-/// The underlying OsString/OsStr implementation on Unix systems: just
-/// a `Vec<u8>`/`[u8]`.
-
-use crate::borrow::Cow;
-use crate::fmt;
-use crate::str;
-use crate::mem;
-use crate::rc::Rc;
-use crate::sync::Arc;
-use crate::sys_common::{AsInner, IntoInner};
-use crate::sys_common::bytestring::debug_fmt_bytestring;
-
-use core::str::lossy::Utf8Lossy;
-
-#[derive(Clone, Hash)]
-pub struct Buf {
- pub inner: Vec<u8>
-}
-
-pub struct Slice {
- pub inner: [u8]
-}
-
-impl fmt::Debug for Slice {
- fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- debug_fmt_bytestring(&self.inner, formatter)
- }
-}
-
-impl fmt::Display for Slice {
- fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- fmt::Display::fmt(&Utf8Lossy::from_bytes(&self.inner), formatter)
- }
-}
-
-impl fmt::Debug for Buf {
- fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- fmt::Debug::fmt(self.as_slice(), formatter)
- }
-}
-
-impl fmt::Display for Buf {
- fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- fmt::Display::fmt(self.as_slice(), formatter)
- }
-}
-
-impl IntoInner<Vec<u8>> for Buf {
- fn into_inner(self) -> Vec<u8> {
- self.inner
- }
-}
-
-impl AsInner<[u8]> for Buf {
- fn as_inner(&self) -> &[u8] {
- &self.inner
- }
-}
-
-
-impl Buf {
- pub fn from_string(s: String) -> Buf {
- Buf { inner: s.into_bytes() }
- }
-
- #[inline]
- pub fn with_capacity(capacity: usize) -> Buf {
- Buf {
- inner: Vec::with_capacity(capacity)
- }
- }
-
- #[inline]
- pub fn clear(&mut self) {
- self.inner.clear()
- }
-
- #[inline]
- pub fn capacity(&self) -> usize {
- self.inner.capacity()
- }
-
- #[inline]
- pub fn reserve(&mut self, additional: usize) {
- self.inner.reserve(additional)
- }
-
- #[inline]
- pub fn reserve_exact(&mut self, additional: usize) {
- self.inner.reserve_exact(additional)
- }
-
- #[inline]
- pub fn shrink_to_fit(&mut self) {
- self.inner.shrink_to_fit()
- }
-
- #[inline]
- pub fn shrink_to(&mut self, min_capacity: usize) {
- self.inner.shrink_to(min_capacity)
- }
-
- pub fn as_slice(&self) -> &Slice {
- unsafe { mem::transmute(&*self.inner) }
- }
-
- pub fn into_string(self) -> Result<String, Buf> {
- String::from_utf8(self.inner).map_err(|p| Buf { inner: p.into_bytes() } )
- }
-
- pub fn push_slice(&mut self, s: &Slice) {
- self.inner.extend_from_slice(&s.inner)
- }
-
- #[inline]
- pub fn into_box(self) -> Box<Slice> {
- unsafe { mem::transmute(self.inner.into_boxed_slice()) }
- }
-
- #[inline]
- pub fn from_box(boxed: Box<Slice>) -> Buf {
- let inner: Box<[u8]> = unsafe { mem::transmute(boxed) };
- Buf { inner: inner.into_vec() }
- }
-
- #[inline]
- pub fn into_arc(&self) -> Arc<Slice> {
- self.as_slice().into_arc()
- }
-
- #[inline]
- pub fn into_rc(&self) -> Rc<Slice> {
- self.as_slice().into_rc()
- }
-}
-
-impl Slice {
- fn from_u8_slice(s: &[u8]) -> &Slice {
- unsafe { mem::transmute(s) }
- }
-
- pub fn from_str(s: &str) -> &Slice {
- Slice::from_u8_slice(s.as_bytes())
- }
-
- pub fn to_str(&self) -> Option<&str> {
- str::from_utf8(&self.inner).ok()
- }
-
- pub fn to_string_lossy(&self) -> Cow<str> {
- String::from_utf8_lossy(&self.inner)
- }
-
- pub fn to_owned(&self) -> Buf {
- Buf { inner: self.inner.to_vec() }
- }
-
- #[inline]
- pub fn into_box(&self) -> Box<Slice> {
- let boxed: Box<[u8]> = self.inner.into();
- unsafe { mem::transmute(boxed) }
- }
-
- pub fn empty_box() -> Box<Slice> {
- let boxed: Box<[u8]> = Default::default();
- unsafe { mem::transmute(boxed) }
- }
-
- #[inline]
- pub fn into_arc(&self) -> Arc<Slice> {
- let arc: Arc<[u8]> = Arc::from(&self.inner);
- unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Slice) }
- }
-
- #[inline]
- pub fn into_rc(&self) -> Rc<Slice> {
- let rc: Rc<[u8]> = Rc::from(&self.inner);
- unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Slice) }
- }
-}
diff --git a/src/libstd/sys/unix/ext/ffi.rs b/src/libstd/sys/unix/ext/ffi.rs
index 0c02323..76b34a6 100644
--- a/src/libstd/sys/unix/ext/ffi.rs
+++ b/src/libstd/sys/unix/ext/ffi.rs
@@ -1,109 +1,38 @@
//! Unix-specific extension to the primitives in the `std::ffi` module
+//!
+//! # Examples
+//!
+//! ```
+//! use std::ffi::OsString;
+//! use std::os::unix::ffi::OsStringExt;
+//!
+//! let bytes = b"foo".to_vec();
+//!
+//! // OsStringExt::from_vec
+//! let os_string = OsString::from_vec(bytes);
+//! assert_eq!(os_string.to_str(), Some("foo"));
+//!
+//! // OsStringExt::into_vec
+//! let bytes = os_string.into_vec();
+//! assert_eq!(bytes, b"foo");
+//! ```
+//!
+//! ```
+//! use std::ffi::OsStr;
+//! use std::os::unix::ffi::OsStrExt;
+//!
+//! let bytes = b"foo";
+//!
+//! // OsStrExt::from_bytes
+//! let os_str = OsStr::from_bytes(bytes);
+//! assert_eq!(os_str.to_str(), Some("foo"));
+//!
+//! // OsStrExt::as_bytes
+//! let bytes = os_str.as_bytes();
+//! assert_eq!(bytes, b"foo");
+//! ```
#![stable(feature = "rust1", since = "1.0.0")]
-use crate::ffi::{OsStr, OsString};
-use crate::mem;
-use crate::sys::os_str::Buf;
-use crate::sys_common::{FromInner, IntoInner, AsInner};
-
-/// Unix-specific extensions to [`OsString`].
-///
-/// [`OsString`]: ../../../../std/ffi/struct.OsString.html
#[stable(feature = "rust1", since = "1.0.0")]
-pub trait OsStringExt {
- /// Creates an [`OsString`] from a byte vector.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::ffi::OsString;
- /// use std::os::unix::ffi::OsStringExt;
- ///
- /// let bytes = b"foo".to_vec();
- /// let os_string = OsString::from_vec(bytes);
- /// assert_eq!(os_string.to_str(), Some("foo"));
- /// ```
- ///
- /// [`OsString`]: ../../../ffi/struct.OsString.html
- #[stable(feature = "rust1", since = "1.0.0")]
- fn from_vec(vec: Vec<u8>) -> Self;
-
- /// Yields the underlying byte vector of this [`OsString`].
- ///
- /// # Examples
- ///
- /// ```
- /// use std::ffi::OsString;
- /// use std::os::unix::ffi::OsStringExt;
- ///
- /// let mut os_string = OsString::new();
- /// os_string.push("foo");
- /// let bytes = os_string.into_vec();
- /// assert_eq!(bytes, b"foo");
- /// ```
- ///
- /// [`OsString`]: ../../../ffi/struct.OsString.html
- #[stable(feature = "rust1", since = "1.0.0")]
- fn into_vec(self) -> Vec<u8>;
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl OsStringExt for OsString {
- fn from_vec(vec: Vec<u8>) -> OsString {
- FromInner::from_inner(Buf { inner: vec })
- }
- fn into_vec(self) -> Vec<u8> {
- self.into_inner().inner
- }
-}
-
-/// Unix-specific extensions to [`OsStr`].
-///
-/// [`OsStr`]: ../../../../std/ffi/struct.OsStr.html
-#[stable(feature = "rust1", since = "1.0.0")]
-pub trait OsStrExt {
- #[stable(feature = "rust1", since = "1.0.0")]
- /// Creates an [`OsStr`] from a byte slice.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::ffi::OsStr;
- /// use std::os::unix::ffi::OsStrExt;
- ///
- /// let bytes = b"foo";
- /// let os_str = OsStr::from_bytes(bytes);
- /// assert_eq!(os_str.to_str(), Some("foo"));
- /// ```
- ///
- /// [`OsStr`]: ../../../ffi/struct.OsStr.html
- fn from_bytes(slice: &[u8]) -> &Self;
-
- /// Gets the underlying byte view of the [`OsStr`] slice.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::ffi::OsStr;
- /// use std::os::unix::ffi::OsStrExt;
- ///
- /// let mut os_str = OsStr::new("foo");
- /// let bytes = os_str.as_bytes();
- /// assert_eq!(bytes, b"foo");
- /// ```
- ///
- /// [`OsStr`]: ../../../ffi/struct.OsStr.html
- #[stable(feature = "rust1", since = "1.0.0")]
- fn as_bytes(&self) -> &[u8];
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl OsStrExt for OsStr {
- fn from_bytes(slice: &[u8]) -> &OsStr {
- unsafe { mem::transmute(slice) }
- }
- fn as_bytes(&self) -> &[u8] {
- &self.as_inner().inner
- }
-}
+pub use crate::sys_common::os_str_bytes::*;
diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs
index 3b80b47..7ff098b 100644
--- a/src/libstd/sys/unix/fs.rs
+++ b/src/libstd/sys/unix/fs.rs
@@ -827,7 +827,10 @@
Ok(PathBuf::from(OsString::from_vec(buf)))
}
-#[cfg(not(any(target_os = "linux", target_os = "android")))]
+#[cfg(not(any(target_os = "linux",
+ target_os = "android",
+ target_os = "macos",
+ target_os = "ios")))]
pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
use crate::fs::File;
if !from.is_file() {
@@ -937,3 +940,85 @@
writer.set_permissions(perm)?;
Ok(written)
}
+
+#[cfg(any(target_os = "macos", target_os = "ios"))]
+pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
+ const COPYFILE_ACL: u32 = 1 << 0;
+ const COPYFILE_STAT: u32 = 1 << 1;
+ const COPYFILE_XATTR: u32 = 1 << 2;
+ const COPYFILE_DATA: u32 = 1 << 3;
+
+ const COPYFILE_SECURITY: u32 = COPYFILE_STAT | COPYFILE_ACL;
+ const COPYFILE_METADATA: u32 = COPYFILE_SECURITY | COPYFILE_XATTR;
+ const COPYFILE_ALL: u32 = COPYFILE_METADATA | COPYFILE_DATA;
+
+ const COPYFILE_STATE_COPIED: u32 = 8;
+
+ #[allow(non_camel_case_types)]
+ type copyfile_state_t = *mut libc::c_void;
+ #[allow(non_camel_case_types)]
+ type copyfile_flags_t = u32;
+
+ extern "C" {
+ fn copyfile(
+ from: *const libc::c_char,
+ to: *const libc::c_char,
+ state: copyfile_state_t,
+ flags: copyfile_flags_t,
+ ) -> libc::c_int;
+ fn copyfile_state_alloc() -> copyfile_state_t;
+ fn copyfile_state_free(state: copyfile_state_t) -> libc::c_int;
+ fn copyfile_state_get(
+ state: copyfile_state_t,
+ flag: u32,
+ dst: *mut libc::c_void,
+ ) -> libc::c_int;
+ }
+
+ struct FreeOnDrop(copyfile_state_t);
+ impl Drop for FreeOnDrop {
+ fn drop(&mut self) {
+ // The code below ensures that `FreeOnDrop` is never a null pointer
+ unsafe {
+ // `copyfile_state_free` returns -1 if the `to` or `from` files
+ // cannot be closed. However, this is not considerd this an
+ // error.
+ copyfile_state_free(self.0);
+ }
+ }
+ }
+
+ if !from.is_file() {
+ return Err(Error::new(ErrorKind::InvalidInput,
+ "the source path is not an existing regular file"))
+ }
+
+ // We ensure that `FreeOnDrop` never contains a null pointer so it is
+ // always safe to call `copyfile_state_free`
+ let state = unsafe {
+ let state = copyfile_state_alloc();
+ if state.is_null() {
+ return Err(crate::io::Error::last_os_error());
+ }
+ FreeOnDrop(state)
+ };
+
+ cvt(unsafe {
+ copyfile(
+ cstr(from)?.as_ptr(),
+ cstr(to)?.as_ptr(),
+ state.0,
+ COPYFILE_ALL,
+ )
+ })?;
+
+ let mut bytes_copied: libc::off_t = 0;
+ cvt(unsafe {
+ copyfile_state_get(
+ state.0,
+ COPYFILE_STATE_COPIED,
+ &mut bytes_copied as *mut libc::off_t as *mut libc::c_void,
+ )
+ })?;
+ Ok(bytes_copied as u64)
+}
diff --git a/src/libstd/sys/unix/l4re.rs b/src/libstd/sys/unix/l4re.rs
index b9e7253..b3dd1cf 100644
--- a/src/libstd/sys/unix/l4re.rs
+++ b/src/libstd/sys/unix/l4re.rs
@@ -292,6 +292,10 @@
pub fn into_socket(self) -> Socket { self.inner }
+ pub fn peer_addr(&self) -> io::Result<SocketAddr> {
+ unimpl!();
+ }
+
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
unimpl!();
}
@@ -463,4 +467,3 @@
}
}
}
-
diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs
index fbe3444..90e2644 100644
--- a/src/libstd/sys/unix/mod.rs
+++ b/src/libstd/sys/unix/mod.rs
@@ -47,7 +47,6 @@
#[cfg(target_os = "l4re")]
pub use self::l4re::net;
pub mod os;
-pub mod os_str;
pub mod path;
pub mod pipe;
pub mod process;
@@ -59,6 +58,8 @@
pub mod time;
pub mod stdio;
+pub use crate::sys_common::os_str_bytes as os_str;
+
#[cfg(not(test))]
pub fn init() {
// By default, some platforms will send a *signal* when an EPIPE error
diff --git a/src/libstd/sys/unix/os_str.rs b/src/libstd/sys/unix/os_str.rs
deleted file mode 100644
index 79b4345..0000000
--- a/src/libstd/sys/unix/os_str.rs
+++ /dev/null
@@ -1,180 +0,0 @@
-/// The underlying OsString/OsStr implementation on Unix systems: just
-/// a `Vec<u8>`/`[u8]`.
-
-use crate::borrow::Cow;
-use crate::fmt;
-use crate::str;
-use crate::mem;
-use crate::rc::Rc;
-use crate::sync::Arc;
-use crate::sys_common::{AsInner, IntoInner};
-use crate::sys_common::bytestring::debug_fmt_bytestring;
-
-use core::str::lossy::Utf8Lossy;
-
-#[derive(Clone, Hash)]
-pub struct Buf {
- pub inner: Vec<u8>
-}
-
-pub struct Slice {
- pub inner: [u8]
-}
-
-impl fmt::Debug for Slice {
- fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- debug_fmt_bytestring(&self.inner, formatter)
- }
-}
-
-impl fmt::Display for Slice {
- fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- fmt::Display::fmt(&Utf8Lossy::from_bytes(&self.inner), formatter)
- }
-}
-
-impl fmt::Debug for Buf {
- fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- fmt::Debug::fmt(self.as_slice(), formatter)
- }
-}
-
-impl fmt::Display for Buf {
- fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- fmt::Display::fmt(self.as_slice(), formatter)
- }
-}
-
-impl IntoInner<Vec<u8>> for Buf {
- fn into_inner(self) -> Vec<u8> {
- self.inner
- }
-}
-
-impl AsInner<[u8]> for Buf {
- fn as_inner(&self) -> &[u8] {
- &self.inner
- }
-}
-
-
-impl Buf {
- pub fn from_string(s: String) -> Buf {
- Buf { inner: s.into_bytes() }
- }
-
- #[inline]
- pub fn with_capacity(capacity: usize) -> Buf {
- Buf {
- inner: Vec::with_capacity(capacity)
- }
- }
-
- #[inline]
- pub fn clear(&mut self) {
- self.inner.clear()
- }
-
- #[inline]
- pub fn capacity(&self) -> usize {
- self.inner.capacity()
- }
-
- #[inline]
- pub fn reserve(&mut self, additional: usize) {
- self.inner.reserve(additional)
- }
-
- #[inline]
- pub fn reserve_exact(&mut self, additional: usize) {
- self.inner.reserve_exact(additional)
- }
-
- #[inline]
- pub fn shrink_to_fit(&mut self) {
- self.inner.shrink_to_fit()
- }
-
- #[inline]
- pub fn shrink_to(&mut self, min_capacity: usize) {
- self.inner.shrink_to(min_capacity)
- }
-
- pub fn as_slice(&self) -> &Slice {
- unsafe { mem::transmute(&*self.inner) }
- }
-
- pub fn into_string(self) -> Result<String, Buf> {
- String::from_utf8(self.inner).map_err(|p| Buf { inner: p.into_bytes() } )
- }
-
- pub fn push_slice(&mut self, s: &Slice) {
- self.inner.extend_from_slice(&s.inner)
- }
-
- #[inline]
- pub fn into_box(self) -> Box<Slice> {
- unsafe { mem::transmute(self.inner.into_boxed_slice()) }
- }
-
- #[inline]
- pub fn from_box(boxed: Box<Slice>) -> Buf {
- let inner: Box<[u8]> = unsafe { mem::transmute(boxed) };
- Buf { inner: inner.into_vec() }
- }
-
- #[inline]
- pub fn into_arc(&self) -> Arc<Slice> {
- self.as_slice().into_arc()
- }
-
- #[inline]
- pub fn into_rc(&self) -> Rc<Slice> {
- self.as_slice().into_rc()
- }
-}
-
-impl Slice {
- fn from_u8_slice(s: &[u8]) -> &Slice {
- unsafe { mem::transmute(s) }
- }
-
- pub fn from_str(s: &str) -> &Slice {
- Slice::from_u8_slice(s.as_bytes())
- }
-
- pub fn to_str(&self) -> Option<&str> {
- str::from_utf8(&self.inner).ok()
- }
-
- pub fn to_string_lossy(&self) -> Cow<str> {
- String::from_utf8_lossy(&self.inner)
- }
-
- pub fn to_owned(&self) -> Buf {
- Buf { inner: self.inner.to_vec() }
- }
-
- #[inline]
- pub fn into_box(&self) -> Box<Slice> {
- let boxed: Box<[u8]> = self.inner.into();
- unsafe { mem::transmute(boxed) }
- }
-
- pub fn empty_box() -> Box<Slice> {
- let boxed: Box<[u8]> = Default::default();
- unsafe { mem::transmute(boxed) }
- }
-
- #[inline]
- pub fn into_arc(&self) -> Arc<Slice> {
- let arc: Arc<[u8]> = Arc::from(&self.inner);
- unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Slice) }
- }
-
- #[inline]
- pub fn into_rc(&self) -> Rc<Slice> {
- let rc: Rc<[u8]> = Rc::from(&self.inner);
- unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Slice) }
- }
-}
diff --git a/src/libstd/sys/unix/stack_overflow.rs b/src/libstd/sys/unix/stack_overflow.rs
index 8c60bdd..561279e8 100644
--- a/src/libstd/sys/unix/stack_overflow.rs
+++ b/src/libstd/sys/unix/stack_overflow.rs
@@ -140,6 +140,7 @@
#[cfg(any(target_os = "linux",
target_os = "macos",
target_os = "bitrig",
+ target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
target_os = "solaris"))]
@@ -147,8 +148,7 @@
libc::stack_t { ss_sp: get_stackp(), ss_flags: 0, ss_size: SIGSTKSZ }
}
- #[cfg(any(target_os = "freebsd",
- target_os = "dragonfly"))]
+ #[cfg(target_os = "dragonfly")]
unsafe fn get_stack() -> libc::stack_t {
libc::stack_t { ss_sp: get_stackp() as *mut i8, ss_flags: 0, ss_size: SIGSTKSZ }
}
diff --git a/src/libstd/sys/wasm/alloc.rs b/src/libstd/sys/wasm/alloc.rs
index b909854..c1af6ec 100644
--- a/src/libstd/sys/wasm/alloc.rs
+++ b/src/libstd/sys/wasm/alloc.rs
@@ -49,7 +49,6 @@
#[cfg(target_feature = "atomics")]
mod lock {
- use crate::arch::wasm32;
use crate::sync::atomic::{AtomicI32, Ordering::SeqCst};
static LOCKED: AtomicI32 = AtomicI32::new(0);
@@ -61,14 +60,76 @@
if LOCKED.swap(1, SeqCst) == 0 {
return DropLock
}
- unsafe {
- let r = wasm32::i32_atomic_wait(
- &LOCKED as *const AtomicI32 as *mut i32,
- 1, // expected value
- -1, // timeout
- );
- debug_assert!(r == 0 || r == 1);
- }
+ // Ok so here's where things get a little depressing. At this point
+ // in time we need to synchronously acquire a lock, but we're
+ // contending with some other thread. Typically we'd execute some
+ // form of `i32.atomic.wait` like so:
+ //
+ // unsafe {
+ // let r = core::arch::wasm32::i32_atomic_wait(
+ // &LOCKED as *const AtomicI32 as *mut i32,
+ // 1, // expected value
+ // -1, // timeout
+ // );
+ // debug_assert!(r == 0 || r == 1);
+ // }
+ //
+ // Unfortunately though in doing so we would cause issues for the
+ // main thread. The main thread in a web browser *cannot ever
+ // block*, no exceptions. This means that the main thread can't
+ // actually execute the `i32.atomic.wait` instruction.
+ //
+ // As a result if we want to work within the context of browsers we
+ // need to figure out some sort of allocation scheme for the main
+ // thread where when there's contention on the global malloc lock we
+ // do... something.
+ //
+ // Possible ideas include:
+ //
+ // 1. Attempt to acquire the global lock. If it fails, fall back to
+ // memory allocation via `memory.grow`. Later just ... somehow
+ // ... inject this raw page back into the main allocator as it
+ // gets sliced up over time. This strategy has the downside of
+ // forcing allocation of a page to happen whenever the main
+ // thread contents with other threads, which is unfortunate.
+ //
+ // 2. Maintain a form of "two level" allocator scheme where the main
+ // thread has its own allocator. Somehow this allocator would
+ // also be balanced with a global allocator, not only to have
+ // allocations cross between threads but also to ensure that the
+ // two allocators stay "balanced" in terms of free'd memory and
+ // such. This, however, seems significantly complicated.
+ //
+ // Out of a lack of other ideas, the current strategy implemented
+ // here is to simply spin. Typical spin loop algorithms have some
+ // form of "hint" here to the CPU that it's what we're doing to
+ // ensure that the CPU doesn't get too hot, but wasm doesn't have
+ // such an instruction.
+ //
+ // To be clear, spinning here is not a great solution.
+ // Another thread with the lock may take quite a long time to wake
+ // up. For example it could be in `memory.grow` or it could be
+ // evicted from the CPU for a timeslice like 10ms. For these periods
+ // of time our thread will "helpfully" sit here and eat CPU time
+ // until it itself is evicted or the lock holder finishes. This
+ // means we're just burning and wasting CPU time to no one's
+ // benefit.
+ //
+ // Spinning does have the nice properties, though, of being
+ // semantically correct, being fair to all threads for memory
+ // allocation, and being simple enough to implement.
+ //
+ // This will surely (hopefully) be replaced in the future with a
+ // real memory allocator that can handle the restriction of the main
+ // thread.
+ //
+ //
+ // FIXME: We can also possibly add an optimization here to detect
+ // when a thread is the main thread or not and block on all
+ // non-main-thread threads. Currently, however, we have no way
+ // of knowing which wasm thread is on the browser main thread, but
+ // if we could figure out we could at least somewhat mitigate the
+ // cost of this spinning.
}
}
@@ -76,12 +137,16 @@
fn drop(&mut self) {
let r = LOCKED.swap(0, SeqCst);
debug_assert_eq!(r, 1);
- unsafe {
- wasm32::atomic_notify(
- &LOCKED as *const AtomicI32 as *mut i32,
- 1, // only one thread
- );
- }
+
+ // Note that due to the above logic we don't actually need to wake
+ // anyone up, but if we did it'd likely look something like this:
+ //
+ // unsafe {
+ // core::arch::wasm32::atomic_notify(
+ // &LOCKED as *const AtomicI32 as *mut i32,
+ // 1, // only one thread
+ // );
+ // }
}
}
}
diff --git a/src/libstd/sys/wasm/mod.rs b/src/libstd/sys/wasm/mod.rs
index 1828cce..670d07d 100644
--- a/src/libstd/sys/wasm/mod.rs
+++ b/src/libstd/sys/wasm/mod.rs
@@ -32,7 +32,6 @@
pub mod memchr;
pub mod net;
pub mod os;
-pub mod os_str;
pub mod path;
pub mod pipe;
pub mod process;
@@ -41,6 +40,8 @@
pub mod time;
pub mod stdio;
+pub use crate::sys_common::os_str_bytes as os_str;
+
cfg_if! {
if #[cfg(target_feature = "atomics")] {
#[path = "condvar_atomics.rs"]
diff --git a/src/libstd/sys/wasm/net.rs b/src/libstd/sys/wasm/net.rs
index a2ea2df..c85dd00 100644
--- a/src/libstd/sys/wasm/net.rs
+++ b/src/libstd/sys/wasm/net.rs
@@ -156,6 +156,10 @@
unsupported()
}
+ pub fn peer_addr(&self) -> io::Result<SocketAddr> {
+ match self.0 {}
+ }
+
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
match self.0 {}
}
diff --git a/src/libstd/sys/wasm/os_str.rs b/src/libstd/sys/wasm/os_str.rs
deleted file mode 100644
index 79b4345..0000000
--- a/src/libstd/sys/wasm/os_str.rs
+++ /dev/null
@@ -1,180 +0,0 @@
-/// The underlying OsString/OsStr implementation on Unix systems: just
-/// a `Vec<u8>`/`[u8]`.
-
-use crate::borrow::Cow;
-use crate::fmt;
-use crate::str;
-use crate::mem;
-use crate::rc::Rc;
-use crate::sync::Arc;
-use crate::sys_common::{AsInner, IntoInner};
-use crate::sys_common::bytestring::debug_fmt_bytestring;
-
-use core::str::lossy::Utf8Lossy;
-
-#[derive(Clone, Hash)]
-pub struct Buf {
- pub inner: Vec<u8>
-}
-
-pub struct Slice {
- pub inner: [u8]
-}
-
-impl fmt::Debug for Slice {
- fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- debug_fmt_bytestring(&self.inner, formatter)
- }
-}
-
-impl fmt::Display for Slice {
- fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- fmt::Display::fmt(&Utf8Lossy::from_bytes(&self.inner), formatter)
- }
-}
-
-impl fmt::Debug for Buf {
- fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- fmt::Debug::fmt(self.as_slice(), formatter)
- }
-}
-
-impl fmt::Display for Buf {
- fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- fmt::Display::fmt(self.as_slice(), formatter)
- }
-}
-
-impl IntoInner<Vec<u8>> for Buf {
- fn into_inner(self) -> Vec<u8> {
- self.inner
- }
-}
-
-impl AsInner<[u8]> for Buf {
- fn as_inner(&self) -> &[u8] {
- &self.inner
- }
-}
-
-
-impl Buf {
- pub fn from_string(s: String) -> Buf {
- Buf { inner: s.into_bytes() }
- }
-
- #[inline]
- pub fn with_capacity(capacity: usize) -> Buf {
- Buf {
- inner: Vec::with_capacity(capacity)
- }
- }
-
- #[inline]
- pub fn clear(&mut self) {
- self.inner.clear()
- }
-
- #[inline]
- pub fn capacity(&self) -> usize {
- self.inner.capacity()
- }
-
- #[inline]
- pub fn reserve(&mut self, additional: usize) {
- self.inner.reserve(additional)
- }
-
- #[inline]
- pub fn reserve_exact(&mut self, additional: usize) {
- self.inner.reserve_exact(additional)
- }
-
- #[inline]
- pub fn shrink_to_fit(&mut self) {
- self.inner.shrink_to_fit()
- }
-
- #[inline]
- pub fn shrink_to(&mut self, min_capacity: usize) {
- self.inner.shrink_to(min_capacity)
- }
-
- pub fn as_slice(&self) -> &Slice {
- unsafe { mem::transmute(&*self.inner) }
- }
-
- pub fn into_string(self) -> Result<String, Buf> {
- String::from_utf8(self.inner).map_err(|p| Buf { inner: p.into_bytes() } )
- }
-
- pub fn push_slice(&mut self, s: &Slice) {
- self.inner.extend_from_slice(&s.inner)
- }
-
- #[inline]
- pub fn into_box(self) -> Box<Slice> {
- unsafe { mem::transmute(self.inner.into_boxed_slice()) }
- }
-
- #[inline]
- pub fn from_box(boxed: Box<Slice>) -> Buf {
- let inner: Box<[u8]> = unsafe { mem::transmute(boxed) };
- Buf { inner: inner.into_vec() }
- }
-
- #[inline]
- pub fn into_arc(&self) -> Arc<Slice> {
- self.as_slice().into_arc()
- }
-
- #[inline]
- pub fn into_rc(&self) -> Rc<Slice> {
- self.as_slice().into_rc()
- }
-}
-
-impl Slice {
- fn from_u8_slice(s: &[u8]) -> &Slice {
- unsafe { mem::transmute(s) }
- }
-
- pub fn from_str(s: &str) -> &Slice {
- Slice::from_u8_slice(s.as_bytes())
- }
-
- pub fn to_str(&self) -> Option<&str> {
- str::from_utf8(&self.inner).ok()
- }
-
- pub fn to_string_lossy(&self) -> Cow<str> {
- String::from_utf8_lossy(&self.inner)
- }
-
- pub fn to_owned(&self) -> Buf {
- Buf { inner: self.inner.to_vec() }
- }
-
- #[inline]
- pub fn into_box(&self) -> Box<Slice> {
- let boxed: Box<[u8]> = self.inner.into();
- unsafe { mem::transmute(boxed) }
- }
-
- pub fn empty_box() -> Box<Slice> {
- let boxed: Box<[u8]> = Default::default();
- unsafe { mem::transmute(boxed) }
- }
-
- #[inline]
- pub fn into_arc(&self) -> Arc<Slice> {
- let arc: Arc<[u8]> = Arc::from(&self.inner);
- unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Slice) }
- }
-
- #[inline]
- pub fn into_rc(&self) -> Rc<Slice> {
- let rc: Rc<[u8]> = Rc::from(&self.inner);
- unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Slice) }
- }
-}
diff --git a/src/libstd/sys/windows/pipe.rs b/src/libstd/sys/windows/pipe.rs
index 07f4f5f..b387278 100644
--- a/src/libstd/sys/windows/pipe.rs
+++ b/src/libstd/sys/windows/pipe.rs
@@ -37,9 +37,9 @@
///
/// The ours/theirs pipes are *not* specifically readable or writable. Each
/// one only supports a read or a write, but which is which depends on the
-/// boolean flag given. If `ours_readable` is true then `ours` is readable where
-/// `theirs` is writable. Conversely if `ours_readable` is false then `ours` is
-/// writable where `theirs` is readable.
+/// boolean flag given. If `ours_readable` is `true`, then `ours` is readable and
+/// `theirs` is writable. Conversely, if `ours_readable` is `false`, then `ours`
+/// is writable and `theirs` is readable.
///
/// Also note that the `ours` pipe is always a handle opened up in overlapped
/// mode. This means that technically speaking it should only ever be used
diff --git a/src/libstd/sys_common/mod.rs b/src/libstd/sys_common/mod.rs
index 1fc3236..883ab34 100644
--- a/src/libstd/sys_common/mod.rs
+++ b/src/libstd/sys_common/mod.rs
@@ -35,6 +35,13 @@
pub mod condvar;
pub mod io;
pub mod mutex;
+#[cfg(any(rustdoc, // see `mod os`, docs are generated for multiple platforms
+ unix,
+ target_os = "redox",
+ target_os = "cloudabi",
+ target_arch = "wasm32",
+ all(target_vendor = "fortanix", target_env = "sgx")))]
+pub mod os_str_bytes;
pub mod poison;
pub mod remutex;
pub mod rwlock;
diff --git a/src/libstd/sys_common/net.rs b/src/libstd/sys_common/net.rs
index b9505aaa..b77bcee 100644
--- a/src/libstd/sys_common/net.rs
+++ b/src/libstd/sys_common/net.rs
@@ -472,6 +472,12 @@
pub fn into_socket(self) -> Socket { self.inner }
+ pub fn peer_addr(&self) -> io::Result<SocketAddr> {
+ sockname(|buf, len| unsafe {
+ c::getpeername(*self.inner.as_inner(), buf, len)
+ })
+ }
+
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
sockname(|buf, len| unsafe {
c::getsockname(*self.inner.as_inner(), buf, len)
diff --git a/src/libstd/sys/redox/os_str.rs b/src/libstd/sys_common/os_str_bytes.rs
similarity index 64%
rename from src/libstd/sys/redox/os_str.rs
rename to src/libstd/sys_common/os_str_bytes.rs
index 79b4345..5a9235a 100644
--- a/src/libstd/sys/redox/os_str.rs
+++ b/src/libstd/sys_common/os_str_bytes.rs
@@ -1,23 +1,24 @@
-/// The underlying OsString/OsStr implementation on Unix systems: just
-/// a `Vec<u8>`/`[u8]`.
+//! The underlying OsString/OsStr implementation on Unix and many other
+//! systems: just a `Vec<u8>`/`[u8]`.
use crate::borrow::Cow;
+use crate::ffi::{OsStr, OsString};
use crate::fmt;
use crate::str;
use crate::mem;
use crate::rc::Rc;
use crate::sync::Arc;
-use crate::sys_common::{AsInner, IntoInner};
+use crate::sys_common::{FromInner, IntoInner, AsInner};
use crate::sys_common::bytestring::debug_fmt_bytestring;
use core::str::lossy::Utf8Lossy;
#[derive(Clone, Hash)]
-pub struct Buf {
+pub(crate) struct Buf {
pub inner: Vec<u8>
}
-pub struct Slice {
+pub(crate) struct Slice {
pub inner: [u8]
}
@@ -178,3 +179,67 @@
unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Slice) }
}
}
+
+/// Platform-specific extensions to [`OsString`].
+///
+/// [`OsString`]: ../../../../std/ffi/struct.OsString.html
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait OsStringExt {
+ /// Creates an [`OsString`] from a byte vector.
+ ///
+ /// See the module docmentation for an example.
+ ///
+ /// [`OsString`]: ../../../ffi/struct.OsString.html
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn from_vec(vec: Vec<u8>) -> Self;
+
+ /// Yields the underlying byte vector of this [`OsString`].
+ ///
+ /// See the module docmentation for an example.
+ ///
+ /// [`OsString`]: ../../../ffi/struct.OsString.html
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn into_vec(self) -> Vec<u8>;
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl OsStringExt for OsString {
+ fn from_vec(vec: Vec<u8>) -> OsString {
+ FromInner::from_inner(Buf { inner: vec })
+ }
+ fn into_vec(self) -> Vec<u8> {
+ self.into_inner().inner
+ }
+}
+
+/// Platform-specific extensions to [`OsStr`].
+///
+/// [`OsStr`]: ../../../../std/ffi/struct.OsStr.html
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait OsStrExt {
+ #[stable(feature = "rust1", since = "1.0.0")]
+ /// Creates an [`OsStr`] from a byte slice.
+ ///
+ /// See the module docmentation for an example.
+ ///
+ /// [`OsStr`]: ../../../ffi/struct.OsStr.html
+ fn from_bytes(slice: &[u8]) -> &Self;
+
+ /// Gets the underlying byte view of the [`OsStr`] slice.
+ ///
+ /// See the module docmentation for an example.
+ ///
+ /// [`OsStr`]: ../../../ffi/struct.OsStr.html
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn as_bytes(&self) -> &[u8];
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl OsStrExt for OsStr {
+ fn from_bytes(slice: &[u8]) -> &OsStr {
+ unsafe { mem::transmute(slice) }
+ }
+ fn as_bytes(&self) -> &[u8] {
+ &self.as_inner().inner
+ }
+}
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
index 08f0aa2..d856f9b 100644
--- a/src/libstd/thread/mod.rs
+++ b/src/libstd/thread/mod.rs
@@ -163,6 +163,7 @@
use crate::fmt;
use crate::io;
use crate::mem;
+use crate::num::NonZeroU64;
use crate::panic;
use crate::panicking;
use crate::str;
@@ -1036,7 +1037,7 @@
/// [`Thread`]: ../../std/thread/struct.Thread.html
#[stable(feature = "thread_id", since = "1.19.0")]
#[derive(Eq, PartialEq, Clone, Copy, Hash, Debug)]
-pub struct ThreadId(u64);
+pub struct ThreadId(NonZeroU64);
impl ThreadId {
// Generate a new unique thread ID.
@@ -1044,7 +1045,7 @@
// We never call `GUARD.init()`, so it is UB to attempt to
// acquire this mutex reentrantly!
static GUARD: mutex::Mutex = mutex::Mutex::new();
- static mut COUNTER: u64 = 0;
+ static mut COUNTER: u64 = 1;
unsafe {
let _guard = GUARD.lock();
@@ -1058,7 +1059,7 @@
let id = COUNTER;
COUNTER += 1;
- ThreadId(id)
+ ThreadId(NonZeroU64::new(id).unwrap())
}
}
}
@@ -1484,9 +1485,10 @@
mod tests {
use super::Builder;
use crate::any::Any;
+ use crate::mem;
use crate::sync::mpsc::{channel, Sender};
use crate::result;
- use crate::thread;
+ use crate::thread::{self, ThreadId};
use crate::time::Duration;
use crate::u32;
@@ -1717,6 +1719,11 @@
}
#[test]
+ fn test_size_of_option_thread_id() {
+ assert_eq!(mem::size_of::<Option<ThreadId>>(), mem::size_of::<ThreadId>());
+ }
+
+ #[test]
fn test_thread_id_equal() {
assert!(thread::current().id() == thread::current().id());
}
diff --git a/src/libstd/time.rs b/src/libstd/time.rs
index 6d7093a..4c86f70 100644
--- a/src/libstd/time.rs
+++ b/src/libstd/time.rs
@@ -712,13 +712,6 @@
assert_almost_eq!(a - second + second, a);
assert_almost_eq!(a.checked_sub(second).unwrap().checked_add(second).unwrap(), a);
- // A difference of 80 and 800 years cannot fit inside a 32-bit time_t
- if !(cfg!(unix) && crate::mem::size_of::<libc::time_t>() <= 4) {
- let eighty_years = second * 60 * 60 * 24 * 365 * 80;
- assert_almost_eq!(a - eighty_years + eighty_years, a);
- assert_almost_eq!(a - (eighty_years * 10) + (eighty_years * 10), a);
- }
-
let one_second_from_epoch = UNIX_EPOCH + Duration::new(1, 0);
let one_second_from_epoch2 = UNIX_EPOCH + Duration::new(0, 500_000_000)
+ Duration::new(0, 500_000_000);
@@ -747,8 +740,8 @@
#[test]
fn since_epoch() {
let ts = SystemTime::now();
- let a = ts.duration_since(UNIX_EPOCH).unwrap();
- let b = ts.duration_since(UNIX_EPOCH - Duration::new(1, 0)).unwrap();
+ let a = ts.duration_since(UNIX_EPOCH + Duration::new(1, 0)).unwrap();
+ let b = ts.duration_since(UNIX_EPOCH).unwrap();
assert!(b > a);
assert_eq!(b - a, Duration::new(1, 0));
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index a01a5bb..2cbd2df 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -443,14 +443,11 @@
pub span: Span,
}
-/// A spanned compile-time attribute list item.
-pub type NestedMetaItem = Spanned<NestedMetaItemKind>;
-
/// Possible values inside of compile-time attribute lists.
///
/// E.g., the '..' in `#[name(..)]`.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
-pub enum NestedMetaItemKind {
+pub enum NestedMetaItem {
/// A full MetaItem, for recursive meta items.
MetaItem(MetaItem),
/// A literal.
@@ -464,7 +461,7 @@
/// E.g., `#[test]`, `#[derive(..)]`, `#[rustfmt::skip]` or `#[feature = "foo"]`.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct MetaItem {
- pub ident: Path,
+ pub path: Path,
pub node: MetaItemKind,
pub span: Span,
}
@@ -623,7 +620,7 @@
/// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`).
/// The `bool` is `true` in the presence of a `..`.
- Struct(Path, Vec<Spanned<FieldPat>>, bool),
+ Struct(Path, Vec<Spanned<FieldPat>>, /* recovered */ bool),
/// A tuple struct/variant pattern (`Variant(x, y, .., z)`).
/// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
@@ -2136,7 +2133,7 @@
/// Struct variant.
///
/// E.g., `Bar { .. }` as in `enum Foo { Bar { .. } }`.
- Struct(Vec<StructField>, NodeId),
+ Struct(Vec<StructField>, NodeId, bool),
/// Tuple variant.
///
/// E.g., `Bar(..)` as in `enum Foo { Bar(..) }`.
@@ -2150,13 +2147,13 @@
impl VariantData {
pub fn fields(&self) -> &[StructField] {
match *self {
- VariantData::Struct(ref fields, _) | VariantData::Tuple(ref fields, _) => fields,
+ VariantData::Struct(ref fields, ..) | VariantData::Tuple(ref fields, _) => fields,
_ => &[],
}
}
pub fn id(&self) -> NodeId {
match *self {
- VariantData::Struct(_, id) | VariantData::Tuple(_, id) | VariantData::Unit(id) => id,
+ VariantData::Struct(_, id, _) | VariantData::Tuple(_, id) | VariantData::Unit(id) => id,
}
}
pub fn is_struct(&self) -> bool {
@@ -2207,7 +2204,7 @@
impl Item {
/// Return the span that encompasses the attributes.
pub fn span_with_attributes(&self) -> Span {
- self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span()))
+ self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span))
}
}
diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs
index f7a0009..cdfb83c 100644
--- a/src/libsyntax/attr/builtin.rs
+++ b/src/libsyntax/attr/builtin.rs
@@ -1,6 +1,6 @@
//! Parsing and validation of builtin attributes
-use crate::ast::{self, Attribute, MetaItem, Name, NestedMetaItemKind};
+use crate::ast::{self, Attribute, MetaItem, NestedMetaItem};
use crate::feature_gate::{Features, GatedCfg};
use crate::parse::ParseSess;
@@ -10,8 +10,8 @@
use super::{mark_used, MetaItemKind};
enum AttrError {
- MultipleItem(Name),
- UnknownMetaItem(Name, &'static [&'static str]),
+ MultipleItem(String),
+ UnknownMetaItem(String, &'static [&'static str]),
MissingSince,
MissingFeature,
MultipleStabilityLevels,
@@ -155,10 +155,7 @@
attrs.iter().any(|item| {
item.check_name("feature") &&
item.meta_item_list().map(|list| {
- list.iter().any(|mi| {
- mi.word().map(|w| w.name() == feature_name)
- .unwrap_or(false)
- })
+ list.iter().any(|mi| mi.is_word() && mi.check_name(feature_name))
}).unwrap_or(false)
})
}
@@ -206,7 +203,7 @@
let meta = meta.as_ref().unwrap();
let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
if item.is_some() {
- handle_errors(sess, meta.span, AttrError::MultipleItem(meta.name()));
+ handle_errors(sess, meta.span, AttrError::MultipleItem(meta.path.to_string()));
return false
}
if let Some(v) = meta.value_str() {
@@ -225,9 +222,9 @@
)+
for meta in metas {
if let Some(mi) = meta.meta_item() {
- match &*mi.name().as_str() {
+ match mi.ident_str() {
$(
- stringify!($name)
+ Some(stringify!($name))
=> if !get(mi, &mut $name) { continue 'outer },
)+
_ => {
@@ -235,7 +232,7 @@
handle_errors(
sess,
mi.span,
- AttrError::UnknownMetaItem(mi.name(), expected),
+ AttrError::UnknownMetaItem(mi.path.to_string(), expected),
);
continue 'outer
}
@@ -243,7 +240,7 @@
} else {
handle_errors(
sess,
- meta.span,
+ meta.span(),
AttrError::UnsupportedLiteral(
"unsupported literal",
false,
@@ -255,7 +252,7 @@
}
}
- match &*meta.name().as_str() {
+ match meta.ident_str().expect("not a stability level") {
"rustc_deprecated" => {
if rustc_depr.is_some() {
span_err!(diagnostic, item_sp, E0540,
@@ -274,11 +271,11 @@
})
}
(None, _) => {
- handle_errors(sess, attr.span(), AttrError::MissingSince);
+ handle_errors(sess, attr.span, AttrError::MissingSince);
continue
}
_ => {
- span_err!(diagnostic, attr.span(), E0543, "missing 'reason'");
+ span_err!(diagnostic, attr.span, E0543, "missing 'reason'");
continue
}
}
@@ -294,13 +291,13 @@
if let Some(feature) = feature {
rustc_const_unstable = Some(feature);
} else {
- span_err!(diagnostic, attr.span(), E0629, "missing 'feature'");
+ span_err!(diagnostic, attr.span, E0629, "missing 'feature'");
continue
}
}
"unstable" => {
if stab.is_some() {
- handle_errors(sess, attr.span(), AttrError::MultipleStabilityLevels);
+ handle_errors(sess, attr.span, AttrError::MultipleStabilityLevels);
break
}
@@ -309,16 +306,16 @@
let mut issue = None;
for meta in metas {
if let Some(mi) = meta.meta_item() {
- match &*mi.name().as_str() {
- "feature" => if !get(mi, &mut feature) { continue 'outer },
- "reason" => if !get(mi, &mut reason) { continue 'outer },
- "issue" => if !get(mi, &mut issue) { continue 'outer },
+ match mi.ident_str() {
+ Some("feature") => if !get(mi, &mut feature) { continue 'outer },
+ Some("reason") => if !get(mi, &mut reason) { continue 'outer },
+ Some("issue") => if !get(mi, &mut issue) { continue 'outer },
_ => {
handle_errors(
sess,
- meta.span,
+ meta.span(),
AttrError::UnknownMetaItem(
- mi.name(),
+ mi.path.to_string(),
&["feature", "reason", "issue"]
),
);
@@ -328,7 +325,7 @@
} else {
handle_errors(
sess,
- meta.span,
+ meta.span(),
AttrError::UnsupportedLiteral(
"unsupported literal",
false,
@@ -347,7 +344,7 @@
if let Ok(issue) = issue.as_str().parse() {
issue
} else {
- span_err!(diagnostic, attr.span(), E0545,
+ span_err!(diagnostic, attr.span, E0545,
"incorrect 'issue'");
continue
}
@@ -360,42 +357,44 @@
})
}
(None, _, _) => {
- handle_errors(sess, attr.span(), AttrError::MissingFeature);
+ handle_errors(sess, attr.span, AttrError::MissingFeature);
continue
}
_ => {
- span_err!(diagnostic, attr.span(), E0547, "missing 'issue'");
+ span_err!(diagnostic, attr.span, E0547, "missing 'issue'");
continue
}
}
}
"stable" => {
if stab.is_some() {
- handle_errors(sess, attr.span(), AttrError::MultipleStabilityLevels);
+ handle_errors(sess, attr.span, AttrError::MultipleStabilityLevels);
break
}
let mut feature = None;
let mut since = None;
for meta in metas {
- match &meta.node {
- NestedMetaItemKind::MetaItem(mi) => {
- match &*mi.name().as_str() {
- "feature" => if !get(mi, &mut feature) { continue 'outer },
- "since" => if !get(mi, &mut since) { continue 'outer },
+ match meta {
+ NestedMetaItem::MetaItem(mi) => {
+ match mi.ident_str() {
+ Some("feature") =>
+ if !get(mi, &mut feature) { continue 'outer },
+ Some("since") =>
+ if !get(mi, &mut since) { continue 'outer },
_ => {
handle_errors(
sess,
- meta.span,
+ meta.span(),
AttrError::UnknownMetaItem(
- mi.name(), &["since", "note"],
+ mi.path.to_string(), &["since", "note"],
),
);
continue 'outer
}
}
},
- NestedMetaItemKind::Literal(lit) => {
+ NestedMetaItem::Literal(lit) => {
handle_errors(
sess,
lit.span,
@@ -422,11 +421,11 @@
})
}
(None, _) => {
- handle_errors(sess, attr.span(), AttrError::MissingFeature);
+ handle_errors(sess, attr.span, AttrError::MissingFeature);
continue
}
_ => {
- handle_errors(sess, attr.span(), AttrError::MissingSince);
+ handle_errors(sess, attr.span, AttrError::MissingSince);
continue
}
}
@@ -483,8 +482,8 @@
gated_cfg.check_and_emit(sess, feats);
}
let error = |span, msg| { sess.span_diagnostic.span_err(span, msg); true };
- if cfg.ident.segments.len() != 1 {
- return error(cfg.ident.span, "`cfg` predicate key must be an identifier");
+ if cfg.path.segments.len() != 1 {
+ return error(cfg.path.span, "`cfg` predicate key must be an identifier");
}
match &cfg.node {
MetaItemKind::List(..) => {
@@ -502,7 +501,8 @@
true
}
MetaItemKind::NameValue(..) | MetaItemKind::Word => {
- sess.config.contains(&(cfg.name(), cfg.value_str()))
+ let ident = cfg.ident().expect("multi-segment cfg predicate");
+ sess.config.contains(&(ident.name, cfg.value_str()))
}
}
})
@@ -520,7 +520,7 @@
if !mi.is_meta_item() {
handle_errors(
sess,
- mi.span,
+ mi.span(),
AttrError::UnsupportedLiteral(
"unsupported literal",
false
@@ -532,14 +532,14 @@
// The unwraps below may look dangerous, but we've already asserted
// that they won't fail with the loop above.
- match &*cfg.name().as_str() {
- "any" => mis.iter().any(|mi| {
+ match cfg.ident_str() {
+ Some("any") => mis.iter().any(|mi| {
eval_condition(mi.meta_item().unwrap(), sess, eval)
}),
- "all" => mis.iter().all(|mi| {
+ Some("all") => mis.iter().all(|mi| {
eval_condition(mi.meta_item().unwrap(), sess, eval)
}),
- "not" => {
+ Some("not") => {
if mis.len() != 1 {
span_err!(sess.span_diagnostic, cfg.span, E0536, "expected 1 cfg-pattern");
return false;
@@ -547,8 +547,9 @@
!eval_condition(mis[0].meta_item().unwrap(), sess, eval)
},
- p => {
- span_err!(sess.span_diagnostic, cfg.span, E0537, "invalid predicate `{}`", p);
+ _ => {
+ span_err!(sess.span_diagnostic, cfg.span, E0537,
+ "invalid predicate `{}`", cfg.path);
false
}
}
@@ -602,7 +603,9 @@
MetaItemKind::List(list) => {
let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
if item.is_some() {
- handle_errors(sess, meta.span, AttrError::MultipleItem(meta.name()));
+ handle_errors(
+ sess, meta.span, AttrError::MultipleItem(meta.path.to_string())
+ );
return false
}
if let Some(v) = meta.value_str() {
@@ -630,22 +633,23 @@
let mut since = None;
let mut note = None;
for meta in list {
- match &meta.node {
- NestedMetaItemKind::MetaItem(mi) => {
- match &*mi.name().as_str() {
- "since" => if !get(mi, &mut since) { continue 'outer },
- "note" => if !get(mi, &mut note) { continue 'outer },
+ match meta {
+ NestedMetaItem::MetaItem(mi) => {
+ match mi.ident_str() {
+ Some("since") => if !get(mi, &mut since) { continue 'outer },
+ Some("note") => if !get(mi, &mut note) { continue 'outer },
_ => {
handle_errors(
sess,
- meta.span,
- AttrError::UnknownMetaItem(mi.name(), &["since", "note"]),
+ meta.span(),
+ AttrError::UnknownMetaItem(mi.path.to_string(),
+ &["since", "note"]),
);
continue 'outer
}
}
}
- NestedMetaItemKind::Literal(lit) => {
+ NestedMetaItem::Literal(lit) => {
handle_errors(
sess,
lit.span,
@@ -714,7 +718,7 @@
if !item.is_meta_item() {
handle_errors(
sess,
- item.span,
+ item.span(),
AttrError::UnsupportedLiteral(
"meta item in `repr` must be an identifier",
false,
@@ -724,19 +728,13 @@
}
let mut recognised = false;
- if let Some(mi) = item.word() {
- let word = &*mi.name().as_str();
- let hint = match word {
- "C" => Some(ReprC),
- "packed" => Some(ReprPacked(1)),
- "simd" => Some(ReprSimd),
- "transparent" => Some(ReprTransparent),
- _ => match int_type_of_word(word) {
- Some(ity) => Some(ReprInt(ity)),
- None => {
- None
- }
- }
+ if item.is_word() {
+ let hint = match item.ident_str() {
+ Some("C") => Some(ReprC),
+ Some("packed") => Some(ReprPacked(1)),
+ Some("simd") => Some(ReprSimd),
+ Some("transparent") => Some(ReprTransparent),
+ name => name.and_then(|name| int_type_of_word(name)).map(ReprInt),
};
if let Some(h) = hint {
@@ -777,20 +775,20 @@
};
}
if let Some(literal_error) = literal_error {
- span_err!(diagnostic, item.span, E0589,
+ span_err!(diagnostic, item.span(), E0589,
"invalid `repr(align)` attribute: {}", literal_error);
}
} else {
if let Some(meta_item) = item.meta_item() {
- if meta_item.name() == "align" {
+ if meta_item.check_name("align") {
if let MetaItemKind::NameValue(ref value) = meta_item.node {
recognised = true;
- let mut err = struct_span_err!(diagnostic, item.span, E0693,
+ let mut err = struct_span_err!(diagnostic, item.span(), E0693,
"incorrect `repr(align)` attribute format");
match value.node {
ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => {
err.span_suggestion(
- item.span,
+ item.span(),
"use parentheses instead",
format!("align({})", int),
Applicability::MachineApplicable
@@ -798,7 +796,7 @@
}
ast::LitKind::Str(s, _) => {
err.span_suggestion(
- item.span,
+ item.span(),
"use parentheses instead",
format!("align({})", s),
Applicability::MachineApplicable
@@ -813,7 +811,7 @@
}
if !recognised {
// Not a word we recognize
- span_err!(diagnostic, item.span, E0552,
+ span_err!(diagnostic, item.span(), E0552,
"unrecognized representation hint");
}
}
diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs
index b5fc850..1a8faa4 100644
--- a/src/libsyntax/attr/mod.rs
+++ b/src/libsyntax/attr/mod.rs
@@ -13,7 +13,7 @@
use crate::ast;
use crate::ast::{AttrId, Attribute, AttrStyle, Name, Ident, Path, PathSegment};
-use crate::ast::{MetaItem, MetaItemKind, NestedMetaItem, NestedMetaItemKind};
+use crate::ast::{MetaItem, MetaItemKind, NestedMetaItem};
use crate::ast::{Lit, LitKind, Expr, ExprKind, Item, Local, Stmt, StmtKind, GenericParam};
use crate::mut_visit::visit_clobber;
use crate::source_map::{BytePos, Spanned, respan, dummy_spanned};
@@ -64,36 +64,33 @@
}
impl NestedMetaItem {
- /// Returns the MetaItem if self is a NestedMetaItemKind::MetaItem.
+ /// Returns the MetaItem if self is a NestedMetaItem::MetaItem.
pub fn meta_item(&self) -> Option<&MetaItem> {
- match self.node {
- NestedMetaItemKind::MetaItem(ref item) => Some(item),
+ match *self {
+ NestedMetaItem::MetaItem(ref item) => Some(item),
_ => None
}
}
- /// Returns the Lit if self is a NestedMetaItemKind::Literal.
+ /// Returns the Lit if self is a NestedMetaItem::Literal.
pub fn literal(&self) -> Option<&Lit> {
- match self.node {
- NestedMetaItemKind::Literal(ref lit) => Some(lit),
+ match *self {
+ NestedMetaItem::Literal(ref lit) => Some(lit),
_ => None
}
}
- /// Returns the Span for `self`.
- pub fn span(&self) -> Span {
- self.span
- }
-
/// Returns `true` if this list item is a MetaItem with a name of `name`.
pub fn check_name(&self, name: &str) -> bool {
self.meta_item().map_or(false, |meta_item| meta_item.check_name(name))
}
- /// Returns the name of the meta item, e.g., `foo` in `#[foo]`,
- /// `#[foo="bar"]` and `#[foo(bar)]`, if self is a MetaItem
- pub fn name(&self) -> Option<Name> {
- self.meta_item().and_then(|meta_item| Some(meta_item.name()))
+ /// For a single-segment meta-item returns its name, otherwise returns `None`.
+ pub fn ident(&self) -> Option<Ident> {
+ self.meta_item().and_then(|meta_item| meta_item.ident())
+ }
+ pub fn ident_str(&self) -> Option<&str> {
+ self.ident().map(|name| name.as_str().get())
}
/// Gets the string value if self is a MetaItem and the MetaItem is a
@@ -108,25 +105,14 @@
|meta_item| meta_item.meta_item_list().and_then(
|meta_item_list| {
if meta_item_list.len() == 1 {
- let nested_item = &meta_item_list[0];
- if nested_item.is_literal() {
- Some((meta_item.name(), nested_item.literal().unwrap()))
- } else {
- None
+ if let Some(ident) = meta_item.ident() {
+ if let Some(lit) = meta_item_list[0].literal() {
+ return Some((ident.name, lit));
+ }
}
}
- else {
- None
- }}))
- }
-
- /// Returns a MetaItem if self is a MetaItem with Kind Word.
- pub fn word(&self) -> Option<&MetaItem> {
- self.meta_item().and_then(|meta_item| if meta_item.is_word() {
- Some(meta_item)
- } else {
- None
- })
+ None
+ }))
}
/// Gets a list of inner meta items from a list MetaItem type.
@@ -146,7 +132,7 @@
/// Returns `true` if self is a MetaItem and the meta item is a word.
pub fn is_word(&self) -> bool {
- self.word().is_some()
+ self.meta_item().map_or(false, |meta_item| meta_item.is_word())
}
/// Returns `true` if self is a MetaItem and the meta item is a ValueString.
@@ -160,10 +146,6 @@
}
}
-fn name_from_path(path: &Path) -> Name {
- path.segments.last().expect("empty path in attribute").ident.name
-}
-
impl Attribute {
/// Returns `true` if the attribute's path matches the argument. If it matches, then the
/// attribute is marked as used.
@@ -177,10 +159,16 @@
matches
}
- /// Returns the **last** segment of the name of this attribute.
- /// e.g., `foo` for `#[foo]`, `skip` for `#[rustfmt::skip]`.
- pub fn name(&self) -> Name {
- name_from_path(&self.path)
+ /// For a single-segment attribute returns its name, otherwise returns `None`.
+ pub fn ident(&self) -> Option<Ident> {
+ if self.path.segments.len() == 1 {
+ Some(self.path.segments[0].ident)
+ } else {
+ None
+ }
+ }
+ pub fn ident_str(&self) -> Option<&str> {
+ self.ident().map(|name| name.as_str().get())
}
pub fn value_str(&self) -> Option<Symbol> {
@@ -195,11 +183,7 @@
}
pub fn is_word(&self) -> bool {
- self.path.segments.len() == 1 && self.tokens.is_empty()
- }
-
- pub fn span(&self) -> Span {
- self.span
+ self.tokens.is_empty()
}
pub fn is_meta_item_list(&self) -> bool {
@@ -213,8 +197,16 @@
}
impl MetaItem {
- pub fn name(&self) -> Name {
- name_from_path(&self.ident)
+ /// For a single-segment meta-item returns its name, otherwise returns `None`.
+ pub fn ident(&self) -> Option<Ident> {
+ if self.path.segments.len() == 1 {
+ Some(self.path.segments[0].ident)
+ } else {
+ None
+ }
+ }
+ pub fn ident_str(&self) -> Option<&str> {
+ self.ident().map(|name| name.as_str().get())
}
// #[attribute(name = "value")]
@@ -252,10 +244,8 @@
}
}
- pub fn span(&self) -> Span { self.span }
-
pub fn check_name(&self, name: &str) -> bool {
- self.name() == name
+ self.path == name
}
pub fn is_value_str(&self) -> bool {
@@ -265,14 +255,6 @@
pub fn is_meta_item_list(&self) -> bool {
self.meta_item_list().is_some()
}
-
- pub fn is_scoped(&self) -> Option<Ident> {
- if self.ident.segments.len() > 1 {
- Some(self.ident.segments[0].ident)
- } else {
- None
- }
- }
}
impl Attribute {
@@ -280,7 +262,7 @@
pub fn meta(&self) -> Option<MetaItem> {
let mut tokens = self.tokens.trees().peekable();
Some(MetaItem {
- ident: self.path.clone(),
+ path: self.path.clone(),
node: if let Some(node) = MetaItemKind::from_tokens(&mut tokens) {
if tokens.peek().is_some() {
return None;
@@ -326,7 +308,7 @@
pub fn parse_meta<'a>(&self, sess: &'a ParseSess) -> PResult<'a, MetaItem> {
Ok(MetaItem {
- ident: self.path.clone(),
+ path: self.path.clone(),
node: self.parse(sess, |parser| parser.parse_meta_item_kind())?,
span: self.span,
})
@@ -364,19 +346,19 @@
}
pub fn mk_name_value_item(span: Span, ident: Ident, value: ast::Lit) -> MetaItem {
- MetaItem { ident: Path::from_ident(ident), span, node: MetaItemKind::NameValue(value) }
+ MetaItem { path: Path::from_ident(ident), span, node: MetaItemKind::NameValue(value) }
}
pub fn mk_list_item(span: Span, ident: Ident, items: Vec<NestedMetaItem>) -> MetaItem {
- MetaItem { ident: Path::from_ident(ident), span, node: MetaItemKind::List(items) }
+ MetaItem { path: Path::from_ident(ident), span, node: MetaItemKind::List(items) }
}
pub fn mk_word_item(ident: Ident) -> MetaItem {
- MetaItem { ident: Path::from_ident(ident), span: ident.span, node: MetaItemKind::Word }
+ MetaItem { path: Path::from_ident(ident), span: ident.span, node: MetaItemKind::Word }
}
pub fn mk_nested_word_item(ident: Ident) -> NestedMetaItem {
- respan(ident.span, NestedMetaItemKind::MetaItem(mk_word_item(ident)))
+ NestedMetaItem::MetaItem(mk_word_item(ident))
}
pub fn mk_attr_id() -> AttrId {
@@ -400,7 +382,7 @@
Attribute {
id,
style: ast::AttrStyle::Inner,
- path: item.ident,
+ path: item.path,
tokens: item.node.tokens(item.span),
is_sugared_doc: false,
span: sp,
@@ -417,7 +399,7 @@
Attribute {
id,
style: ast::AttrStyle::Outer,
- path: item.ident,
+ path: item.path,
tokens: item.node.tokens(item.span),
is_sugared_doc: false,
span: sp,
@@ -468,7 +450,7 @@
fn tokens(&self) -> TokenStream {
let mut idents = vec![];
let mut last_pos = BytePos(0 as u32);
- for (i, segment) in self.ident.segments.iter().enumerate() {
+ for (i, segment) in self.path.segments.iter().enumerate() {
let is_first = i == 0;
if !is_first {
let mod_sep_span = Span::new(last_pos,
@@ -488,7 +470,7 @@
where I: Iterator<Item = TokenTree>,
{
// FIXME: Share code with `parse_path`.
- let ident = match tokens.next() {
+ let path = match tokens.next() {
Some(TokenTree::Token(span, token @ Token::Ident(..))) |
Some(TokenTree::Token(span, token @ Token::ModSep)) => 'arm: {
let mut segments = if let Token::Ident(ident, _) = token {
@@ -529,11 +511,11 @@
let node = MetaItemKind::from_tokens(tokens)?;
let hi = match node {
MetaItemKind::NameValue(ref lit) => lit.span.hi(),
- MetaItemKind::List(..) => list_closing_paren_pos.unwrap_or(ident.span.hi()),
- _ => ident.span.hi(),
+ MetaItemKind::List(..) => list_closing_paren_pos.unwrap_or(path.span.hi()),
+ _ => path.span.hi(),
};
- let span = ident.span.with_hi(hi);
- Some(MetaItem { ident, node, span })
+ let span = path.span.with_hi(hi);
+ Some(MetaItem { path, node, span })
}
}
@@ -552,7 +534,7 @@
if i > 0 {
tokens.push(TokenTree::Token(span, Token::Comma).into());
}
- item.node.tokens().append_to_tree_and_joint_vec(&mut tokens);
+ item.tokens().append_to_tree_and_joint_vec(&mut tokens);
}
TokenTree::Delimited(
DelimSpan::from_single(span),
@@ -586,8 +568,8 @@
let mut tokens = delimited.into_trees().peekable();
let mut result = Vec::new();
while let Some(..) = tokens.peek() {
- let item = NestedMetaItemKind::from_tokens(&mut tokens)?;
- result.push(respan(item.span(), item));
+ let item = NestedMetaItem::from_tokens(&mut tokens)?;
+ result.push(item);
match tokens.next() {
None | Some(TokenTree::Token(_, Token::Comma)) => {}
_ => return None,
@@ -597,32 +579,32 @@
}
}
-impl NestedMetaItemKind {
- fn span(&self) -> Span {
+impl NestedMetaItem {
+ pub fn span(&self) -> Span {
match *self {
- NestedMetaItemKind::MetaItem(ref item) => item.span,
- NestedMetaItemKind::Literal(ref lit) => lit.span,
+ NestedMetaItem::MetaItem(ref item) => item.span,
+ NestedMetaItem::Literal(ref lit) => lit.span,
}
}
fn tokens(&self) -> TokenStream {
match *self {
- NestedMetaItemKind::MetaItem(ref item) => item.tokens(),
- NestedMetaItemKind::Literal(ref lit) => lit.tokens(),
+ NestedMetaItem::MetaItem(ref item) => item.tokens(),
+ NestedMetaItem::Literal(ref lit) => lit.tokens(),
}
}
- fn from_tokens<I>(tokens: &mut iter::Peekable<I>) -> Option<NestedMetaItemKind>
+ fn from_tokens<I>(tokens: &mut iter::Peekable<I>) -> Option<NestedMetaItem>
where I: Iterator<Item = TokenTree>,
{
if let Some(TokenTree::Token(span, token)) = tokens.peek().cloned() {
if let Some(node) = LitKind::from_token(token) {
tokens.next();
- return Some(NestedMetaItemKind::Literal(respan(span, node)));
+ return Some(NestedMetaItem::Literal(respan(span, node)));
}
}
- MetaItem::from_tokens(tokens).map(NestedMetaItemKind::MetaItem)
+ MetaItem::from_tokens(tokens).map(NestedMetaItem::MetaItem)
}
}
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs
index 4e4432a..7159c94 100644
--- a/src/libsyntax/config.rs
+++ b/src/libsyntax/config.rs
@@ -24,8 +24,8 @@
}
// `cfg_attr`-process the crate's attributes and compute the crate's features.
-pub fn features(mut krate: ast::Crate, sess: &ParseSess, edition: Edition)
- -> (ast::Crate, Features) {
+pub fn features(mut krate: ast::Crate, sess: &ParseSess, edition: Edition,
+ allow_features: &Option<Vec<String>>) -> (ast::Crate, Features) {
let features;
{
let mut strip_unconfigured = StripUnconfigured {
@@ -43,7 +43,7 @@
return (krate, Features::new());
}
- features = get_features(&sess.span_diagnostic, &krate.attrs, edition);
+ features = get_features(&sess.span_diagnostic, &krate.attrs, edition, allow_features);
// Avoid reconfiguring malformed `cfg_attr`s
if err_count == sess.span_diagnostic.err_count() {
@@ -181,13 +181,13 @@
if nested_meta_items.is_empty() {
return error(meta_item.span, "`cfg` predicate is not specified", "");
} else if nested_meta_items.len() > 1 {
- return error(nested_meta_items.last().unwrap().span,
+ return error(nested_meta_items.last().unwrap().span(),
"multiple `cfg` predicates are specified", "");
}
match nested_meta_items[0].meta_item() {
Some(meta_item) => attr::cfg_matches(meta_item, self.sess, self.features),
- None => error(nested_meta_items[0].span,
+ None => error(nested_meta_items[0].span(),
"`cfg` predicate key cannot be a literal", ""),
}
})
@@ -225,7 +225,7 @@
fn configure_variant_data(&mut self, vdata: &mut ast::VariantData) {
match vdata {
- ast::VariantData::Struct(fields, _id) |
+ ast::VariantData::Struct(fields, _id, _) |
ast::VariantData::Tuple(fields, _id) =>
fields.flat_map_in_place(|field| self.configure(field)),
ast::VariantData::Unit(_id) => {}
diff --git a/src/libsyntax/diagnostic_list.rs b/src/libsyntax/diagnostic_list.rs
index 2c367f1..ac24475 100644
--- a/src/libsyntax/diagnostic_list.rs
+++ b/src/libsyntax/diagnostic_list.rs
@@ -378,6 +378,21 @@
"##,
+E0725: r##"
+A feature attribute named a feature that was disallowed in the compiler
+command line flags.
+
+Erroneous code example:
+
+```ignore (can't specify compiler flags from doctests)
+#![feature(never_type)] // error: the feature `never_type` is not in
+ // the list of allowed features
+```
+
+Delete the offending feature attribute, or add it to the list of allowed
+features in the `-Z allow_features` flag.
+"##,
+
}
register_diagnostics! {
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index b805213..8235867 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -601,7 +601,7 @@
res
}
ProcMacroDerive(..) | BuiltinDerive(..) => {
- self.cx.span_err(attr.span, &format!("`{}` is a derive mode", attr.path));
+ self.cx.span_err(attr.span, &format!("`{}` is a derive macro", attr.path));
self.cx.trace_macros_diag();
invoc.fragment_kind.dummy(attr.span)
}
@@ -822,7 +822,7 @@
}
ProcMacroDerive(..) | BuiltinDerive(..) => {
- self.cx.span_err(path.span, &format!("`{}` is a derive mode", path));
+ self.cx.span_err(path.span, &format!("`{}` is a derive macro", path));
self.cx.trace_macros_diag();
kind.dummy(span)
}
@@ -929,7 +929,7 @@
invoc.expansion_data.mark.set_expn_info(expn_info);
let span = span.with_ctxt(self.cx.backtrace());
let dummy = ast::MetaItem { // FIXME(jseyfried) avoid this
- ident: Path::from_ident(keywords::Invalid.ident()),
+ path: Path::from_ident(keywords::Invalid.ident()),
span: DUMMY_SP,
node: ast::MetaItemKind::Word,
};
@@ -1520,23 +1520,23 @@
self.cx.source_map().new_source_file(filename.into(), src);
let include_info = vec![
- dummy_spanned(ast::NestedMetaItemKind::MetaItem(
+ ast::NestedMetaItem::MetaItem(
attr::mk_name_value_item_str(
Ident::from_str("file"),
dummy_spanned(file),
),
- )),
- dummy_spanned(ast::NestedMetaItemKind::MetaItem(
+ ),
+ ast::NestedMetaItem::MetaItem(
attr::mk_name_value_item_str(
Ident::from_str("contents"),
dummy_spanned(src_interned),
),
- )),
+ ),
];
let include_ident = Ident::from_str("include");
let item = attr::mk_list_item(DUMMY_SP, include_ident, include_info);
- items.push(dummy_spanned(ast::NestedMetaItemKind::MetaItem(item)));
+ items.push(ast::NestedMetaItem::MetaItem(item));
}
Err(e) => {
let lit = it
@@ -1569,7 +1569,7 @@
}
} else {
let mut err = self.cx.struct_span_err(
- it.span,
+ it.span(),
&format!("expected path to external documentation"),
);
@@ -1590,7 +1590,7 @@
};
err.span_suggestion(
- it.span,
+ it.span(),
"provide a file path with `=`",
format!("include = \"{}\"", path),
applicability,
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index bd64bb0..1291204 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -380,9 +380,14 @@
.map(|attr| attr
.meta_item_list()
.map(|list| list.iter()
- .map(|it| it.name().unwrap_or_else(|| sess.span_diagnostic.span_bug(
- it.span, "allow internal unstable expects feature names",
- )))
+ .filter_map(|it| {
+ let name = it.ident().map(|ident| ident.name);
+ if name.is_none() {
+ sess.span_diagnostic.span_err(it.span(),
+ "allow internal unstable expects feature names")
+ }
+ name
+ })
.collect::<Vec<Symbol>>().into()
)
.unwrap_or_else(|| {
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index b298262..9beaabb 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -1289,9 +1289,8 @@
impl GatedCfg {
pub fn gate(cfg: &ast::MetaItem) -> Option<GatedCfg> {
- let name = cfg.name().as_str();
GATED_CFGS.iter()
- .position(|info| info.0 == name)
+ .position(|info| cfg.check_name(info.0))
.map(|idx| {
GatedCfg {
span: cfg.span,
@@ -1342,16 +1341,16 @@
impl<'a> Context<'a> {
fn check_attribute(&self, attr: &ast::Attribute, is_macro: bool) {
debug!("check_attribute(attr = {:?})", attr);
- let name = attr.name().as_str();
+ let name = attr.ident_str();
for &(n, ty, _template, ref gateage) in BUILTIN_ATTRIBUTES {
- if name == n {
+ if name == Some(n) {
if let Gated(_, name, desc, ref has_feature) = *gateage {
if !attr.span.allows_unstable(name) {
gate_feature_fn!(
self, has_feature, attr.span, name, desc, GateStrength::Hard
);
}
- } else if name == "doc" {
+ } else if n == "doc" {
if let Some(content) = attr.meta_item_list() {
if content.iter().any(|c| c.check_name("include")) {
gate_feature!(self, external_doc, attr.span,
@@ -1374,7 +1373,7 @@
}
}
if !attr::is_known(attr) {
- if name.starts_with("rustc_") {
+ if name.map_or(false, |name| name.starts_with("rustc_")) {
let msg = "unless otherwise specified, attributes with the prefix `rustc_` \
are reserved for internal compiler diagnostics";
gate_feature!(self, rustc_attrs, attr.span, msg);
@@ -2008,7 +2007,7 @@
}
pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
- crate_edition: Edition) -> Features {
+ crate_edition: Edition, allow_features: &Option<Vec<String>>) -> Features {
fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
let mut err = struct_span_err!(span_handler, span, E0557, "feature has been removed");
if let Some(reason) = reason {
@@ -2055,15 +2054,14 @@
};
for mi in list {
- let name = if let Some(word) = mi.word() {
- word.name()
- } else {
- continue
+ let name = match mi.ident_str() {
+ Some(name) if mi.is_word() => name,
+ _ => continue,
};
- if incomplete_features.iter().any(|f| *f == name.as_str()) {
+ if incomplete_features.iter().any(|f| *f == name) {
span_handler.struct_span_warn(
- mi.span,
+ mi.span(),
&format!(
"the feature `{}` is incomplete and may cause the compiler to crash",
name
@@ -2101,18 +2099,19 @@
};
for mi in list {
- let name = if let Some(word) = mi.word() {
- word.name()
- } else {
- span_err!(span_handler, mi.span, E0556,
- "malformed feature, expected just one word");
- continue
+ let name = match mi.ident() {
+ Some(ident) if mi.is_word() => ident.name,
+ _ => {
+ span_err!(span_handler, mi.span(), E0556,
+ "malformed feature, expected just one word");
+ continue
+ }
};
if let Some(edition) = edition_enabled_features.get(&name) {
struct_span_warn!(
span_handler,
- mi.span,
+ mi.span(),
E0705,
"the feature `{}` is included in the Rust {} edition",
name,
@@ -2127,25 +2126,34 @@
}
if let Some((.., set)) = ACTIVE_FEATURES.iter().find(|f| name == f.0) {
- set(&mut features, mi.span);
- features.declared_lang_features.push((name, mi.span, None));
+ if let Some(allowed) = allow_features.as_ref() {
+ if allowed.iter().find(|f| *f == name.as_str()).is_none() {
+ span_err!(span_handler, mi.span(), E0725,
+ "the feature `{}` is not in the list of allowed features",
+ name);
+ continue;
+ }
+ }
+
+ set(&mut features, mi.span());
+ features.declared_lang_features.push((name, mi.span(), None));
continue
}
let removed = REMOVED_FEATURES.iter().find(|f| name == f.0);
let stable_removed = STABLE_REMOVED_FEATURES.iter().find(|f| name == f.0);
if let Some((.., reason)) = removed.or(stable_removed) {
- feature_removed(span_handler, mi.span, *reason);
+ feature_removed(span_handler, mi.span(), *reason);
continue
}
if let Some((_, since, ..)) = ACCEPTED_FEATURES.iter().find(|f| name == f.0) {
let since = Some(Symbol::intern(since));
- features.declared_lang_features.push((name, mi.span, since));
+ features.declared_lang_features.push((name, mi.span(), since));
continue
}
- features.declared_lib_features.push((name, mi.span));
+ features.declared_lib_features.push((name, mi.span()));
}
}
diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs
index 802b780..5bb1d8a 100644
--- a/src/libsyntax/mut_visit.rs
+++ b/src/libsyntax/mut_visit.rs
@@ -539,16 +539,14 @@
}
pub fn noop_visit_meta_list_item<T: MutVisitor>(li: &mut NestedMetaItem, vis: &mut T) {
- let Spanned { node, span } = li;
- match node {
- NestedMetaItemKind::MetaItem(mi) => vis.visit_meta_item(mi),
- NestedMetaItemKind::Literal(_lit) => {}
+ match li {
+ NestedMetaItem::MetaItem(mi) => vis.visit_meta_item(mi),
+ NestedMetaItem::Literal(_lit) => {}
}
- vis.visit_span(span);
}
pub fn noop_visit_meta_item<T: MutVisitor>(mi: &mut MetaItem, vis: &mut T) {
- let MetaItem { ident: _, node, span } = mi;
+ let MetaItem { path: _, node, span } = mi;
match node {
MetaItemKind::Word => {}
MetaItemKind::List(mis) => visit_vec(mis, |mi| vis.visit_meta_list_item(mi)),
@@ -767,7 +765,7 @@
pub fn noop_visit_variant_data<T: MutVisitor>(vdata: &mut VariantData, vis: &mut T) {
match vdata {
- VariantData::Struct(fields, id) |
+ VariantData::Struct(fields, id, _) |
VariantData::Tuple(fields, id) => {
visit_vec(fields, |field| vis.visit_struct_field(field));
vis.visit_id(id);
@@ -1340,4 +1338,3 @@
})
}
}
-
diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs
index e93e15f..4211268 100644
--- a/src/libsyntax/parse/attr.rs
+++ b/src/libsyntax/parse/attr.rs
@@ -1,6 +1,5 @@
use crate::attr;
use crate::ast;
-use crate::source_map::respan;
use crate::parse::{SeqSep, PResult};
use crate::parse::token::{self, Nonterminal, DelimToken};
use crate::parse::parser::{Parser, TokenType, PathStyle};
@@ -149,7 +148,7 @@
};
Ok(if let Some(meta) = meta {
self.bump();
- (meta.ident, meta.node.tokens(meta.span))
+ (meta.path, meta.node.tokens(meta.span))
} else {
let path = self.parse_path(PathStyle::Mod)?;
let tokens = if self.check(&token::OpenDelim(DelimToken::Paren)) ||
@@ -250,10 +249,10 @@
}
let lo = self.span;
- let ident = self.parse_path(PathStyle::Mod)?;
+ let path = self.parse_path(PathStyle::Mod)?;
let node = self.parse_meta_item_kind()?;
let span = lo.to(self.prev_span);
- Ok(ast::MetaItem { ident, node, span })
+ Ok(ast::MetaItem { path, node, span })
}
crate fn parse_meta_item_kind(&mut self) -> PResult<'a, ast::MetaItemKind> {
@@ -268,18 +267,16 @@
/// matches meta_item_inner : (meta_item | UNSUFFIXED_LIT) ;
fn parse_meta_item_inner(&mut self) -> PResult<'a, ast::NestedMetaItem> {
- let lo = self.span;
-
match self.parse_unsuffixed_lit() {
Ok(lit) => {
- return Ok(respan(lo.to(self.prev_span), ast::NestedMetaItemKind::Literal(lit)))
+ return Ok(ast::NestedMetaItem::Literal(lit))
}
Err(ref mut err) => self.diagnostic().cancel(err)
}
match self.parse_meta_item() {
Ok(mi) => {
- return Ok(respan(lo.to(self.prev_span), ast::NestedMetaItemKind::MetaItem(mi)))
+ return Ok(ast::NestedMetaItem::MetaItem(mi))
}
Err(ref mut err) => self.diagnostic().cancel(err)
}
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs
index 01e3b29..cd4944d 100644
--- a/src/libsyntax/parse/lexer/mod.rs
+++ b/src/libsyntax/parse/lexer/mod.rs
@@ -1,7 +1,7 @@
use crate::ast::{self, Ident};
use crate::source_map::{SourceMap, FilePathMapping};
use crate::parse::{token, ParseSess};
-use crate::symbol::{Symbol, keywords};
+use crate::symbol::Symbol;
use errors::{Applicability, FatalError, Diagnostic, DiagnosticBuilder};
use syntax_pos::{BytePos, CharPos, Pos, Span, NO_EXPANSION};
@@ -968,9 +968,10 @@
} else {
let span = self.mk_sp(start, self.pos);
let mut suggestion = "\\u{".to_owned();
+ let msg = "incorrect unicode escape sequence";
let mut err = self.sess.span_diagnostic.struct_span_err(
span,
- "incorrect unicode escape sequence",
+ msg,
);
let mut i = 0;
while let (Some(ch), true) = (self.ch, i < 6) {
@@ -991,8 +992,8 @@
Applicability::MaybeIncorrect,
);
} else {
- err.span_help(
- span,
+ err.span_label(span, msg);
+ err.help(
"format of unicode escape sequences is `\\u{...}`",
);
}
@@ -1018,25 +1019,24 @@
}
c => {
let pos = self.pos;
- let mut err = self.struct_err_span_char(escaped_pos,
- pos,
- if ascii_only {
- "unknown byte escape"
- } else {
- "unknown character \
- escape"
- },
- c);
+ let msg = if ascii_only {
+ "unknown byte escape"
+ } else {
+ "unknown character escape"
+ };
+ let mut err = self.struct_err_span_char(escaped_pos, pos, msg, c);
+ err.span_label(self.mk_sp(escaped_pos, pos), msg);
if e == '\r' {
- err.span_help(self.mk_sp(escaped_pos, pos),
- "this is an isolated carriage return; consider \
- checking your editor and version control \
- settings");
+ err.help(
+ "this is an isolated carriage return; consider checking \
+ your editor and version control settings",
+ );
}
if (e == '{' || e == '}') && !ascii_only {
- err.span_help(self.mk_sp(escaped_pos, pos),
- "if used in a formatting string, curly braces \
- are escaped with `{{` and `}}`");
+ err.help(
+ "if used in a formatting string, curly braces are escaped \
+ with `{{` and `}}`",
+ );
}
err.emit();
false
@@ -1249,15 +1249,11 @@
// FIXME: perform NFKC normalization here. (Issue #2253)
let ident = self.mk_ident(string);
- if is_raw_ident && (ident.is_path_segment_keyword() ||
- ident.name == keywords::Underscore.name()) {
- self.fatal_span_(raw_start, self.pos,
- &format!("`r#{}` is not currently supported.", ident.name)
- ).raise();
- }
-
if is_raw_ident {
let span = self.mk_sp(raw_start, self.pos);
+ if !ident.can_be_raw() {
+ self.err_span(span, &format!("`{}` cannot be a raw identifier", ident));
+ }
self.sess.raw_identifier_spans.borrow_mut().push(span);
}
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index fe31311..5627ac3 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -895,9 +895,7 @@
&format!("expected identifier, found {}",
self.this_token_descr()));
if let token::Ident(ident, false) = &self.token {
- if ident.is_reserved() && !ident.is_path_segment_keyword() &&
- ident.name != keywords::Underscore.name()
- {
+ if ident.is_raw_guess() {
err.span_suggestion(
self.span,
"you can escape reserved keywords to use them as identifiers",
@@ -1526,7 +1524,7 @@
at_end: &mut bool,
mut attrs: Vec<Attribute>) -> PResult<'a, TraitItem> {
let lo = self.span;
-
+ self.eat_bad_pub();
let (name, node, generics) = if self.eat_keyword(keywords::Type) {
self.parse_trait_item_assoc_ty()?
} else if self.is_const_item() {
@@ -2335,7 +2333,7 @@
let meta_ident = match self.token {
token::Interpolated(ref nt) => match **nt {
token::NtMeta(ref meta) => match meta.node {
- ast::MetaItemKind::Word => Some(meta.ident.clone()),
+ ast::MetaItemKind::Word => Some(meta.path.clone()),
_ => None,
},
_ => None,
@@ -4231,19 +4229,24 @@
fn parse_pat_list(&mut self) -> PResult<'a, (Vec<P<Pat>>, Option<usize>, bool)> {
let mut fields = Vec::new();
let mut ddpos = None;
+ let mut prev_dd_sp = None;
let mut trailing_comma = false;
loop {
if self.eat(&token::DotDot) {
if ddpos.is_none() {
ddpos = Some(fields.len());
+ prev_dd_sp = Some(self.prev_span);
} else {
// Emit a friendly error, ignore `..` and continue parsing
- self.struct_span_err(
+ let mut err = self.struct_span_err(
self.prev_span,
"`..` can only be used once per tuple or tuple struct pattern",
- )
- .span_label(self.prev_span, "can only be used once per pattern")
- .emit();
+ );
+ err.span_label(self.prev_span, "can only be used once per pattern");
+ if let Some(sp) = prev_dd_sp {
+ err.span_label(sp, "previously present here");
+ }
+ err.emit();
}
} else if !self.check(&token::CloseDelim(token::Paren)) {
fields.push(self.parse_pat(None)?);
@@ -5116,12 +5119,8 @@
let ident = self.parse_ident()?;
let (delim, tokens) = self.expect_delimited_token_tree()?;
- if delim != MacDelimiter::Brace {
- if !self.eat(&token::Semi) {
- let msg = "macros that expand to items must either \
- be surrounded with braces or followed by a semicolon";
- self.span_err(self.prev_span, msg);
- }
+ if delim != MacDelimiter::Brace && !self.eat(&token::Semi) {
+ self.report_invalid_macro_expansion_item();
}
(ident, ast::MacroDef { tokens: tokens, legacy: true })
@@ -5264,13 +5263,8 @@
// if it has a special ident, it's definitely an item
//
// Require a semicolon or braces.
- if style != MacStmtStyle::Braces {
- if !self.eat(&token::Semi) {
- self.span_err(self.prev_span,
- "macros that expand to items must \
- either be surrounded with braces or \
- followed by a semicolon");
- }
+ if style != MacStmtStyle::Braces && !self.eat(&token::Semi) {
+ self.report_invalid_macro_expansion_item();
}
let span = lo.to(hi);
Stmt {
@@ -6743,7 +6737,15 @@
};
// Parse both types and traits as a type, then reinterpret if necessary.
- let ty_first = self.parse_ty()?;
+ let err_path = |span| ast::Path::from_ident(Ident::new(keywords::Invalid.name(), span));
+ let ty_first = if self.token.is_keyword(keywords::For) &&
+ self.look_ahead(1, |t| t != &token::Lt) {
+ let span = self.prev_span.between(self.span);
+ self.struct_span_err(span, "missing trait in a trait impl").emit();
+ P(Ty { node: TyKind::Path(None, err_path(span)), span, id: ast::DUMMY_NODE_ID })
+ } else {
+ self.parse_ty()?
+ };
// If `for` is missing we try to recover.
let has_for = self.eat_keyword(keywords::For);
@@ -6752,7 +6754,7 @@
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 }))
+ Some(DummyResult::raw_ty(self.prev_span, true))
} else if has_for || self.token.can_begin_type() {
Some(self.parse_ty()?)
} else {
@@ -6782,7 +6784,7 @@
TyKind::Path(None, path) => path,
_ => {
self.span_err(ty_first.span, "expected a trait, found type");
- ast::Path::from_ident(Ident::new(keywords::Invalid.name(), ty_first.span))
+ err_path(ty_first.span)
}
};
let trait_ref = TraitRef { path, ref_id: ty_first.id };
@@ -6840,14 +6842,16 @@
VariantData::Unit(ast::DUMMY_NODE_ID)
} else {
// If we see: `struct Foo<T> where T: Copy { ... }`
- VariantData::Struct(self.parse_record_struct_body()?, ast::DUMMY_NODE_ID)
+ let (fields, recovered) = self.parse_record_struct_body()?;
+ VariantData::Struct(fields, ast::DUMMY_NODE_ID, recovered)
}
// No `where` so: `struct Foo<T>;`
} else if self.eat(&token::Semi) {
VariantData::Unit(ast::DUMMY_NODE_ID)
// Record-style struct definition
} else if self.token == token::OpenDelim(token::Brace) {
- VariantData::Struct(self.parse_record_struct_body()?, ast::DUMMY_NODE_ID)
+ let (fields, recovered) = self.parse_record_struct_body()?;
+ VariantData::Struct(fields, ast::DUMMY_NODE_ID, recovered)
// Tuple-style struct definition with optional where-clause.
} else if self.token == token::OpenDelim(token::Paren) {
let body = VariantData::Tuple(self.parse_tuple_struct_body()?, ast::DUMMY_NODE_ID);
@@ -6875,9 +6879,11 @@
let vdata = if self.token.is_keyword(keywords::Where) {
generics.where_clause = self.parse_where_clause()?;
- VariantData::Struct(self.parse_record_struct_body()?, ast::DUMMY_NODE_ID)
+ let (fields, recovered) = self.parse_record_struct_body()?;
+ VariantData::Struct(fields, ast::DUMMY_NODE_ID, recovered)
} else if self.token == token::OpenDelim(token::Brace) {
- VariantData::Struct(self.parse_record_struct_body()?, ast::DUMMY_NODE_ID)
+ let (fields, recovered) = self.parse_record_struct_body()?;
+ VariantData::Struct(fields, ast::DUMMY_NODE_ID, recovered)
} else {
let token_str = self.this_token_descr();
let mut err = self.fatal(&format!(
@@ -6909,12 +6915,16 @@
}
}
- fn parse_record_struct_body(&mut self) -> PResult<'a, Vec<StructField>> {
+ fn parse_record_struct_body(
+ &mut self,
+ ) -> PResult<'a, (Vec<StructField>, /* recovered */ bool)> {
let mut fields = Vec::new();
+ let mut recovered = false;
if self.eat(&token::OpenDelim(token::Brace)) {
while self.token != token::CloseDelim(token::Brace) {
let field = self.parse_struct_decl_field().map_err(|e| {
self.recover_stmt();
+ recovered = true;
e
});
match field {
@@ -6933,7 +6943,7 @@
return Err(err);
}
- Ok(fields)
+ Ok((fields, recovered))
}
fn parse_tuple_struct_body(&mut self) -> PResult<'a, Vec<StructField>> {
@@ -7691,16 +7701,19 @@
let struct_def;
let mut disr_expr = None;
+ self.eat_bad_pub();
let ident = self.parse_ident()?;
if self.check(&token::OpenDelim(token::Brace)) {
// Parse a struct variant.
all_nullary = false;
- struct_def = VariantData::Struct(self.parse_record_struct_body()?,
- ast::DUMMY_NODE_ID);
+ let (fields, recovered) = self.parse_record_struct_body()?;
+ struct_def = VariantData::Struct(fields, ast::DUMMY_NODE_ID, recovered);
} else if self.check(&token::OpenDelim(token::Paren)) {
all_nullary = false;
- struct_def = VariantData::Tuple(self.parse_tuple_struct_body()?,
- ast::DUMMY_NODE_ID);
+ struct_def = VariantData::Tuple(
+ self.parse_tuple_struct_body()?,
+ ast::DUMMY_NODE_ID,
+ );
} else if self.eat(&token::Eq) {
disr_expr = Some(AnonConst {
id: ast::DUMMY_NODE_ID,
@@ -7722,11 +7735,25 @@
};
variants.push(respan(vlo.to(self.prev_span), vr));
- if !self.eat(&token::Comma) { break; }
+ if !self.eat(&token::Comma) {
+ if self.token.is_ident() && !self.token.is_reserved_ident() {
+ let sp = self.sess.source_map().next_point(self.prev_span);
+ let mut err = self.struct_span_err(sp, "missing comma");
+ err.span_suggestion_short(
+ sp,
+ "missing comma",
+ ",".to_owned(),
+ Applicability::MaybeIncorrect,
+ );
+ err.emit();
+ } else {
+ break;
+ }
+ }
}
self.expect(&token::CloseDelim(token::Brace))?;
if !any_disr.is_empty() && !all_nullary {
- let mut err =self.struct_span_err(
+ let mut err = self.struct_span_err(
any_disr.clone(),
"discriminator values can only be used with a field-less enum",
);
@@ -8360,13 +8387,8 @@
};
// eat a matched-delimiter token tree:
let (delim, tts) = self.expect_delimited_token_tree()?;
- if delim != MacDelimiter::Brace {
- if !self.eat(&token::Semi) {
- self.span_err(self.prev_span,
- "macros that expand to items must either \
- be surrounded with braces or followed by \
- a semicolon");
- }
+ if delim != MacDelimiter::Brace && !self.eat(&token::Semi) {
+ self.report_invalid_macro_expansion_item();
}
let hi = self.prev_span;
@@ -8597,6 +8619,40 @@
}
}
}
+
+ fn report_invalid_macro_expansion_item(&self) {
+ self.struct_span_err(
+ self.prev_span,
+ "macros that expand to items must be delimited with braces or followed by a semicolon",
+ ).multipart_suggestion(
+ "change the delimiters to curly braces",
+ vec![
+ (self.prev_span.with_hi(self.prev_span.lo() + BytePos(1)), String::from(" {")),
+ (self.prev_span.with_lo(self.prev_span.hi() - BytePos(1)), '}'.to_string()),
+ ],
+ Applicability::MaybeIncorrect,
+ ).span_suggestion(
+ self.sess.source_map.next_point(self.prev_span),
+ "add a semicolon",
+ ';'.to_string(),
+ Applicability::MaybeIncorrect,
+ ).emit();
+ }
+
+ /// Recover from `pub` keyword in places where it seems _reasonable_ but isn't valid.
+ fn eat_bad_pub(&mut self) {
+ if self.token.is_keyword(keywords::Pub) {
+ match self.parse_visibility(false) {
+ Ok(vis) => {
+ let mut err = self.diagnostic()
+ .struct_span_err(vis.span, "unnecessary visibility qualifier");
+ err.span_label(vis.span, "`pub` not permitted here");
+ err.emit();
+ }
+ Err(mut err) => err.emit(),
+ }
+ }
+ }
}
pub fn emit_unclosed_delims(unclosed_delims: &mut Vec<UnmatchedBrace>, handler: &errors::Handler) {
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 49e3fad..07df14d 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -768,11 +768,11 @@
}
fn print_meta_list_item(&mut self, item: &ast::NestedMetaItem) -> io::Result<()> {
- match item.node {
- ast::NestedMetaItemKind::MetaItem(ref mi) => {
+ match item {
+ ast::NestedMetaItem::MetaItem(ref mi) => {
self.print_meta_item(mi)
},
- ast::NestedMetaItemKind::Literal(ref lit) => {
+ ast::NestedMetaItem::Literal(ref lit) => {
self.print_literal(lit)
}
}
@@ -781,15 +781,15 @@
fn print_meta_item(&mut self, item: &ast::MetaItem) -> io::Result<()> {
self.ibox(INDENT_UNIT)?;
match item.node {
- ast::MetaItemKind::Word => self.print_attribute_path(&item.ident)?,
+ ast::MetaItemKind::Word => self.print_attribute_path(&item.path)?,
ast::MetaItemKind::NameValue(ref value) => {
- self.print_attribute_path(&item.ident)?;
+ self.print_attribute_path(&item.path)?;
self.writer().space()?;
self.word_space("=")?;
self.print_literal(value)?;
}
ast::MetaItemKind::List(ref items) => {
- self.print_attribute_path(&item.ident)?;
+ self.print_attribute_path(&item.path)?;
self.popen()?;
self.commasep(Consistent,
&items[..],
@@ -1263,13 +1263,13 @@
self.s.word(";")?;
self.end()?; // end the outer cbox
}
- ast::ItemKind::Fn(ref decl, header, ref typarams, ref body) => {
+ ast::ItemKind::Fn(ref decl, header, ref param_names, ref body) => {
self.head("")?;
self.print_fn(
decl,
header,
Some(item.ident),
- typarams,
+ param_names,
&item.vis
)?;
self.s.word(" ")?;
diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs
index 56290fa..6f03c58 100644
--- a/src/libsyntax/test.rs
+++ b/src/libsyntax/test.rs
@@ -435,9 +435,12 @@
let test_attr = attr::find_by_name(&krate.attrs, "test_runner")?;
test_attr.meta_item_list().map(|meta_list| {
if meta_list.len() != 1 {
- sd.span_fatal(test_attr.span(),
+ sd.span_fatal(test_attr.span,
"#![test_runner(..)] accepts exactly 1 argument").raise()
}
- meta_list[0].word().as_ref().unwrap().ident.clone()
+ match meta_list[0].meta_item() {
+ Some(meta_item) if meta_item.is_word() => meta_item.path.clone(),
+ _ => sd.span_fatal(test_attr.span, "`test_runner` argument must be a path").raise()
+ }
})
}
diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs
index 4ce308d..80a7bde 100644
--- a/src/libsyntax/tokenstream.rs
+++ b/src/libsyntax/tokenstream.rs
@@ -178,9 +178,11 @@
while let Some((pos, ts)) = iter.next() {
if let Some((_, next)) = iter.peek() {
let sp = match (&ts, &next) {
- ((TokenTree::Token(_, token::Token::Comma), NonJoint), _) |
- (_, (TokenTree::Token(_, token::Token::Comma), NonJoint)) => continue,
- ((TokenTree::Token(sp, _), NonJoint), _) => *sp,
+ (_, (TokenTree::Token(_, token::Token::Comma), _)) => continue,
+ ((TokenTree::Token(sp, token_left), NonJoint),
+ (TokenTree::Token(_, token_right), _))
+ if (token_left.is_ident() || token_left.is_lit()) &&
+ (token_right.is_ident() || token_right.is_lit()) => *sp,
((TokenTree::Delimited(sp, ..), NonJoint), _) => sp.entire(),
_ => continue,
};
diff --git a/src/libsyntax_ext/deriving/custom.rs b/src/libsyntax_ext/deriving/custom.rs
index cfc3c93..e731107 100644
--- a/src/libsyntax_ext/deriving/custom.rs
+++ b/src/libsyntax_ext/deriving/custom.rs
@@ -17,9 +17,11 @@
impl<'a> Visitor<'a> for MarkAttrs<'a> {
fn visit_attribute(&mut self, attr: &Attribute) {
- if self.0.contains(&attr.name()) {
- mark_used(attr);
- mark_known(attr);
+ if let Some(ident) = attr.ident() {
+ if self.0.contains(&ident.name) {
+ mark_used(attr);
+ mark_known(attr);
+ }
}
}
diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs
index b8f96c5..2bb98c1 100644
--- a/src/libsyntax_ext/deriving/generic/mod.rs
+++ b/src/libsyntax_ext/deriving/generic/mod.rs
@@ -463,12 +463,9 @@
let mut attrs = newitem.attrs.clone();
attrs.extend(item.attrs
.iter()
- .filter(|a| {
- match &*a.name().as_str() {
- "allow" | "warn" | "deny" | "forbid" | "stable" | "unstable" => true,
- _ => false,
- }
- })
+ .filter(|a| a.ident_str().map_or(false, |name| {
+ ["allow", "warn", "deny", "forbid", "stable", "unstable"].contains(&name)
+ }))
.cloned());
push(Annotatable::Item(P(ast::Item { attrs: attrs, ..(*newitem).clone() })))
}
diff --git a/src/libsyntax_ext/proc_macro_decls.rs b/src/libsyntax_ext/proc_macro_decls.rs
index d8f8dec..d5f37af 100644
--- a/src/libsyntax_ext/proc_macro_decls.rs
+++ b/src/libsyntax_ext/proc_macro_decls.rs
@@ -109,52 +109,67 @@
None => return,
};
if list.len() != 1 && list.len() != 2 {
- self.handler.span_err(attr.span(),
+ self.handler.span_err(attr.span,
"attribute must have either one or two arguments");
return
}
- let trait_attr = &list[0];
- let attributes_attr = list.get(1);
- let trait_name = match trait_attr.name() {
- Some(name) => name,
+ let trait_attr = match list[0].meta_item() {
+ Some(meta_item) => meta_item,
_ => {
- self.handler.span_err(trait_attr.span(), "not a meta item");
+ self.handler.span_err(list[0].span(), "not a meta item");
return
}
};
- if !trait_attr.is_word() {
- self.handler.span_err(trait_attr.span(), "must only be one word");
+ let trait_ident = match trait_attr.ident() {
+ Some(trait_ident) if trait_attr.is_word() => trait_ident,
+ _ => {
+ self.handler.span_err(trait_attr.span, "must only be one word");
+ return
+ }
+ };
+
+ if !trait_ident.can_be_raw() {
+ self.handler.span_err(trait_attr.span,
+ &format!("`{}` cannot be a name of derive macro", trait_ident));
+ }
+ if deriving::is_builtin_trait(trait_ident.name) {
+ self.handler.span_err(trait_attr.span,
+ "cannot override a built-in derive macro");
}
- if deriving::is_builtin_trait(trait_name) {
- self.handler.span_err(trait_attr.span(),
- "cannot override a built-in #[derive] mode");
- }
-
+ let attributes_attr = list.get(1);
let proc_attrs: Vec<_> = if let Some(attr) = attributes_attr {
if !attr.check_name("attributes") {
self.handler.span_err(attr.span(), "second argument must be `attributes`")
}
attr.meta_item_list().unwrap_or_else(|| {
self.handler.span_err(attr.span(),
- "attribute must be of form: \
- `attributes(foo, bar)`");
+ "attribute must be of form: `attributes(foo, bar)`");
&[]
}).into_iter().filter_map(|attr| {
- let name = match attr.name() {
- Some(name) => name,
+ let attr = match attr.meta_item() {
+ Some(meta_item) => meta_item,
_ => {
self.handler.span_err(attr.span(), "not a meta item");
return None;
- },
+ }
};
- if !attr.is_word() {
- self.handler.span_err(attr.span(), "must only be one word");
- return None;
+ let ident = match attr.ident() {
+ Some(ident) if attr.is_word() => ident,
+ _ => {
+ self.handler.span_err(attr.span, "must only be one word");
+ return None;
+ }
+ };
+ if !ident.can_be_raw() {
+ self.handler.span_err(
+ attr.span,
+ &format!("`{}` cannot be a name of derive helper attribute", ident),
+ );
}
- Some(name)
+ Some(ident.name)
}).collect()
} else {
Vec::new()
@@ -163,7 +178,7 @@
if self.in_root && item.vis.node.is_pub() {
self.derives.push(ProcMacroDerive {
span: item.span,
- trait_name,
+ trait_name: trait_ident.name,
function_name: item.ident,
attrs: proc_attrs,
});
@@ -247,8 +262,8 @@
to the same function", attr.path, prev_attr.path)
};
- self.handler.struct_span_err(attr.span(), &msg)
- .span_note(prev_attr.span(), "Previous attribute here")
+ self.handler.struct_span_err(attr.span, &msg)
+ .span_note(prev_attr.span, "Previous attribute here")
.emit();
return;
@@ -273,7 +288,7 @@
let msg = format!("the `#[{}]` attribute may only be used on bare functions",
attr.path);
- self.handler.span_err(attr.span(), &msg);
+ self.handler.span_err(attr.span, &msg);
return;
}
@@ -285,7 +300,7 @@
let msg = format!("the `#[{}]` attribute is only usable with crates of the \
`proc-macro` crate type", attr.path);
- self.handler.span_err(attr.span(), &msg);
+ self.handler.span_err(attr.span, &msg);
return;
}
diff --git a/src/libsyntax_ext/proc_macro_server.rs b/src/libsyntax_ext/proc_macro_server.rs
index a7ac95b..c0a9dfe 100644
--- a/src/libsyntax_ext/proc_macro_server.rs
+++ b/src/libsyntax_ext/proc_macro_server.rs
@@ -340,12 +340,8 @@
if !Self::is_valid(string) {
panic!("`{:?}` is not a valid identifier", string)
}
- if is_raw {
- let normalized_sym = Symbol::intern(string);
- if normalized_sym == keywords::Underscore.name() ||
- ast::Ident::with_empty_ctxt(normalized_sym).is_path_segment_keyword() {
- panic!("`{:?}` is not a valid raw identifier", string)
- }
+ if is_raw && !ast::Ident::from_str(string).can_be_raw() {
+ panic!("`{}` cannot be a raw identifier", string);
}
Ident { sym, is_raw, span }
}
diff --git a/src/libsyntax_ext/test.rs b/src/libsyntax_ext/test.rs
index f4b625f..0dbcb7c 100644
--- a/src/libsyntax_ext/test.rs
+++ b/src/libsyntax_ext/test.rs
@@ -227,7 +227,7 @@
.and_then(|mi| mi.value_str());
if list.len() != 1 || msg.is_none() {
sd.struct_span_warn(
- attr.span(),
+ attr.span,
"argument must be of the form: \
`expected = \"error message\"`"
).note("Errors in this attribute were erroneously \
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index c5301f9..e8d215a 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -484,11 +484,16 @@
self.name == keywords::DollarCrate.name()
}
- // We see this identifier in a normal identifier position, like variable name or a type.
- // How was it written originally? Did it use the raw form? Let's try to guess.
- pub fn is_raw_guess(self) -> bool {
+ /// This identifier can be a raw identifier.
+ pub fn can_be_raw(self) -> bool {
self.name != keywords::Invalid.name() && self.name != keywords::Underscore.name() &&
- self.is_reserved() && !self.is_path_segment_keyword()
+ !self.is_path_segment_keyword()
+ }
+
+ /// We see this identifier in a normal identifier position, like variable name or a type.
+ /// How was it written originally? Did it use the raw form? Let's try to guess.
+ pub fn is_raw_guess(self) -> bool {
+ self.can_be_raw() && self.is_reserved()
}
}
diff --git a/src/libterm/Cargo.toml b/src/libterm/Cargo.toml
deleted file mode 100644
index 4eba9a9..0000000
--- a/src/libterm/Cargo.toml
+++ /dev/null
@@ -1,10 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "term"
-version = "0.0.0"
-edition = "2018"
-
-[lib]
-name = "term"
-path = "lib.rs"
-crate-type = ["dylib", "rlib"]
diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs
deleted file mode 100644
index 711716d..0000000
--- a/src/libterm/lib.rs
+++ /dev/null
@@ -1,201 +0,0 @@
-//! Terminal formatting library.
-//!
-//! This crate provides the `Terminal` trait, which abstracts over an [ANSI
-//! Terminal][ansi] to provide color printing, among other things. There are two
-//! implementations, the `TerminfoTerminal`, which uses control characters from
-//! a [terminfo][ti] database, and `WinConsole`, which uses the [Win32 Console
-//! API][win].
-//!
-//! # Examples
-//!
-//! ```no_run
-//! # #![feature(rustc_private)]
-//! extern crate term;
-//! use std::io::prelude::*;
-//!
-//! fn main() {
-//! let mut t = term::stdout().unwrap();
-//!
-//! t.fg(term::color::GREEN).unwrap();
-//! write!(t, "hello, ").unwrap();
-//!
-//! t.fg(term::color::RED).unwrap();
-//! writeln!(t, "world!").unwrap();
-//!
-//! assert!(t.reset().unwrap());
-//! }
-//! ```
-//!
-//! [ansi]: https://en.wikipedia.org/wiki/ANSI_escape_code
-//! [win]: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682010%28v=vs.85%29.aspx
-//! [ti]: https://en.wikipedia.org/wiki/Terminfo
-
-#![doc(html_root_url = "https://doc.rust-lang.org/nightly/",
- html_playground_url = "https://play.rust-lang.org/",
- test(attr(deny(warnings))))]
-#![deny(missing_docs)]
-
-#![deny(rust_2018_idioms)]
-
-#![cfg_attr(windows, feature(libc))]
-// Handle rustfmt skips
-#![feature(custom_attribute)]
-#![allow(unused_attributes)]
-
-use std::io::prelude::*;
-use std::io::{self, Stdout, Stderr};
-
-pub use terminfo::TerminfoTerminal;
-#[cfg(windows)]
-pub use win::WinConsole;
-
-pub mod terminfo;
-
-#[cfg(windows)]
-mod win;
-
-/// Alias for stdout terminals.
-pub type StdoutTerminal = dyn Terminal<Output = Stdout> + Send;
-/// Alias for stderr terminals.
-pub type StderrTerminal = dyn Terminal<Output = Stderr> + Send;
-
-#[cfg(not(windows))]
-/// Returns a Terminal wrapping stdout, or None if a terminal couldn't be
-/// opened.
-pub fn stdout() -> Option<Box<StdoutTerminal>> {
- TerminfoTerminal::new(io::stdout()).map(|t| Box::new(t) as Box<StdoutTerminal>)
-}
-
-#[cfg(windows)]
-/// Returns a Terminal wrapping stdout, or None if a terminal couldn't be
-/// opened.
-pub fn stdout() -> Option<Box<StdoutTerminal>> {
- TerminfoTerminal::new(io::stdout())
- .map(|t| Box::new(t) as Box<StdoutTerminal>)
- .or_else(|| WinConsole::new(io::stdout()).ok().map(|t| Box::new(t) as Box<StdoutTerminal>))
-}
-
-#[cfg(not(windows))]
-/// Returns a Terminal wrapping stderr, or None if a terminal couldn't be
-/// opened.
-pub fn stderr() -> Option<Box<StderrTerminal>> {
- TerminfoTerminal::new(io::stderr()).map(|t| Box::new(t) as Box<StderrTerminal>)
-}
-
-#[cfg(windows)]
-/// Returns a Terminal wrapping stderr, or None if a terminal couldn't be
-/// opened.
-pub fn stderr() -> Option<Box<StderrTerminal>> {
- TerminfoTerminal::new(io::stderr())
- .map(|t| Box::new(t) as Box<StderrTerminal>)
- .or_else(|| WinConsole::new(io::stderr()).ok().map(|t| Box::new(t) as Box<StderrTerminal>))
-}
-
-
-/// Terminal color definitions
-#[allow(missing_docs)]
-pub mod color {
- /// Number for a terminal color
- pub type Color = u16;
-
- pub const BLACK: Color = 0;
- pub const RED: Color = 1;
- pub const GREEN: Color = 2;
- pub const YELLOW: Color = 3;
- pub const BLUE: Color = 4;
- pub const MAGENTA: Color = 5;
- pub const CYAN: Color = 6;
- pub const WHITE: Color = 7;
-
- pub const BRIGHT_BLACK: Color = 8;
- pub const BRIGHT_RED: Color = 9;
- pub const BRIGHT_GREEN: Color = 10;
- pub const BRIGHT_YELLOW: Color = 11;
- pub const BRIGHT_BLUE: Color = 12;
- pub const BRIGHT_MAGENTA: Color = 13;
- pub const BRIGHT_CYAN: Color = 14;
- pub const BRIGHT_WHITE: Color = 15;
-}
-
-/// Terminal attributes for use with term.attr().
-///
-/// Most attributes can only be turned on and must be turned off with term.reset().
-/// The ones that can be turned off explicitly take a boolean value.
-/// Color is also represented as an attribute for convenience.
-#[derive(Debug, PartialEq, Eq, Copy, Clone)]
-pub enum Attr {
- /// Bold (or possibly bright) mode
- Bold,
- /// Dim mode, also called faint or half-bright. Often not supported
- Dim,
- /// Italics mode. Often not supported
- Italic(bool),
- /// Underline mode
- Underline(bool),
- /// Blink mode
- Blink,
- /// Standout mode. Often implemented as Reverse, sometimes coupled with Bold
- Standout(bool),
- /// Reverse mode, inverts the foreground and background colors
- Reverse,
- /// Secure mode, also called invis mode. Hides the printed text
- Secure,
- /// Convenience attribute to set the foreground color
- ForegroundColor(color::Color),
- /// Convenience attribute to set the background color
- BackgroundColor(color::Color),
-}
-
-/// A terminal with similar capabilities to an ANSI Terminal
-/// (foreground/background colors etc).
-pub trait Terminal: Write {
- /// The terminal's output writer type.
- type Output: Write;
-
- /// Sets the foreground color to the given color.
- ///
- /// If the color is a bright color, but the terminal only supports 8 colors,
- /// the corresponding normal color will be used instead.
- ///
- /// Returns `Ok(true)` if the color was set, `Ok(false)` otherwise, and `Err(e)`
- /// if there was an I/O error.
- fn fg(&mut self, color: color::Color) -> io::Result<bool>;
-
- /// Sets the background color to the given color.
- ///
- /// If the color is a bright color, but the terminal only supports 8 colors,
- /// the corresponding normal color will be used instead.
- ///
- /// Returns `Ok(true)` if the color was set, `Ok(false)` otherwise, and `Err(e)`
- /// if there was an I/O error.
- fn bg(&mut self, color: color::Color) -> io::Result<bool>;
-
- /// Sets the given terminal attribute, if supported. Returns `Ok(true)`
- /// if the attribute was supported, `Ok(false)` otherwise, and `Err(e)` if
- /// there was an I/O error.
- fn attr(&mut self, attr: Attr) -> io::Result<bool>;
-
- /// Returns `true` if the given terminal attribute is supported.
- fn supports_attr(&self, attr: Attr) -> bool;
-
- /// Resets all terminal attributes and colors to their defaults.
- ///
- /// Returns `Ok(true)` if the terminal was reset, `Ok(false)` otherwise, and `Err(e)` if there
- /// was an I/O error.
- ///
- /// *Note: This does not flush.*
- ///
- /// That means the reset command may get buffered so, if you aren't planning on doing anything
- /// else that might flush stdout's buffer (e.g., writing a line of text), you should flush after
- /// calling reset.
- fn reset(&mut self) -> io::Result<bool>;
-
- /// Gets an immutable reference to the stream inside
- fn get_ref(&self) -> &Self::Output;
-
- /// Gets a mutable reference to the stream inside
- fn get_mut(&mut self) -> &mut Self::Output;
-
- /// Returns the contained stream, destroying the `Terminal`
- fn into_inner(self) -> Self::Output where Self: Sized;
-}
diff --git a/src/libterm/terminfo/mod.rs b/src/libterm/terminfo/mod.rs
deleted file mode 100644
index be90195..0000000
--- a/src/libterm/terminfo/mod.rs
+++ /dev/null
@@ -1,265 +0,0 @@
-//! Terminfo database interface.
-
-use std::collections::HashMap;
-use std::env;
-use std::error;
-use std::fmt;
-use std::fs::File;
-use std::io::{self, prelude::*, BufReader};
-use std::path::Path;
-
-use crate::Attr;
-use crate::color;
-use crate::Terminal;
-
-use searcher::get_dbpath_for_term;
-use parser::compiled::{parse, msys_terminfo};
-use parm::{expand, Variables, Param};
-
-/// A parsed terminfo database entry.
-#[derive(Debug)]
-pub struct TermInfo {
- /// Names for the terminal
- pub names: Vec<String>,
- /// Map of capability name to boolean value
- pub bools: HashMap<String, bool>,
- /// Map of capability name to numeric value
- pub numbers: HashMap<String, u16>,
- /// Map of capability name to raw (unexpanded) string
- pub strings: HashMap<String, Vec<u8>>,
-}
-
-/// A terminfo creation error.
-#[derive(Debug)]
-pub enum Error {
- /// TermUnset Indicates that the environment doesn't include enough information to find
- /// the terminfo entry.
- TermUnset,
- /// MalformedTerminfo indicates that parsing the terminfo entry failed.
- MalformedTerminfo(String),
- /// io::Error forwards any io::Errors encountered when finding or reading the terminfo entry.
- IoError(io::Error),
-}
-
-impl error::Error for Error {
- fn description(&self) -> &str {
- "failed to create TermInfo"
- }
-
- fn cause(&self) -> Option<&dyn error::Error> {
- use Error::*;
- match *self {
- IoError(ref e) => Some(e),
- _ => None,
- }
- }
-}
-
-impl fmt::Display for Error {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- use Error::*;
- match *self {
- TermUnset => Ok(()),
- MalformedTerminfo(ref e) => e.fmt(f),
- IoError(ref e) => e.fmt(f),
- }
- }
-}
-
-impl TermInfo {
- /// Creates a TermInfo based on current environment.
- pub fn from_env() -> Result<TermInfo, Error> {
- let term = match env::var("TERM") {
- Ok(name) => TermInfo::from_name(&name),
- Err(..) => return Err(Error::TermUnset),
- };
-
- if term.is_err() && env::var("MSYSCON").ok().map_or(false, |s| "mintty.exe" == s) {
- // msys terminal
- Ok(msys_terminfo())
- } else {
- term
- }
- }
-
- /// Creates a TermInfo for the named terminal.
- pub fn from_name(name: &str) -> Result<TermInfo, Error> {
- get_dbpath_for_term(name)
- .ok_or_else(|| {
- Error::IoError(io::Error::new(io::ErrorKind::NotFound, "terminfo file not found"))
- })
- .and_then(|p| TermInfo::from_path(&(*p)))
- }
-
- /// Parse the given TermInfo.
- pub fn from_path<P: AsRef<Path>>(path: P) -> Result<TermInfo, Error> {
- Self::_from_path(path.as_ref())
- }
- // Keep the metadata small
- fn _from_path(path: &Path) -> Result<TermInfo, Error> {
- let file = File::open(path).map_err(Error::IoError)?;
- let mut reader = BufReader::new(file);
- parse(&mut reader, false).map_err(Error::MalformedTerminfo)
- }
-}
-
-pub mod searcher;
-
-/// TermInfo format parsing.
-pub mod parser {
- //! ncurses-compatible compiled terminfo format parsing (term(5))
- pub mod compiled;
-}
-pub mod parm;
-
-
-fn cap_for_attr(attr: Attr) -> &'static str {
- match attr {
- Attr::Bold => "bold",
- Attr::Dim => "dim",
- Attr::Italic(true) => "sitm",
- Attr::Italic(false) => "ritm",
- Attr::Underline(true) => "smul",
- Attr::Underline(false) => "rmul",
- Attr::Blink => "blink",
- Attr::Standout(true) => "smso",
- Attr::Standout(false) => "rmso",
- Attr::Reverse => "rev",
- Attr::Secure => "invis",
- Attr::ForegroundColor(_) => "setaf",
- Attr::BackgroundColor(_) => "setab",
- }
-}
-
-/// A Terminal that knows how many colors it supports, with a reference to its
-/// parsed Terminfo database record.
-pub struct TerminfoTerminal<T> {
- num_colors: u16,
- out: T,
- ti: TermInfo,
-}
-
-impl<T: Write + Send> Terminal for TerminfoTerminal<T> {
- type Output = T;
- fn fg(&mut self, color: color::Color) -> io::Result<bool> {
- let color = self.dim_if_necessary(color);
- if self.num_colors > color {
- return self.apply_cap("setaf", &[Param::Number(color as i32)]);
- }
- Ok(false)
- }
-
- fn bg(&mut self, color: color::Color) -> io::Result<bool> {
- let color = self.dim_if_necessary(color);
- if self.num_colors > color {
- return self.apply_cap("setab", &[Param::Number(color as i32)]);
- }
- Ok(false)
- }
-
- fn attr(&mut self, attr: Attr) -> io::Result<bool> {
- match attr {
- Attr::ForegroundColor(c) => self.fg(c),
- Attr::BackgroundColor(c) => self.bg(c),
- _ => self.apply_cap(cap_for_attr(attr), &[]),
- }
- }
-
- fn supports_attr(&self, attr: Attr) -> bool {
- match attr {
- Attr::ForegroundColor(_) | Attr::BackgroundColor(_) => self.num_colors > 0,
- _ => {
- let cap = cap_for_attr(attr);
- self.ti.strings.get(cap).is_some()
- }
- }
- }
-
- fn reset(&mut self) -> io::Result<bool> {
- // are there any terminals that have color/attrs and not sgr0?
- // Try falling back to sgr, then op
- let cmd = match ["sgr0", "sgr", "op"]
- .iter()
- .filter_map(|cap| self.ti.strings.get(*cap))
- .next() {
- Some(op) => {
- match expand(&op, &[], &mut Variables::new()) {
- Ok(cmd) => cmd,
- Err(e) => return Err(io::Error::new(io::ErrorKind::InvalidData, e)),
- }
- }
- None => return Ok(false),
- };
- self.out.write_all(&cmd).and(Ok(true))
- }
-
- fn get_ref(&self) -> &T {
- &self.out
- }
-
- fn get_mut(&mut self) -> &mut T {
- &mut self.out
- }
-
- fn into_inner(self) -> T
- where Self: Sized
- {
- self.out
- }
-}
-
-impl<T: Write + Send> TerminfoTerminal<T> {
- /// Creates a new TerminfoTerminal with the given TermInfo and Write.
- pub fn new_with_terminfo(out: T, terminfo: TermInfo) -> TerminfoTerminal<T> {
- let nc = if terminfo.strings.contains_key("setaf") &&
- terminfo.strings.contains_key("setab") {
- terminfo.numbers.get("colors").map_or(0, |&n| n)
- } else {
- 0
- };
-
- TerminfoTerminal {
- out,
- ti: terminfo,
- num_colors: nc,
- }
- }
-
- /// Creates a new TerminfoTerminal for the current environment with the given Write.
- ///
- /// Returns `None` when the terminfo cannot be found or parsed.
- pub fn new(out: T) -> Option<TerminfoTerminal<T>> {
- TermInfo::from_env().map(move |ti| TerminfoTerminal::new_with_terminfo(out, ti)).ok()
- }
-
- fn dim_if_necessary(&self, color: color::Color) -> color::Color {
- if color >= self.num_colors && color >= 8 && color < 16 {
- color - 8
- } else {
- color
- }
- }
-
- fn apply_cap(&mut self, cmd: &str, params: &[Param]) -> io::Result<bool> {
- match self.ti.strings.get(cmd) {
- Some(cmd) => {
- match expand(&cmd, params, &mut Variables::new()) {
- Ok(s) => self.out.write_all(&s).and(Ok(true)),
- Err(e) => Err(io::Error::new(io::ErrorKind::InvalidData, e)),
- }
- }
- None => Ok(false),
- }
- }
-}
-
-
-impl<T: Write> Write for TerminfoTerminal<T> {
- fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
- self.out.write(buf)
- }
-
- fn flush(&mut self) -> io::Result<()> {
- self.out.flush()
- }
-}
diff --git a/src/libterm/terminfo/parm.rs b/src/libterm/terminfo/parm.rs
deleted file mode 100644
index 28229bd..0000000
--- a/src/libterm/terminfo/parm.rs
+++ /dev/null
@@ -1,669 +0,0 @@
-//! Parameterized string expansion
-
-use self::Param::*;
-use self::States::*;
-
-use std::iter::repeat;
-
-#[derive(Clone, Copy, PartialEq)]
-enum States {
- Nothing,
- Percent,
- SetVar,
- GetVar,
- PushParam,
- CharConstant,
- CharClose,
- IntConstant(i32),
- FormatPattern(Flags, FormatState),
- SeekIfElse(usize),
- SeekIfElsePercent(usize),
- SeekIfEnd(usize),
- SeekIfEndPercent(usize),
-}
-
-#[derive(Copy, PartialEq, Clone)]
-enum FormatState {
- Flags,
- Width,
- Precision,
-}
-
-/// Types of parameters a capability can use
-#[allow(missing_docs)]
-#[derive(Clone)]
-pub enum Param {
- Words(String),
- Number(i32),
-}
-
-/// Container for static and dynamic variable arrays
-pub struct Variables {
- /// Static variables A-Z
- sta_va: [Param; 26],
- /// Dynamic variables a-z
- dyn_va: [Param; 26],
-}
-
-impl Variables {
- /// Returns a new zero-initialized Variables
- pub fn new() -> Variables {
- Variables {
- sta_va: [
- Number(0), Number(0), Number(0), Number(0), Number(0), Number(0), Number(0),
- Number(0), Number(0), Number(0), Number(0), Number(0), Number(0), Number(0),
- Number(0), Number(0), Number(0), Number(0), Number(0), Number(0), Number(0),
- Number(0), Number(0), Number(0), Number(0), Number(0)
- ],
- dyn_va: [
- Number(0), Number(0), Number(0), Number(0), Number(0), Number(0), Number(0),
- Number(0), Number(0), Number(0), Number(0), Number(0), Number(0), Number(0),
- Number(0), Number(0), Number(0), Number(0), Number(0), Number(0), Number(0),
- Number(0), Number(0), Number(0), Number(0), Number(0)
- ],
- }
- }
-}
-
-/// Expand a parameterized capability
-///
-/// # Arguments
-/// * `cap` - string to expand
-/// * `params` - vector of params for %p1 etc
-/// * `vars` - Variables struct for %Pa etc
-///
-/// To be compatible with ncurses, `vars` should be the same between calls to `expand` for
-/// multiple capabilities for the same terminal.
-pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec<u8>, String> {
- let mut state = Nothing;
-
- // expanded cap will only rarely be larger than the cap itself
- let mut output = Vec::with_capacity(cap.len());
-
- let mut stack: Vec<Param> = Vec::new();
-
- // Copy parameters into a local vector for mutability
- let mut mparams = [Number(0), Number(0), Number(0), Number(0), Number(0), Number(0),
- Number(0), Number(0), Number(0)];
- for (dst, src) in mparams.iter_mut().zip(params.iter()) {
- *dst = (*src).clone();
- }
-
- for &c in cap.iter() {
- let cur = c as char;
- let mut old_state = state;
- match state {
- Nothing => {
- if cur == '%' {
- state = Percent;
- } else {
- output.push(c);
- }
- }
- Percent => {
- match cur {
- '%' => {
- output.push(c);
- state = Nothing
- }
- 'c' => {
- match stack.pop() {
- // if c is 0, use 0200 (128) for ncurses compatibility
- Some(Number(0)) => output.push(128u8),
- // Don't check bounds. ncurses just casts and truncates.
- Some(Number(c)) => output.push(c as u8),
- Some(_) => return Err("a non-char was used with %c".to_string()),
- None => return Err("stack is empty".to_string()),
- }
- }
- 'p' => state = PushParam,
- 'P' => state = SetVar,
- 'g' => state = GetVar,
- '\'' => state = CharConstant,
- '{' => state = IntConstant(0),
- 'l' => {
- match stack.pop() {
- Some(Words(s)) => stack.push(Number(s.len() as i32)),
- Some(_) => return Err("a non-str was used with %l".to_string()),
- None => return Err("stack is empty".to_string()),
- }
- }
- '+' | '-' | '/' | '*' | '^' | '&' | '|' | 'm' => {
- match (stack.pop(), stack.pop()) {
- (Some(Number(y)), Some(Number(x))) => {
- stack.push(Number(match cur {
- '+' => x + y,
- '-' => x - y,
- '*' => x * y,
- '/' => x / y,
- '|' => x | y,
- '&' => x & y,
- '^' => x ^ y,
- 'm' => x % y,
- _ => unreachable!("All cases handled"),
- }))
- }
- (Some(_), Some(_)) => {
- return Err(format!("non-numbers on stack with {}", cur))
- }
- _ => return Err("stack is empty".to_string()),
- }
- }
- '=' | '>' | '<' | 'A' | 'O' => {
- match (stack.pop(), stack.pop()) {
- (Some(Number(y)), Some(Number(x))) => {
- stack.push(Number(if match cur {
- '=' => x == y,
- '<' => x < y,
- '>' => x > y,
- 'A' => x > 0 && y > 0,
- 'O' => x > 0 || y > 0,
- _ => unreachable!(),
- } {
- 1
- } else {
- 0
- }))
- }
- (Some(_), Some(_)) => {
- return Err(format!("non-numbers on stack with {}", cur))
- }
- _ => return Err("stack is empty".to_string()),
- }
- }
- '!' | '~' => {
- match stack.pop() {
- Some(Number(x)) => {
- stack.push(Number(match cur {
- '!' if x > 0 => 0,
- '!' => 1,
- '~' => !x,
- _ => unreachable!(),
- }))
- }
- Some(_) => return Err(format!("non-numbers on stack with {}", cur)),
- None => return Err("stack is empty".to_string()),
- }
- }
- 'i' => {
- match (&mparams[0], &mparams[1]) {
- (&Number(x), &Number(y)) => {
- mparams[0] = Number(x + 1);
- mparams[1] = Number(y + 1);
- }
- _ => {
- return Err("first two params not numbers with %i".to_string())
- }
- }
- }
-
- // printf-style support for %doxXs
- 'd' | 'o' | 'x' | 'X' | 's' => {
- if let Some(arg) = stack.pop() {
- let flags = Flags::new();
- let res = format(arg, FormatOp::from_char(cur), flags)?;
- output.extend(res.iter().cloned());
- } else {
- return Err("stack is empty".to_string());
- }
- }
- ':' | '#' | ' ' | '.' | '0'..='9' => {
- let mut flags = Flags::new();
- let mut fstate = FormatState::Flags;
- match cur {
- ':' => (),
- '#' => flags.alternate = true,
- ' ' => flags.space = true,
- '.' => fstate = FormatState::Precision,
- '0'..='9' => {
- flags.width = cur as usize - '0' as usize;
- fstate = FormatState::Width;
- }
- _ => unreachable!(),
- }
- state = FormatPattern(flags, fstate);
- }
-
- // conditionals
- '?' => (),
- 't' => {
- match stack.pop() {
- Some(Number(0)) => state = SeekIfElse(0),
- Some(Number(_)) => (),
- Some(_) => {
- return Err("non-number on stack with conditional".to_string())
- }
- None => return Err("stack is empty".to_string()),
- }
- }
- 'e' => state = SeekIfEnd(0),
- ';' => (),
- _ => return Err(format!("unrecognized format option {}", cur)),
- }
- }
- PushParam => {
- // params are 1-indexed
- stack.push(mparams[match cur.to_digit(10) {
- Some(d) => d as usize - 1,
- None => return Err("bad param number".to_string()),
- }]
- .clone());
- }
- SetVar => {
- if cur >= 'A' && cur <= 'Z' {
- if let Some(arg) = stack.pop() {
- let idx = (cur as u8) - b'A';
- vars.sta_va[idx as usize] = arg;
- } else {
- return Err("stack is empty".to_string());
- }
- } else if cur >= 'a' && cur <= 'z' {
- if let Some(arg) = stack.pop() {
- let idx = (cur as u8) - b'a';
- vars.dyn_va[idx as usize] = arg;
- } else {
- return Err("stack is empty".to_string());
- }
- } else {
- return Err("bad variable name in %P".to_string());
- }
- }
- GetVar => {
- if cur >= 'A' && cur <= 'Z' {
- let idx = (cur as u8) - b'A';
- stack.push(vars.sta_va[idx as usize].clone());
- } else if cur >= 'a' && cur <= 'z' {
- let idx = (cur as u8) - b'a';
- stack.push(vars.dyn_va[idx as usize].clone());
- } else {
- return Err("bad variable name in %g".to_string());
- }
- }
- CharConstant => {
- stack.push(Number(c as i32));
- state = CharClose;
- }
- CharClose => {
- if cur != '\'' {
- return Err("malformed character constant".to_string());
- }
- }
- IntConstant(i) => {
- if cur == '}' {
- stack.push(Number(i));
- state = Nothing;
- } else if let Some(digit) = cur.to_digit(10) {
- match i.checked_mul(10).and_then(|i_ten| i_ten.checked_add(digit as i32)) {
- Some(i) => {
- state = IntConstant(i);
- old_state = Nothing;
- }
- None => return Err("int constant too large".to_string()),
- }
- } else {
- return Err("bad int constant".to_string());
- }
- }
- FormatPattern(ref mut flags, ref mut fstate) => {
- old_state = Nothing;
- match (*fstate, cur) {
- (_, 'd') | (_, 'o') | (_, 'x') | (_, 'X') | (_, 's') => {
- if let Some(arg) = stack.pop() {
- let res = format(arg, FormatOp::from_char(cur), *flags)?;
- output.extend(res.iter().cloned());
- // will cause state to go to Nothing
- old_state = FormatPattern(*flags, *fstate);
- } else {
- return Err("stack is empty".to_string());
- }
- }
- (FormatState::Flags, '#') => {
- flags.alternate = true;
- }
- (FormatState::Flags, '-') => {
- flags.left = true;
- }
- (FormatState::Flags, '+') => {
- flags.sign = true;
- }
- (FormatState::Flags, ' ') => {
- flags.space = true;
- }
- (FormatState::Flags, '0'..='9') => {
- flags.width = cur as usize - '0' as usize;
- *fstate = FormatState::Width;
- }
- (FormatState::Flags, '.') => {
- *fstate = FormatState::Precision;
- }
- (FormatState::Width, '0'..='9') => {
- let old = flags.width;
- flags.width = flags.width * 10 + (cur as usize - '0' as usize);
- if flags.width < old {
- return Err("format width overflow".to_string());
- }
- }
- (FormatState::Width, '.') => {
- *fstate = FormatState::Precision;
- }
- (FormatState::Precision, '0'..='9') => {
- let old = flags.precision;
- flags.precision = flags.precision * 10 + (cur as usize - '0' as usize);
- if flags.precision < old {
- return Err("format precision overflow".to_string());
- }
- }
- _ => return Err("invalid format specifier".to_string()),
- }
- }
- SeekIfElse(level) => {
- if cur == '%' {
- state = SeekIfElsePercent(level);
- }
- old_state = Nothing;
- }
- SeekIfElsePercent(level) => {
- if cur == ';' {
- if level == 0 {
- state = Nothing;
- } else {
- state = SeekIfElse(level - 1);
- }
- } else if cur == 'e' && level == 0 {
- state = Nothing;
- } else if cur == '?' {
- state = SeekIfElse(level + 1);
- } else {
- state = SeekIfElse(level);
- }
- }
- SeekIfEnd(level) => {
- if cur == '%' {
- state = SeekIfEndPercent(level);
- }
- old_state = Nothing;
- }
- SeekIfEndPercent(level) => {
- if cur == ';' {
- if level == 0 {
- state = Nothing;
- } else {
- state = SeekIfEnd(level - 1);
- }
- } else if cur == '?' {
- state = SeekIfEnd(level + 1);
- } else {
- state = SeekIfEnd(level);
- }
- }
- }
- if state == old_state {
- state = Nothing;
- }
- }
- Ok(output)
-}
-
-#[derive(Copy, PartialEq, Clone)]
-struct Flags {
- width: usize,
- precision: usize,
- alternate: bool,
- left: bool,
- sign: bool,
- space: bool,
-}
-
-impl Flags {
- fn new() -> Flags {
- Flags {
- width: 0,
- precision: 0,
- alternate: false,
- left: false,
- sign: false,
- space: false,
- }
- }
-}
-
-#[derive(Copy, Clone)]
-enum FormatOp {
- Digit,
- Octal,
- LowerHex,
- UpperHex,
- String,
-}
-
-impl FormatOp {
- fn from_char(c: char) -> FormatOp {
- match c {
- 'd' => FormatOp::Digit,
- 'o' => FormatOp::Octal,
- 'x' => FormatOp::LowerHex,
- 'X' => FormatOp::UpperHex,
- 's' => FormatOp::String,
- _ => panic!("bad FormatOp char"),
- }
- }
- fn to_char(self) -> char {
- match self {
- FormatOp::Digit => 'd',
- FormatOp::Octal => 'o',
- FormatOp::LowerHex => 'x',
- FormatOp::UpperHex => 'X',
- FormatOp::String => 's',
- }
- }
-}
-
-fn format(val: Param, op: FormatOp, flags: Flags) -> Result<Vec<u8>, String> {
- let mut s = match val {
- Number(d) => {
- match op {
- FormatOp::Digit => {
- if flags.sign {
- format!("{:+01$}", d, flags.precision)
- } else if d < 0 {
- // C doesn't take sign into account in precision calculation.
- format!("{:01$}", d, flags.precision + 1)
- } else if flags.space {
- format!(" {:01$}", d, flags.precision)
- } else {
- format!("{:01$}", d, flags.precision)
- }
- }
- FormatOp::Octal => {
- if flags.alternate {
- // Leading octal zero counts against precision.
- format!("0{:01$o}", d, flags.precision.saturating_sub(1))
- } else {
- format!("{:01$o}", d, flags.precision)
- }
- }
- FormatOp::LowerHex => {
- if flags.alternate && d != 0 {
- format!("0x{:01$x}", d, flags.precision)
- } else {
- format!("{:01$x}", d, flags.precision)
- }
- }
- FormatOp::UpperHex => {
- if flags.alternate && d != 0 {
- format!("0X{:01$X}", d, flags.precision)
- } else {
- format!("{:01$X}", d, flags.precision)
- }
- }
- FormatOp::String => return Err("non-number on stack with %s".to_string()),
- }
- .into_bytes()
- }
- Words(s) => {
- match op {
- FormatOp::String => {
- let mut s = s.into_bytes();
- if flags.precision > 0 && flags.precision < s.len() {
- s.truncate(flags.precision);
- }
- s
- }
- _ => return Err(format!("non-string on stack with %{}", op.to_char())),
- }
- }
- };
- if flags.width > s.len() {
- let n = flags.width - s.len();
- if flags.left {
- s.extend(repeat(b' ').take(n));
- } else {
- let mut s_ = Vec::with_capacity(flags.width);
- s_.extend(repeat(b' ').take(n));
- s_.extend(s.into_iter());
- s = s_;
- }
- }
- Ok(s)
-}
-
-#[cfg(test)]
-mod test {
- use super::{expand, Variables};
- use super::Param::{self, Words, Number};
- use std::result::Result::Ok;
-
- #[test]
- fn test_basic_setabf() {
- let s = b"\\E[48;5;%p1%dm";
- assert_eq!(expand(s, &[Number(1)], &mut Variables::new()).unwrap(),
- "\\E[48;5;1m".bytes().collect::<Vec<_>>());
- }
-
- #[test]
- fn test_multiple_int_constants() {
- assert_eq!(expand(b"%{1}%{2}%d%d", &[], &mut Variables::new()).unwrap(),
- "21".bytes().collect::<Vec<_>>());
- }
-
- #[test]
- fn test_op_i() {
- let mut vars = Variables::new();
- assert_eq!(expand(b"%p1%d%p2%d%p3%d%i%p1%d%p2%d%p3%d",
- &[Number(1), Number(2), Number(3)],
- &mut vars),
- Ok("123233".bytes().collect::<Vec<_>>()));
- assert_eq!(expand(b"%p1%d%p2%d%i%p1%d%p2%d", &[], &mut vars),
- Ok("0011".bytes().collect::<Vec<_>>()));
- }
-
- #[test]
- fn test_param_stack_failure_conditions() {
- let mut varstruct = Variables::new();
- let vars = &mut varstruct;
- fn get_res(fmt: &str,
- cap: &str,
- params: &[Param],
- vars: &mut Variables)
- -> Result<Vec<u8>, String> {
- let mut u8v: Vec<_> = fmt.bytes().collect();
- u8v.extend(cap.as_bytes().iter().map(|&b| b));
- expand(&u8v, params, vars)
- }
-
- let caps = ["%d", "%c", "%s", "%Pa", "%l", "%!", "%~"];
- for &cap in caps.iter() {
- let res = get_res("", cap, &[], vars);
- assert!(res.is_err(),
- "Op {} succeeded incorrectly with 0 stack entries",
- cap);
- let p = if cap == "%s" || cap == "%l" {
- Words("foo".to_string())
- } else {
- Number(97)
- };
- let res = get_res("%p1", cap, &[p], vars);
- assert!(res.is_ok(),
- "Op {} failed with 1 stack entry: {}",
- cap,
- res.unwrap_err());
- }
- let caps = ["%+", "%-", "%*", "%/", "%m", "%&", "%|", "%A", "%O"];
- for &cap in caps.iter() {
- let res = expand(cap.as_bytes(), &[], vars);
- assert!(res.is_err(),
- "Binop {} succeeded incorrectly with 0 stack entries",
- cap);
- let res = get_res("%{1}", cap, &[], vars);
- assert!(res.is_err(),
- "Binop {} succeeded incorrectly with 1 stack entry",
- cap);
- let res = get_res("%{1}%{2}", cap, &[], vars);
- assert!(res.is_ok(),
- "Binop {} failed with 2 stack entries: {}",
- cap,
- res.unwrap_err());
- }
- }
-
- #[test]
- fn test_push_bad_param() {
- assert!(expand(b"%pa", &[], &mut Variables::new()).is_err());
- }
-
- #[test]
- fn test_comparison_ops() {
- let v = [('<', [1u8, 0u8, 0u8]), ('=', [0u8, 1u8, 0u8]), ('>', [0u8, 0u8, 1u8])];
- for &(op, bs) in v.iter() {
- let s = format!("%{{1}}%{{2}}%{}%d", op);
- let res = expand(s.as_bytes(), &[], &mut Variables::new());
- assert!(res.is_ok(), res.unwrap_err());
- assert_eq!(res.unwrap(), vec![b'0' + bs[0]]);
- let s = format!("%{{1}}%{{1}}%{}%d", op);
- let res = expand(s.as_bytes(), &[], &mut Variables::new());
- assert!(res.is_ok(), res.unwrap_err());
- assert_eq!(res.unwrap(), vec![b'0' + bs[1]]);
- let s = format!("%{{2}}%{{1}}%{}%d", op);
- let res = expand(s.as_bytes(), &[], &mut Variables::new());
- assert!(res.is_ok(), res.unwrap_err());
- assert_eq!(res.unwrap(), vec![b'0' + bs[2]]);
- }
- }
-
- #[test]
- fn test_conditionals() {
- let mut vars = Variables::new();
- let s = b"\\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m";
- let res = expand(s, &[Number(1)], &mut vars);
- assert!(res.is_ok(), res.unwrap_err());
- assert_eq!(res.unwrap(), "\\E[31m".bytes().collect::<Vec<_>>());
- let res = expand(s, &[Number(8)], &mut vars);
- assert!(res.is_ok(), res.unwrap_err());
- assert_eq!(res.unwrap(), "\\E[90m".bytes().collect::<Vec<_>>());
- let res = expand(s, &[Number(42)], &mut vars);
- assert!(res.is_ok(), res.unwrap_err());
- assert_eq!(res.unwrap(), "\\E[38;5;42m".bytes().collect::<Vec<_>>());
- }
-
- #[test]
- fn test_format() {
- let mut varstruct = Variables::new();
- let vars = &mut varstruct;
- assert_eq!(expand(b"%p1%s%p2%2s%p3%2s%p4%.2s",
- &[Words("foo".to_string()),
- Words("foo".to_string()),
- Words("f".to_string()),
- Words("foo".to_string())],
- vars),
- Ok("foofoo ffo".bytes().collect::<Vec<_>>()));
- assert_eq!(expand(b"%p1%:-4.2s", &[Words("foo".to_string())], vars),
- Ok("fo ".bytes().collect::<Vec<_>>()));
-
- assert_eq!(expand(b"%p1%d%p1%.3d%p1%5d%p1%:+d", &[Number(1)], vars),
- Ok("1001 1+1".bytes().collect::<Vec<_>>()));
- assert_eq!(expand(b"%p1%o%p1%#o%p2%6.4x%p2%#6.4X",
- &[Number(15), Number(27)],
- vars),
- Ok("17017 001b0X001B".bytes().collect::<Vec<_>>()));
- }
-}
diff --git a/src/libterm/terminfo/parser/compiled.rs b/src/libterm/terminfo/parser/compiled.rs
deleted file mode 100644
index 05a8c94..0000000
--- a/src/libterm/terminfo/parser/compiled.rs
+++ /dev/null
@@ -1,346 +0,0 @@
-#![allow(non_upper_case_globals, missing_docs)]
-
-//! ncurses-compatible compiled terminfo format parsing (term(5))
-
-use std::collections::HashMap;
-use std::io;
-use std::io::prelude::*;
-use super::super::TermInfo;
-
-// These are the orders ncurses uses in its compiled format (as of 5.9). Not sure if portable.
-
-#[rustfmt::skip]
-pub static boolfnames: &[&str] = &["auto_left_margin", "auto_right_margin",
- "no_esc_ctlc", "ceol_standout_glitch", "eat_newline_glitch", "erase_overstrike", "generic_type",
- "hard_copy", "has_meta_key", "has_status_line", "insert_null_glitch", "memory_above",
- "memory_below", "move_insert_mode", "move_standout_mode", "over_strike", "status_line_esc_ok",
- "dest_tabs_magic_smso", "tilde_glitch", "transparent_underline", "xon_xoff", "needs_xon_xoff",
- "prtr_silent", "hard_cursor", "non_rev_rmcup", "no_pad_char", "non_dest_scroll_region",
- "can_change", "back_color_erase", "hue_lightness_saturation", "col_addr_glitch",
- "cr_cancels_micro_mode", "has_print_wheel", "row_addr_glitch", "semi_auto_right_margin",
- "cpi_changes_res", "lpi_changes_res", "backspaces_with_bs", "crt_no_scrolling",
- "no_correctly_working_cr", "gnu_has_meta_key", "linefeed_is_newline", "has_hardware_tabs",
- "return_does_clr_eol"];
-
-#[rustfmt::skip]
-pub static boolnames: &[&str] = &["bw", "am", "xsb", "xhp", "xenl", "eo",
- "gn", "hc", "km", "hs", "in", "db", "da", "mir", "msgr", "os", "eslok", "xt", "hz", "ul", "xon",
- "nxon", "mc5i", "chts", "nrrmc", "npc", "ndscr", "ccc", "bce", "hls", "xhpa", "crxm", "daisy",
- "xvpa", "sam", "cpix", "lpix", "OTbs", "OTns", "OTnc", "OTMT", "OTNL", "OTpt", "OTxr"];
-
-#[rustfmt::skip]
-pub static numfnames: &[&str] = &[ "columns", "init_tabs", "lines",
- "lines_of_memory", "magic_cookie_glitch", "padding_baud_rate", "virtual_terminal",
- "width_status_line", "num_labels", "label_height", "label_width", "max_attributes",
- "maximum_windows", "max_colors", "max_pairs", "no_color_video", "buffer_capacity",
- "dot_vert_spacing", "dot_horz_spacing", "max_micro_address", "max_micro_jump", "micro_col_size",
- "micro_line_size", "number_of_pins", "output_res_char", "output_res_line",
- "output_res_horz_inch", "output_res_vert_inch", "print_rate", "wide_char_size", "buttons",
- "bit_image_entwining", "bit_image_type", "magic_cookie_glitch_ul", "carriage_return_delay",
- "new_line_delay", "backspace_delay", "horizontal_tab_delay", "number_of_function_keys"];
-
-#[rustfmt::skip]
-pub static numnames: &[&str] = &[ "cols", "it", "lines", "lm", "xmc", "pb",
- "vt", "wsl", "nlab", "lh", "lw", "ma", "wnum", "colors", "pairs", "ncv", "bufsz", "spinv",
- "spinh", "maddr", "mjump", "mcs", "mls", "npins", "orc", "orl", "orhi", "orvi", "cps", "widcs",
- "btns", "bitwin", "bitype", "UTug", "OTdC", "OTdN", "OTdB", "OTdT", "OTkn"];
-
-#[rustfmt::skip]
-pub static stringfnames: &[&str] = &[ "back_tab", "bell", "carriage_return",
- "change_scroll_region", "clear_all_tabs", "clear_screen", "clr_eol", "clr_eos",
- "column_address", "command_character", "cursor_address", "cursor_down", "cursor_home",
- "cursor_invisible", "cursor_left", "cursor_mem_address", "cursor_normal", "cursor_right",
- "cursor_to_ll", "cursor_up", "cursor_visible", "delete_character", "delete_line",
- "dis_status_line", "down_half_line", "enter_alt_charset_mode", "enter_blink_mode",
- "enter_bold_mode", "enter_ca_mode", "enter_delete_mode", "enter_dim_mode", "enter_insert_mode",
- "enter_secure_mode", "enter_protected_mode", "enter_reverse_mode", "enter_standout_mode",
- "enter_underline_mode", "erase_chars", "exit_alt_charset_mode", "exit_attribute_mode",
- "exit_ca_mode", "exit_delete_mode", "exit_insert_mode", "exit_standout_mode",
- "exit_underline_mode", "flash_screen", "form_feed", "from_status_line", "init_1string",
- "init_2string", "init_3string", "init_file", "insert_character", "insert_line",
- "insert_padding", "key_backspace", "key_catab", "key_clear", "key_ctab", "key_dc", "key_dl",
- "key_down", "key_eic", "key_eol", "key_eos", "key_f0", "key_f1", "key_f10", "key_f2", "key_f3",
- "key_f4", "key_f5", "key_f6", "key_f7", "key_f8", "key_f9", "key_home", "key_ic", "key_il",
- "key_left", "key_ll", "key_npage", "key_ppage", "key_right", "key_sf", "key_sr", "key_stab",
- "key_up", "keypad_local", "keypad_xmit", "lab_f0", "lab_f1", "lab_f10", "lab_f2", "lab_f3",
- "lab_f4", "lab_f5", "lab_f6", "lab_f7", "lab_f8", "lab_f9", "meta_off", "meta_on", "newline",
- "pad_char", "parm_dch", "parm_delete_line", "parm_down_cursor", "parm_ich", "parm_index",
- "parm_insert_line", "parm_left_cursor", "parm_right_cursor", "parm_rindex", "parm_up_cursor",
- "pkey_key", "pkey_local", "pkey_xmit", "print_screen", "prtr_off", "prtr_on", "repeat_char",
- "reset_1string", "reset_2string", "reset_3string", "reset_file", "restore_cursor",
- "row_address", "save_cursor", "scroll_forward", "scroll_reverse", "set_attributes", "set_tab",
- "set_window", "tab", "to_status_line", "underline_char", "up_half_line", "init_prog", "key_a1",
- "key_a3", "key_b2", "key_c1", "key_c3", "prtr_non", "char_padding", "acs_chars", "plab_norm",
- "key_btab", "enter_xon_mode", "exit_xon_mode", "enter_am_mode", "exit_am_mode", "xon_character",
- "xoff_character", "ena_acs", "label_on", "label_off", "key_beg", "key_cancel", "key_close",
- "key_command", "key_copy", "key_create", "key_end", "key_enter", "key_exit", "key_find",
- "key_help", "key_mark", "key_message", "key_move", "key_next", "key_open", "key_options",
- "key_previous", "key_print", "key_redo", "key_reference", "key_refresh", "key_replace",
- "key_restart", "key_resume", "key_save", "key_suspend", "key_undo", "key_sbeg", "key_scancel",
- "key_scommand", "key_scopy", "key_screate", "key_sdc", "key_sdl", "key_select", "key_send",
- "key_seol", "key_sexit", "key_sfind", "key_shelp", "key_shome", "key_sic", "key_sleft",
- "key_smessage", "key_smove", "key_snext", "key_soptions", "key_sprevious", "key_sprint",
- "key_sredo", "key_sreplace", "key_sright", "key_srsume", "key_ssave", "key_ssuspend",
- "key_sundo", "req_for_input", "key_f11", "key_f12", "key_f13", "key_f14", "key_f15", "key_f16",
- "key_f17", "key_f18", "key_f19", "key_f20", "key_f21", "key_f22", "key_f23", "key_f24",
- "key_f25", "key_f26", "key_f27", "key_f28", "key_f29", "key_f30", "key_f31", "key_f32",
- "key_f33", "key_f34", "key_f35", "key_f36", "key_f37", "key_f38", "key_f39", "key_f40",
- "key_f41", "key_f42", "key_f43", "key_f44", "key_f45", "key_f46", "key_f47", "key_f48",
- "key_f49", "key_f50", "key_f51", "key_f52", "key_f53", "key_f54", "key_f55", "key_f56",
- "key_f57", "key_f58", "key_f59", "key_f60", "key_f61", "key_f62", "key_f63", "clr_bol",
- "clear_margins", "set_left_margin", "set_right_margin", "label_format", "set_clock",
- "display_clock", "remove_clock", "create_window", "goto_window", "hangup", "dial_phone",
- "quick_dial", "tone", "pulse", "flash_hook", "fixed_pause", "wait_tone", "user0", "user1",
- "user2", "user3", "user4", "user5", "user6", "user7", "user8", "user9", "orig_pair",
- "orig_colors", "initialize_color", "initialize_pair", "set_color_pair", "set_foreground",
- "set_background", "change_char_pitch", "change_line_pitch", "change_res_horz",
- "change_res_vert", "define_char", "enter_doublewide_mode", "enter_draft_quality",
- "enter_italics_mode", "enter_leftward_mode", "enter_micro_mode", "enter_near_letter_quality",
- "enter_normal_quality", "enter_shadow_mode", "enter_subscript_mode", "enter_superscript_mode",
- "enter_upward_mode", "exit_doublewide_mode", "exit_italics_mode", "exit_leftward_mode",
- "exit_micro_mode", "exit_shadow_mode", "exit_subscript_mode", "exit_superscript_mode",
- "exit_upward_mode", "micro_column_address", "micro_down", "micro_left", "micro_right",
- "micro_row_address", "micro_up", "order_of_pins", "parm_down_micro", "parm_left_micro",
- "parm_right_micro", "parm_up_micro", "select_char_set", "set_bottom_margin",
- "set_bottom_margin_parm", "set_left_margin_parm", "set_right_margin_parm", "set_top_margin",
- "set_top_margin_parm", "start_bit_image", "start_char_set_def", "stop_bit_image",
- "stop_char_set_def", "subscript_characters", "superscript_characters", "these_cause_cr",
- "zero_motion", "char_set_names", "key_mouse", "mouse_info", "req_mouse_pos", "get_mouse",
- "set_a_foreground", "set_a_background", "pkey_plab", "device_type", "code_set_init",
- "set0_des_seq", "set1_des_seq", "set2_des_seq", "set3_des_seq", "set_lr_margin",
- "set_tb_margin", "bit_image_repeat", "bit_image_newline", "bit_image_carriage_return",
- "color_names", "define_bit_image_region", "end_bit_image_region", "set_color_band",
- "set_page_length", "display_pc_char", "enter_pc_charset_mode", "exit_pc_charset_mode",
- "enter_scancode_mode", "exit_scancode_mode", "pc_term_options", "scancode_escape",
- "alt_scancode_esc", "enter_horizontal_hl_mode", "enter_left_hl_mode", "enter_low_hl_mode",
- "enter_right_hl_mode", "enter_top_hl_mode", "enter_vertical_hl_mode", "set_a_attributes",
- "set_pglen_inch", "termcap_init2", "termcap_reset", "linefeed_if_not_lf", "backspace_if_not_bs",
- "other_non_function_keys", "arrow_key_map", "acs_ulcorner", "acs_llcorner", "acs_urcorner",
- "acs_lrcorner", "acs_ltee", "acs_rtee", "acs_btee", "acs_ttee", "acs_hline", "acs_vline",
- "acs_plus", "memory_lock", "memory_unlock", "box_chars_1"];
-
-#[rustfmt::skip]
-pub static stringnames: &[&str] = &[ "cbt", "_", "cr", "csr", "tbc", "clear",
- "_", "_", "hpa", "cmdch", "cup", "cud1", "home", "civis", "cub1", "mrcup", "cnorm", "cuf1",
- "ll", "cuu1", "cvvis", "dch1", "dl1", "dsl", "hd", "smacs", "blink", "bold", "smcup", "smdc",
- "dim", "smir", "invis", "prot", "rev", "smso", "smul", "ech", "rmacs", "sgr0", "rmcup", "rmdc",
- "rmir", "rmso", "rmul", "flash", "ff", "fsl", "is1", "is2", "is3", "if", "ich1", "il1", "ip",
- "kbs", "ktbc", "kclr", "kctab", "_", "_", "kcud1", "_", "_", "_", "_", "_", "_", "_", "_", "_",
- "_", "_", "_", "_", "_", "khome", "_", "_", "kcub1", "_", "knp", "kpp", "kcuf1", "_", "_",
- "khts", "_", "rmkx", "smkx", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "rmm", "_",
- "_", "pad", "dch", "dl", "cud", "ich", "indn", "il", "cub", "cuf", "rin", "cuu", "pfkey",
- "pfloc", "pfx", "mc0", "mc4", "_", "rep", "rs1", "rs2", "rs3", "rf", "rc", "vpa", "sc", "ind",
- "ri", "sgr", "_", "wind", "_", "tsl", "uc", "hu", "iprog", "_", "_", "_", "_", "_", "mc5p",
- "rmp", "acsc", "pln", "kcbt", "smxon", "rmxon", "smam", "rmam", "xonc", "xoffc", "_", "smln",
- "rmln", "_", "kcan", "kclo", "kcmd", "kcpy", "kcrt", "_", "kent", "kext", "kfnd", "khlp",
- "kmrk", "kmsg", "kmov", "knxt", "kopn", "kopt", "kprv", "kprt", "krdo", "kref", "krfr", "krpl",
- "krst", "kres", "ksav", "kspd", "kund", "kBEG", "kCAN", "kCMD", "kCPY", "kCRT", "_", "_",
- "kslt", "kEND", "kEOL", "kEXT", "kFND", "kHLP", "kHOM", "_", "kLFT", "kMSG", "kMOV", "kNXT",
- "kOPT", "kPRV", "kPRT", "kRDO", "kRPL", "kRIT", "kRES", "kSAV", "kSPD", "kUND", "rfi", "_", "_",
- "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_",
- "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_",
- "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_",
- "dclk", "rmclk", "cwin", "wingo", "_", "dial", "qdial", "_", "_", "hook", "pause", "wait", "_",
- "_", "_", "_", "_", "_", "_", "_", "_", "_", "op", "oc", "initc", "initp", "scp", "setf",
- "setb", "cpi", "lpi", "chr", "cvr", "defc", "swidm", "sdrfq", "sitm", "slm", "smicm", "snlq",
- "snrmq", "sshm", "ssubm", "ssupm", "sum", "rwidm", "ritm", "rlm", "rmicm", "rshm", "rsubm",
- "rsupm", "rum", "mhpa", "mcud1", "mcub1", "mcuf1", "mvpa", "mcuu1", "porder", "mcud", "mcub",
- "mcuf", "mcuu", "scs", "smgb", "smgbp", "smglp", "smgrp", "smgt", "smgtp", "sbim", "scsd",
- "rbim", "rcsd", "subcs", "supcs", "docr", "zerom", "csnm", "kmous", "minfo", "reqmp", "getm",
- "setaf", "setab", "pfxl", "devt", "csin", "s0ds", "s1ds", "s2ds", "s3ds", "smglr", "smgtb",
- "birep", "binel", "bicr", "colornm", "defbi", "endbi", "setcolor", "slines", "dispc", "smpch",
- "rmpch", "smsc", "rmsc", "pctrm", "scesc", "scesa", "ehhlm", "elhlm", "elohlm", "erhlm",
- "ethlm", "evhlm", "sgr1", "slength", "OTi2", "OTrs", "OTnl", "OTbs", "OTko", "OTma", "OTG2",
- "OTG3", "OTG1", "OTG4", "OTGR", "OTGL", "OTGU", "OTGD", "OTGH", "OTGV", "OTGC", "meml", "memu",
- "box1"];
-
-fn read_le_u16(r: &mut dyn io::Read) -> io::Result<u16> {
- let mut b = [0; 2];
- let mut amt = 0;
- while amt < b.len() {
- match r.read(&mut b[amt..])? {
- 0 => return Err(io::Error::new(io::ErrorKind::Other, "end of file")),
- n => amt += n,
- }
- }
- Ok((b[0] as u16) | ((b[1] as u16) << 8))
-}
-
-fn read_byte(r: &mut dyn io::Read) -> io::Result<u8> {
- match r.bytes().next() {
- Some(s) => s,
- None => Err(io::Error::new(io::ErrorKind::Other, "end of file")),
- }
-}
-
-/// Parse a compiled terminfo entry, using long capability names if `longnames`
-/// is true
-pub fn parse(file: &mut dyn io::Read, longnames: bool) -> Result<TermInfo, String> {
- macro_rules! t( ($e:expr) => (
- match $e {
- Ok(e) => e,
- Err(e) => return Err(e.to_string())
- }
- ) );
-
- let (bnames, snames, nnames) = if longnames {
- (boolfnames, stringfnames, numfnames)
- } else {
- (boolnames, stringnames, numnames)
- };
-
- // Check magic number
- let magic = t!(read_le_u16(file));
- if magic != 0x011A {
- return Err(format!("invalid magic number: expected {:x}, found {:x}",
- 0x011A,
- magic));
- }
-
- // According to the spec, these fields must be >= -1 where -1 means that the feature is not
- // supported. Using 0 instead of -1 works because we skip sections with length 0.
- macro_rules! read_nonneg {
- () => {{
- match t!(read_le_u16(file)) as i16 {
- n if n >= 0 => n as usize,
- -1 => 0,
- _ => return Err("incompatible file: length fields must be >= -1".to_string()),
- }
- }}
- }
-
- let names_bytes = read_nonneg!();
- let bools_bytes = read_nonneg!();
- let numbers_count = read_nonneg!();
- let string_offsets_count = read_nonneg!();
- let string_table_bytes = read_nonneg!();
-
- if names_bytes == 0 {
- return Err("incompatible file: names field must be at least 1 byte wide".to_string());
- }
-
- if bools_bytes > boolnames.len() {
- return Err("incompatible file: more booleans than expected".to_string());
- }
-
- if numbers_count > numnames.len() {
- return Err("incompatible file: more numbers than expected".to_string());
- }
-
- if string_offsets_count > stringnames.len() {
- return Err("incompatible file: more string offsets than expected".to_string());
- }
-
- // don't read NUL
- let mut bytes = Vec::new();
- t!(file.take((names_bytes - 1) as u64).read_to_end(&mut bytes));
- let names_str = match String::from_utf8(bytes) {
- Ok(s) => s,
- Err(_) => return Err("input not utf-8".to_string()),
- };
-
- let term_names: Vec<String> = names_str.split('|')
- .map(|s| s.to_string())
- .collect();
- // consume NUL
- if t!(read_byte(file)) != b'\0' {
- return Err("incompatible file: missing null terminator for names section".to_string());
- }
-
- let bools_map: HashMap<String, bool> = t! {
- (0..bools_bytes).filter_map(|i| match read_byte(file) {
- Err(e) => Some(Err(e)),
- Ok(1) => Some(Ok((bnames[i].to_string(), true))),
- Ok(_) => None
- }).collect()
- };
-
- if (bools_bytes + names_bytes) % 2 == 1 {
- t!(read_byte(file)); // compensate for padding
- }
-
- let numbers_map: HashMap<String, u16> = t! {
- (0..numbers_count).filter_map(|i| match read_le_u16(file) {
- Ok(0xFFFF) => None,
- Ok(n) => Some(Ok((nnames[i].to_string(), n))),
- Err(e) => Some(Err(e))
- }).collect()
- };
-
- let string_map: HashMap<String, Vec<u8>> = if string_offsets_count > 0 {
- let string_offsets: Vec<u16> = t!((0..string_offsets_count)
- .map(|_| read_le_u16(file))
- .collect());
-
- let mut string_table = Vec::new();
- t!(file.take(string_table_bytes as u64).read_to_end(&mut string_table));
-
- t!(string_offsets.into_iter().enumerate().filter(|&(_, offset)| {
- // non-entry
- offset != 0xFFFF
- }).map(|(i, offset)| {
- let offset = offset as usize;
-
- let name = if snames[i] == "_" {
- stringfnames[i]
- } else {
- snames[i]
- };
-
- if offset == 0xFFFE {
- // undocumented: FFFE indicates cap@, which means the capability is not present
- // unsure if the handling for this is correct
- return Ok((name.to_string(), Vec::new()));
- }
-
- // Find the offset of the NUL we want to go to
- let nulpos = string_table[offset..string_table_bytes].iter().position(|&b| b == 0);
- match nulpos {
- Some(len) => Ok((name.to_string(), string_table[offset..offset + len].to_vec())),
- None => Err("invalid file: missing NUL in string_table".to_string()),
- }
- }).collect())
- } else {
- HashMap::new()
- };
-
- // And that's all there is to it
- Ok(TermInfo {
- names: term_names,
- bools: bools_map,
- numbers: numbers_map,
- strings: string_map,
- })
-}
-
-/// Creates a dummy TermInfo struct for msys terminals
-pub fn msys_terminfo() -> TermInfo {
- let mut strings = HashMap::new();
- strings.insert("sgr0".to_string(), b"\x1B[0m".to_vec());
- strings.insert("bold".to_string(), b"\x1B[1m".to_vec());
- strings.insert("setaf".to_string(), b"\x1B[3%p1%dm".to_vec());
- strings.insert("setab".to_string(), b"\x1B[4%p1%dm".to_vec());
-
- let mut numbers = HashMap::new();
- numbers.insert("colors".to_string(), 8u16);
-
- TermInfo {
- names: vec!["cygwin".to_string()], // msys is a fork of an older cygwin version
- bools: HashMap::new(),
- numbers,
- strings,
- }
-}
-
-#[cfg(test)]
-mod test {
-
- use super::{boolnames, boolfnames, numnames, numfnames, stringnames, stringfnames};
-
- #[test]
- fn test_veclens() {
- assert_eq!(boolfnames.len(), boolnames.len());
- assert_eq!(numfnames.len(), numnames.len());
- assert_eq!(stringfnames.len(), stringnames.len());
- }
-}
diff --git a/src/libterm/terminfo/searcher.rs b/src/libterm/terminfo/searcher.rs
deleted file mode 100644
index 0b17ed3..0000000
--- a/src/libterm/terminfo/searcher.rs
+++ /dev/null
@@ -1,84 +0,0 @@
-//! ncurses-compatible database discovery.
-//!
-//! Does not support hashed database, only filesystem!
-
-use std::env;
-use std::fs;
-use std::path::PathBuf;
-
-/// Return path to database entry for `term`
-#[allow(deprecated)]
-pub fn get_dbpath_for_term(term: &str) -> Option<PathBuf> {
- let mut dirs_to_search = Vec::new();
- let first_char = term.chars().next()?;
-
- // Find search directory
- if let Some(dir) = env::var_os("TERMINFO") {
- dirs_to_search.push(PathBuf::from(dir));
- }
-
- if let Ok(dirs) = env::var("TERMINFO_DIRS") {
- for i in dirs.split(':') {
- if i == "" {
- dirs_to_search.push(PathBuf::from("/usr/share/terminfo"));
- } else {
- dirs_to_search.push(PathBuf::from(i));
- }
- }
- } else {
- // Found nothing in TERMINFO_DIRS, use the default paths:
- // According to /etc/terminfo/README, after looking at
- // ~/.terminfo, ncurses will search /etc/terminfo, then
- // /lib/terminfo, and eventually /usr/share/terminfo.
- // On Haiku the database can be found at /boot/system/data/terminfo
- if let Some(mut homedir) = env::home_dir() {
- homedir.push(".terminfo");
- dirs_to_search.push(homedir)
- }
-
- dirs_to_search.push(PathBuf::from("/etc/terminfo"));
- dirs_to_search.push(PathBuf::from("/lib/terminfo"));
- dirs_to_search.push(PathBuf::from("/usr/share/terminfo"));
- dirs_to_search.push(PathBuf::from("/boot/system/data/terminfo"));
- }
-
- // Look for the terminal in all of the search directories
- for mut p in dirs_to_search {
- if fs::metadata(&p).is_ok() {
- p.push(&first_char.to_string());
- p.push(&term);
- if fs::metadata(&p).is_ok() {
- return Some(p);
- }
- p.pop();
- p.pop();
-
- // on some installations the dir is named after the hex of the char
- // (e.g., macOS)
- p.push(&format!("{:x}", first_char as usize));
- p.push(term);
- if fs::metadata(&p).is_ok() {
- return Some(p);
- }
- }
- }
- None
-}
-
-#[test]
-#[ignore = "buildbots don't have ncurses installed and I can't mock everything I need"]
-fn test_get_dbpath_for_term() {
- // woefully inadequate test coverage
- // note: current tests won't work with non-standard terminfo hierarchies (e.g., macOS's)
- use std::env;
- // FIXME (#9639): This needs to handle non-utf8 paths
- fn x(t: &str) -> String {
- let p = get_dbpath_for_term(t).expect("no terminfo entry found");
- p.to_str().unwrap().to_string()
- }
- assert!(x("screen") == "/usr/share/terminfo/s/screen");
- assert!(get_dbpath_for_term("") == None);
- env::set_var("TERMINFO_DIRS", ":");
- assert!(x("screen") == "/usr/share/terminfo/s/screen");
- env::remove_var("TERMINFO_DIRS");
-}
diff --git a/src/libterm/win.rs b/src/libterm/win.rs
deleted file mode 100644
index 6d42b01..0000000
--- a/src/libterm/win.rs
+++ /dev/null
@@ -1,203 +0,0 @@
-//! Windows console handling
-
-// FIXME (#13400): this is only a tiny fraction of the Windows console api
-
-extern crate libc;
-
-use std::io;
-use std::io::prelude::*;
-
-use crate::Attr;
-use crate::color;
-use crate::Terminal;
-
-/// A Terminal implementation that uses the Win32 Console API.
-pub struct WinConsole<T> {
- buf: T,
- def_foreground: color::Color,
- def_background: color::Color,
- foreground: color::Color,
- background: color::Color,
-}
-
-type WORD = u16;
-type DWORD = u32;
-type BOOL = i32;
-type HANDLE = *mut u8;
-
-#[allow(non_snake_case)]
-#[repr(C)]
-struct CONSOLE_SCREEN_BUFFER_INFO {
- dwSize: [libc::c_short; 2],
- dwCursorPosition: [libc::c_short; 2],
- wAttributes: WORD,
- srWindow: [libc::c_short; 4],
- dwMaximumWindowSize: [libc::c_short; 2],
-}
-
-#[allow(non_snake_case)]
-#[link(name = "kernel32")]
-extern "system" {
- fn SetConsoleTextAttribute(handle: HANDLE, attr: WORD) -> BOOL;
- fn GetStdHandle(which: DWORD) -> HANDLE;
- fn GetConsoleScreenBufferInfo(handle: HANDLE, info: *mut CONSOLE_SCREEN_BUFFER_INFO) -> BOOL;
-}
-
-fn color_to_bits(color: color::Color) -> u16 {
- // magic numbers from mingw-w64's wincon.h
-
- let bits = match color % 8 {
- color::BLACK => 0,
- color::BLUE => 0x1,
- color::GREEN => 0x2,
- color::RED => 0x4,
- color::YELLOW => 0x2 | 0x4,
- color::MAGENTA => 0x1 | 0x4,
- color::CYAN => 0x1 | 0x2,
- color::WHITE => 0x1 | 0x2 | 0x4,
- _ => unreachable!(),
- };
-
- if color >= 8 {
- bits | 0x8
- } else {
- bits
- }
-}
-
-fn bits_to_color(bits: u16) -> color::Color {
- let color = match bits & 0x7 {
- 0 => color::BLACK,
- 0x1 => color::BLUE,
- 0x2 => color::GREEN,
- 0x4 => color::RED,
- 0x6 => color::YELLOW,
- 0x5 => color::MAGENTA,
- 0x3 => color::CYAN,
- 0x7 => color::WHITE,
- _ => unreachable!(),
- };
-
- color | (bits & 0x8) // copy the hi-intensity bit
-}
-
-impl<T: Write + Send + 'static> WinConsole<T> {
- fn apply(&mut self) {
- let _unused = self.buf.flush();
- let mut accum: WORD = 0;
- accum |= color_to_bits(self.foreground);
- accum |= color_to_bits(self.background) << 4;
-
- unsafe {
- // Magic -11 means stdout, from
- // http://msdn.microsoft.com/en-us/library/windows/desktop/ms683231%28v=vs.85%29.aspx
- //
- // You may be wondering, "but what about stderr?", and the answer
- // to that is that setting terminal attributes on the stdout
- // handle also sets them for stderr, since they go to the same
- // terminal! Admittedly, this is fragile, since stderr could be
- // redirected to a different console. This is good enough for
- // rustc though. See #13400.
- let out = GetStdHandle(-11i32 as DWORD);
- SetConsoleTextAttribute(out, accum);
- }
- }
-
- /// Returns `None` whenever the terminal cannot be created for some reason.
- pub fn new(out: T) -> io::Result<WinConsole<T>> {
- let fg;
- let bg;
- unsafe {
- let mut buffer_info = ::std::mem::uninitialized();
- if GetConsoleScreenBufferInfo(GetStdHandle(-11i32 as DWORD), &mut buffer_info) != 0 {
- fg = bits_to_color(buffer_info.wAttributes);
- bg = bits_to_color(buffer_info.wAttributes >> 4);
- } else {
- fg = color::WHITE;
- bg = color::BLACK;
- }
- }
- Ok(WinConsole {
- buf: out,
- def_foreground: fg,
- def_background: bg,
- foreground: fg,
- background: bg,
- })
- }
-}
-
-impl<T: Write> Write for WinConsole<T> {
- fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
- self.buf.write(buf)
- }
-
- fn flush(&mut self) -> io::Result<()> {
- self.buf.flush()
- }
-}
-
-impl<T: Write + Send + 'static> Terminal for WinConsole<T> {
- type Output = T;
-
- fn fg(&mut self, color: color::Color) -> io::Result<bool> {
- self.foreground = color;
- self.apply();
-
- Ok(true)
- }
-
- fn bg(&mut self, color: color::Color) -> io::Result<bool> {
- self.background = color;
- self.apply();
-
- Ok(true)
- }
-
- fn attr(&mut self, attr: Attr) -> io::Result<bool> {
- match attr {
- Attr::ForegroundColor(f) => {
- self.foreground = f;
- self.apply();
- Ok(true)
- }
- Attr::BackgroundColor(b) => {
- self.background = b;
- self.apply();
- Ok(true)
- }
- _ => Ok(false),
- }
- }
-
- fn supports_attr(&self, attr: Attr) -> bool {
- // it claims support for underscore and reverse video, but I can't get
- // it to do anything -cmr
- match attr {
- Attr::ForegroundColor(_) | Attr::BackgroundColor(_) => true,
- _ => false,
- }
- }
-
- fn reset(&mut self) -> io::Result<bool> {
- self.foreground = self.def_foreground;
- self.background = self.def_background;
- self.apply();
-
- Ok(true)
- }
-
- fn get_ref(&self) -> &T {
- &self.buf
- }
-
- fn get_mut(&mut self) -> &mut T {
- &mut self.buf
- }
-
- fn into_inner(self) -> T
- where Self: Sized
- {
- self.buf
- }
-}
diff --git a/src/libtest/Cargo.toml b/src/libtest/Cargo.toml
index 10bdd6e..26ac788 100644
--- a/src/libtest/Cargo.toml
+++ b/src/libtest/Cargo.toml
@@ -10,8 +10,7 @@
crate-type = ["dylib", "rlib"]
[dependencies]
-getopts = "0.2"
-term = { path = "../libterm" }
+libtest = { version = "0.0.1" }
# not actually used but needed to always have proc_macro in the sysroot
proc_macro = { path = "../libproc_macro" }
diff --git a/src/libtest/README.md b/src/libtest/README.md
new file mode 100644
index 0000000..6d9fe30
--- /dev/null
+++ b/src/libtest/README.md
@@ -0,0 +1,13 @@
+WIP - stable libtest
+===
+
+The migration of libtest to stable Rust is currently in progress.
+
+You can find libtest at: https://github.com/rust-lang/libtest . If you need to
+make a change:
+
+* perform the change there,
+* do a new crates.io release, and
+* send a PR to rust-lang/rust bumping the libtest version.
+
+The roadmap of the migration is being tracked here: https://github.com/rust-lang/libtest/issues/2
diff --git a/src/libtest/formatters/json.rs b/src/libtest/formatters/json.rs
deleted file mode 100644
index a06497f..0000000
--- a/src/libtest/formatters/json.rs
+++ /dev/null
@@ -1,208 +0,0 @@
-use super::*;
-
-pub(crate) struct JsonFormatter<T> {
- out: OutputLocation<T>,
-}
-
-impl<T: Write> JsonFormatter<T> {
- pub fn new(out: OutputLocation<T>) -> Self {
- Self { out }
- }
-
- fn write_message(&mut self, s: &str) -> io::Result<()> {
- assert!(!s.contains('\n'));
-
- self.out.write_all(s.as_ref())?;
- self.out.write_all(b"\n")
- }
-
- fn write_event(
- &mut self,
- ty: &str,
- name: &str,
- evt: &str,
- extra: Option<String>,
- ) -> io::Result<()> {
- if let Some(extras) = extra {
- self.write_message(&*format!(
- r#"{{ "type": "{}", "name": "{}", "event": "{}", {} }}"#,
- ty, name, evt, extras
- ))
- } else {
- self.write_message(&*format!(
- r#"{{ "type": "{}", "name": "{}", "event": "{}" }}"#,
- ty, name, evt
- ))
- }
- }
-}
-
-impl<T: Write> OutputFormatter for JsonFormatter<T> {
- fn write_run_start(&mut self, test_count: usize) -> io::Result<()> {
- self.write_message(&*format!(
- r#"{{ "type": "suite", "event": "started", "test_count": {} }}"#,
- test_count
- ))
- }
-
- fn write_test_start(&mut self, desc: &TestDesc) -> io::Result<()> {
- self.write_message(&*format!(
- r#"{{ "type": "test", "event": "started", "name": "{}" }}"#,
- desc.name
- ))
- }
-
- fn write_result(
- &mut self,
- desc: &TestDesc,
- result: &TestResult,
- stdout: &[u8],
- ) -> io::Result<()> {
- match *result {
- TrOk => self.write_event("test", desc.name.as_slice(), "ok", None),
-
- TrFailed => {
- let extra_data = if stdout.len() > 0 {
- Some(format!(
- r#""stdout": "{}""#,
- EscapedString(String::from_utf8_lossy(stdout))
- ))
- } else {
- None
- };
-
- self.write_event("test", desc.name.as_slice(), "failed", extra_data)
- }
-
- TrFailedMsg(ref m) => self.write_event(
- "test",
- desc.name.as_slice(),
- "failed",
- Some(format!(r#""message": "{}""#, EscapedString(m))),
- ),
-
- TrIgnored => self.write_event("test", desc.name.as_slice(), "ignored", None),
-
- TrAllowedFail => {
- self.write_event("test", desc.name.as_slice(), "allowed_failure", None)
- }
-
- TrBench(ref bs) => {
- let median = bs.ns_iter_summ.median as usize;
- let deviation = (bs.ns_iter_summ.max - bs.ns_iter_summ.min) as usize;
-
- let mbps = if bs.mb_s == 0 {
- String::new()
- } else {
- format!(r#", "mib_per_second": {}"#, bs.mb_s)
- };
-
- let line = format!(
- "{{ \"type\": \"bench\", \
- \"name\": \"{}\", \
- \"median\": {}, \
- \"deviation\": {}{} }}",
- desc.name, median, deviation, mbps
- );
-
- self.write_message(&*line)
- }
- }
- }
-
- fn write_timeout(&mut self, desc: &TestDesc) -> io::Result<()> {
- self.write_message(&*format!(
- r#"{{ "type": "test", "event": "timeout", "name": "{}" }}"#,
- desc.name
- ))
- }
-
- fn write_run_finish(&mut self, state: &ConsoleTestState) -> io::Result<bool> {
- self.write_message(&*format!(
- "{{ \"type\": \"suite\", \
- \"event\": \"{}\", \
- \"passed\": {}, \
- \"failed\": {}, \
- \"allowed_fail\": {}, \
- \"ignored\": {}, \
- \"measured\": {}, \
- \"filtered_out\": {} }}",
- if state.failed == 0 { "ok" } else { "failed" },
- state.passed,
- state.failed + state.allowed_fail,
- state.allowed_fail,
- state.ignored,
- state.measured,
- state.filtered_out
- ))?;
-
- Ok(state.failed == 0)
- }
-}
-
-/// A formatting utility used to print strings with characters in need of escaping.
-/// Base code taken form `libserialize::json::escape_str`
-struct EscapedString<S: AsRef<str>>(S);
-
-impl<S: AsRef<str>> ::std::fmt::Display for EscapedString<S> {
- fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
- let mut start = 0;
-
- for (i, byte) in self.0.as_ref().bytes().enumerate() {
- let escaped = match byte {
- b'"' => "\\\"",
- b'\\' => "\\\\",
- b'\x00' => "\\u0000",
- b'\x01' => "\\u0001",
- b'\x02' => "\\u0002",
- b'\x03' => "\\u0003",
- b'\x04' => "\\u0004",
- b'\x05' => "\\u0005",
- b'\x06' => "\\u0006",
- b'\x07' => "\\u0007",
- b'\x08' => "\\b",
- b'\t' => "\\t",
- b'\n' => "\\n",
- b'\x0b' => "\\u000b",
- b'\x0c' => "\\f",
- b'\r' => "\\r",
- b'\x0e' => "\\u000e",
- b'\x0f' => "\\u000f",
- b'\x10' => "\\u0010",
- b'\x11' => "\\u0011",
- b'\x12' => "\\u0012",
- b'\x13' => "\\u0013",
- b'\x14' => "\\u0014",
- b'\x15' => "\\u0015",
- b'\x16' => "\\u0016",
- b'\x17' => "\\u0017",
- b'\x18' => "\\u0018",
- b'\x19' => "\\u0019",
- b'\x1a' => "\\u001a",
- b'\x1b' => "\\u001b",
- b'\x1c' => "\\u001c",
- b'\x1d' => "\\u001d",
- b'\x1e' => "\\u001e",
- b'\x1f' => "\\u001f",
- b'\x7f' => "\\u007f",
- _ => {
- continue;
- }
- };
-
- if start < i {
- f.write_str(&self.0.as_ref()[start..i])?;
- }
-
- f.write_str(escaped)?;
-
- start = i + 1;
- }
-
- if start != self.0.as_ref().len() {
- f.write_str(&self.0.as_ref()[start..])?;
- }
-
- Ok(())
- }
-}
diff --git a/src/libtest/formatters/mod.rs b/src/libtest/formatters/mod.rs
deleted file mode 100644
index be5f6a6..0000000
--- a/src/libtest/formatters/mod.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-use super::*;
-
-mod pretty;
-mod json;
-mod terse;
-
-pub(crate) use self::pretty::PrettyFormatter;
-pub(crate) use self::json::JsonFormatter;
-pub(crate) use self::terse::TerseFormatter;
-
-pub(crate) trait OutputFormatter {
- fn write_run_start(&mut self, test_count: usize) -> io::Result<()>;
- fn write_test_start(&mut self, desc: &TestDesc) -> io::Result<()>;
- fn write_timeout(&mut self, desc: &TestDesc) -> io::Result<()>;
- fn write_result(
- &mut self,
- desc: &TestDesc,
- result: &TestResult,
- stdout: &[u8],
- ) -> io::Result<()>;
- fn write_run_finish(&mut self, state: &ConsoleTestState) -> io::Result<bool>;
-}
diff --git a/src/libtest/formatters/pretty.rs b/src/libtest/formatters/pretty.rs
deleted file mode 100644
index 4af0042..0000000
--- a/src/libtest/formatters/pretty.rs
+++ /dev/null
@@ -1,232 +0,0 @@
-use super::*;
-
-pub(crate) struct PrettyFormatter<T> {
- out: OutputLocation<T>,
- use_color: bool,
-
- /// Number of columns to fill when aligning names
- max_name_len: usize,
-
- is_multithreaded: bool,
-}
-
-impl<T: Write> PrettyFormatter<T> {
- pub fn new(
- out: OutputLocation<T>,
- use_color: bool,
- max_name_len: usize,
- is_multithreaded: bool,
- ) -> Self {
- PrettyFormatter {
- out,
- use_color,
- max_name_len,
- is_multithreaded,
- }
- }
-
- #[cfg(test)]
- pub fn output_location(&self) -> &OutputLocation<T> {
- &self.out
- }
-
- pub fn write_ok(&mut self) -> io::Result<()> {
- self.write_short_result("ok", term::color::GREEN)
- }
-
- pub fn write_failed(&mut self) -> io::Result<()> {
- self.write_short_result("FAILED", term::color::RED)
- }
-
- pub fn write_ignored(&mut self) -> io::Result<()> {
- self.write_short_result("ignored", term::color::YELLOW)
- }
-
- pub fn write_allowed_fail(&mut self) -> io::Result<()> {
- self.write_short_result("FAILED (allowed)", term::color::YELLOW)
- }
-
- pub fn write_bench(&mut self) -> io::Result<()> {
- self.write_pretty("bench", term::color::CYAN)
- }
-
- pub fn write_short_result(
- &mut self,
- result: &str,
- color: term::color::Color,
- ) -> io::Result<()> {
- self.write_pretty(result, color)?;
- self.write_plain("\n")
- }
-
- pub fn write_pretty(&mut self, word: &str, color: term::color::Color) -> io::Result<()> {
- match self.out {
- Pretty(ref mut term) => {
- if self.use_color {
- term.fg(color)?;
- }
- term.write_all(word.as_bytes())?;
- if self.use_color {
- term.reset()?;
- }
- term.flush()
- }
- Raw(ref mut stdout) => {
- stdout.write_all(word.as_bytes())?;
- stdout.flush()
- }
- }
- }
-
- pub fn write_plain<S: AsRef<str>>(&mut self, s: S) -> io::Result<()> {
- let s = s.as_ref();
- self.out.write_all(s.as_bytes())?;
- self.out.flush()
- }
-
- pub fn write_successes(&mut self, state: &ConsoleTestState) -> io::Result<()> {
- self.write_plain("\nsuccesses:\n")?;
- let mut successes = Vec::new();
- let mut stdouts = String::new();
- for &(ref f, ref stdout) in &state.not_failures {
- successes.push(f.name.to_string());
- if !stdout.is_empty() {
- stdouts.push_str(&format!("---- {} stdout ----\n", f.name));
- let output = String::from_utf8_lossy(stdout);
- stdouts.push_str(&output);
- stdouts.push_str("\n");
- }
- }
- if !stdouts.is_empty() {
- self.write_plain("\n")?;
- self.write_plain(&stdouts)?;
- }
-
- self.write_plain("\nsuccesses:\n")?;
- successes.sort();
- for name in &successes {
- self.write_plain(&format!(" {}\n", name))?;
- }
- Ok(())
- }
-
- pub fn write_failures(&mut self, state: &ConsoleTestState) -> io::Result<()> {
- self.write_plain("\nfailures:\n")?;
- let mut failures = Vec::new();
- let mut fail_out = String::new();
- for &(ref f, ref stdout) in &state.failures {
- failures.push(f.name.to_string());
- if !stdout.is_empty() {
- fail_out.push_str(&format!("---- {} stdout ----\n", f.name));
- let output = String::from_utf8_lossy(stdout);
- fail_out.push_str(&output);
- fail_out.push_str("\n");
- }
- }
- if !fail_out.is_empty() {
- self.write_plain("\n")?;
- self.write_plain(&fail_out)?;
- }
-
- self.write_plain("\nfailures:\n")?;
- failures.sort();
- for name in &failures {
- self.write_plain(&format!(" {}\n", name))?;
- }
- Ok(())
- }
-
- fn write_test_name(&mut self, desc: &TestDesc) -> io::Result<()> {
- let name = desc.padded_name(self.max_name_len, desc.name.padding());
- self.write_plain(&format!("test {} ... ", name))?;
-
- Ok(())
- }
-}
-
-impl<T: Write> OutputFormatter for PrettyFormatter<T> {
- fn write_run_start(&mut self, test_count: usize) -> io::Result<()> {
- let noun = if test_count != 1 { "tests" } else { "test" };
- self.write_plain(&format!("\nrunning {} {}\n", test_count, noun))
- }
-
- fn write_test_start(&mut self, desc: &TestDesc) -> io::Result<()> {
- // When running tests concurrently, we should not print
- // the test's name as the result will be mis-aligned.
- // When running the tests serially, we print the name here so
- // that the user can see which test hangs.
- if !self.is_multithreaded {
- self.write_test_name(desc)?;
- }
-
- Ok(())
- }
-
- fn write_result(&mut self, desc: &TestDesc, result: &TestResult, _: &[u8]) -> io::Result<()> {
- if self.is_multithreaded {
- self.write_test_name(desc)?;
- }
-
- match *result {
- TrOk => self.write_ok(),
- TrFailed | TrFailedMsg(_) => self.write_failed(),
- TrIgnored => self.write_ignored(),
- TrAllowedFail => self.write_allowed_fail(),
- TrBench(ref bs) => {
- self.write_bench()?;
- self.write_plain(&format!(": {}\n", fmt_bench_samples(bs)))
- }
- }
- }
-
- fn write_timeout(&mut self, desc: &TestDesc) -> io::Result<()> {
- if self.is_multithreaded {
- self.write_test_name(desc)?;
- }
-
- self.write_plain(&format!(
- "test {} has been running for over {} seconds\n",
- desc.name, TEST_WARN_TIMEOUT_S
- ))
- }
-
- fn write_run_finish(&mut self, state: &ConsoleTestState) -> io::Result<bool> {
- if state.options.display_output {
- self.write_successes(state)?;
- }
- let success = state.failed == 0;
- if !success {
- self.write_failures(state)?;
- }
-
- self.write_plain("\ntest result: ")?;
-
- if success {
- // There's no parallelism at this point so it's safe to use color
- self.write_pretty("ok", term::color::GREEN)?;
- } else {
- self.write_pretty("FAILED", term::color::RED)?;
- }
-
- let s = if state.allowed_fail > 0 {
- format!(
- ". {} passed; {} failed ({} allowed); {} ignored; {} measured; {} filtered out\n\n",
- state.passed,
- state.failed + state.allowed_fail,
- state.allowed_fail,
- state.ignored,
- state.measured,
- state.filtered_out
- )
- } else {
- format!(
- ". {} passed; {} failed; {} ignored; {} measured; {} filtered out\n\n",
- state.passed, state.failed, state.ignored, state.measured, state.filtered_out
- )
- };
-
- self.write_plain(&s)?;
-
- Ok(success)
- }
-}
diff --git a/src/libtest/formatters/terse.rs b/src/libtest/formatters/terse.rs
deleted file mode 100644
index 1400fba..0000000
--- a/src/libtest/formatters/terse.rs
+++ /dev/null
@@ -1,235 +0,0 @@
-use super::*;
-
-pub(crate) struct TerseFormatter<T> {
- out: OutputLocation<T>,
- use_color: bool,
- is_multithreaded: bool,
- /// Number of columns to fill when aligning names
- max_name_len: usize,
-
- test_count: usize,
- total_test_count: usize,
-}
-
-impl<T: Write> TerseFormatter<T> {
- pub fn new(
- out: OutputLocation<T>,
- use_color: bool,
- max_name_len: usize,
- is_multithreaded: bool,
- ) -> Self {
- TerseFormatter {
- out,
- use_color,
- max_name_len,
- is_multithreaded,
- test_count: 0,
- total_test_count: 0, // initialized later, when write_run_start is called
- }
- }
-
- pub fn write_ok(&mut self) -> io::Result<()> {
- self.write_short_result(".", term::color::GREEN)
- }
-
- pub fn write_failed(&mut self) -> io::Result<()> {
- self.write_short_result("F", term::color::RED)
- }
-
- pub fn write_ignored(&mut self) -> io::Result<()> {
- self.write_short_result("i", term::color::YELLOW)
- }
-
- pub fn write_allowed_fail(&mut self) -> io::Result<()> {
- self.write_short_result("a", term::color::YELLOW)
- }
-
- pub fn write_bench(&mut self) -> io::Result<()> {
- self.write_pretty("bench", term::color::CYAN)
- }
-
- pub fn write_short_result(
- &mut self,
- result: &str,
- color: term::color::Color,
- ) -> io::Result<()> {
- self.write_pretty(result, color)?;
- if self.test_count % QUIET_MODE_MAX_COLUMN == QUIET_MODE_MAX_COLUMN - 1 {
- // we insert a new line every 100 dots in order to flush the
- // screen when dealing with line-buffered output (e.g., piping to
- // `stamp` in the rust CI).
- let out = format!(" {}/{}\n", self.test_count+1, self.total_test_count);
- self.write_plain(&out)?;
- }
-
- self.test_count += 1;
- Ok(())
- }
-
- pub fn write_pretty(&mut self, word: &str, color: term::color::Color) -> io::Result<()> {
- match self.out {
- Pretty(ref mut term) => {
- if self.use_color {
- term.fg(color)?;
- }
- term.write_all(word.as_bytes())?;
- if self.use_color {
- term.reset()?;
- }
- term.flush()
- }
- Raw(ref mut stdout) => {
- stdout.write_all(word.as_bytes())?;
- stdout.flush()
- }
- }
- }
-
- pub fn write_plain<S: AsRef<str>>(&mut self, s: S) -> io::Result<()> {
- let s = s.as_ref();
- self.out.write_all(s.as_bytes())?;
- self.out.flush()
- }
-
- pub fn write_outputs(&mut self, state: &ConsoleTestState) -> io::Result<()> {
- self.write_plain("\nsuccesses:\n")?;
- let mut successes = Vec::new();
- let mut stdouts = String::new();
- for &(ref f, ref stdout) in &state.not_failures {
- successes.push(f.name.to_string());
- if !stdout.is_empty() {
- stdouts.push_str(&format!("---- {} stdout ----\n", f.name));
- let output = String::from_utf8_lossy(stdout);
- stdouts.push_str(&output);
- stdouts.push_str("\n");
- }
- }
- if !stdouts.is_empty() {
- self.write_plain("\n")?;
- self.write_plain(&stdouts)?;
- }
-
- self.write_plain("\nsuccesses:\n")?;
- successes.sort();
- for name in &successes {
- self.write_plain(&format!(" {}\n", name))?;
- }
- Ok(())
- }
-
- pub fn write_failures(&mut self, state: &ConsoleTestState) -> io::Result<()> {
- self.write_plain("\nfailures:\n")?;
- let mut failures = Vec::new();
- let mut fail_out = String::new();
- for &(ref f, ref stdout) in &state.failures {
- failures.push(f.name.to_string());
- if !stdout.is_empty() {
- fail_out.push_str(&format!("---- {} stdout ----\n", f.name));
- let output = String::from_utf8_lossy(stdout);
- fail_out.push_str(&output);
- fail_out.push_str("\n");
- }
- }
- if !fail_out.is_empty() {
- self.write_plain("\n")?;
- self.write_plain(&fail_out)?;
- }
-
- self.write_plain("\nfailures:\n")?;
- failures.sort();
- for name in &failures {
- self.write_plain(&format!(" {}\n", name))?;
- }
- Ok(())
- }
-
- fn write_test_name(&mut self, desc: &TestDesc) -> io::Result<()> {
- let name = desc.padded_name(self.max_name_len, desc.name.padding());
- self.write_plain(&format!("test {} ... ", name))?;
-
- Ok(())
- }
-}
-
-impl<T: Write> OutputFormatter for TerseFormatter<T> {
- fn write_run_start(&mut self, test_count: usize) -> io::Result<()> {
- self.total_test_count = test_count;
- let noun = if test_count != 1 { "tests" } else { "test" };
- self.write_plain(&format!("\nrunning {} {}\n", test_count, noun))
- }
-
- fn write_test_start(&mut self, desc: &TestDesc) -> io::Result<()> {
- // Remnants from old libtest code that used the padding value
- // in order to indicate benchmarks.
- // When running benchmarks, terse-mode should still print their name as if
- // it is the Pretty formatter.
- if !self.is_multithreaded && desc.name.padding() == PadOnRight {
- self.write_test_name(desc)?;
- }
-
- Ok(())
- }
-
- fn write_result(&mut self, desc: &TestDesc, result: &TestResult, _: &[u8]) -> io::Result<()> {
- match *result {
- TrOk => self.write_ok(),
- TrFailed | TrFailedMsg(_) => self.write_failed(),
- TrIgnored => self.write_ignored(),
- TrAllowedFail => self.write_allowed_fail(),
- TrBench(ref bs) => {
- if self.is_multithreaded {
- self.write_test_name(desc)?;
- }
- self.write_bench()?;
- self.write_plain(&format!(": {}\n", fmt_bench_samples(bs)))
- }
- }
- }
-
- fn write_timeout(&mut self, desc: &TestDesc) -> io::Result<()> {
- self.write_plain(&format!(
- "test {} has been running for over {} seconds\n",
- desc.name, TEST_WARN_TIMEOUT_S
- ))
- }
-
- fn write_run_finish(&mut self, state: &ConsoleTestState) -> io::Result<bool> {
- if state.options.display_output {
- self.write_outputs(state)?;
- }
- let success = state.failed == 0;
- if !success {
- self.write_failures(state)?;
- }
-
- self.write_plain("\ntest result: ")?;
-
- if success {
- // There's no parallelism at this point so it's safe to use color
- self.write_pretty("ok", term::color::GREEN)?;
- } else {
- self.write_pretty("FAILED", term::color::RED)?;
- }
-
- let s = if state.allowed_fail > 0 {
- format!(
- ". {} passed; {} failed ({} allowed); {} ignored; {} measured; {} filtered out\n\n",
- state.passed,
- state.failed + state.allowed_fail,
- state.allowed_fail,
- state.ignored,
- state.measured,
- state.filtered_out
- )
- } else {
- format!(
- ". {} passed; {} failed; {} ignored; {} measured; {} filtered out\n\n",
- state.passed, state.failed, state.ignored, state.measured, state.filtered_out
- )
- };
-
- self.write_plain(&s)?;
-
- Ok(success)
- }
-}
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index ea821a1..cb0ce48 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -8,1582 +8,24 @@
//!
//! See the [Testing Chapter](../book/ch11-00-testing.html) of the book for more details.
-// Currently, not much of this is meant for users. It is intended to
-// support the simplest interface possible for representing and
-// running tests while providing a base that other test frameworks may
-// build off of.
-
-// N.B., this is also specified in this crate's Cargo.toml, but libsyntax contains logic specific to
-// this crate, which relies on this attribute (rather than the value of `--crate-name` passed by
-// cargo) to detect this crate.
-
-#![deny(rust_2018_idioms)]
#![crate_name = "test"]
#![unstable(feature = "test", issue = "27812")]
-#![doc(html_root_url = "https://doc.rust-lang.org/nightly/", test(attr(deny(warnings))))]
+#![doc(html_root_url = "https://doc.rust-lang.org/nightly/",
+ test(attr(deny(warnings))))]
#![feature(asm)]
-#![feature(fnbox)]
-#![cfg_attr(any(unix, target_os = "cloudabi"), feature(libc, rustc_private))]
-#![feature(nll)]
-#![feature(set_stdio)]
-#![feature(panic_unwind)]
#![feature(staged_api)]
-#![feature(termination_trait_lib)]
#![feature(test)]
-use getopts;
-#[cfg(any(unix, target_os = "cloudabi"))]
-extern crate libc;
-use term;
+extern crate libtest;
-// FIXME(#54291): rustc and/or LLVM don't yet support building with panic-unwind
-// on aarch64-pc-windows-msvc, so we don't link libtest against
-// libunwind (for the time being), even though it means that
-// libtest won't be fully functional on this platform.
-//
-// See also: https://github.com/rust-lang/rust/issues/54190#issuecomment-422904437
-#[cfg(not(all(windows, target_arch = "aarch64")))]
-extern crate panic_unwind;
-
-pub use self::ColorConfig::*;
-use self::NamePadding::*;
-use self::OutputLocation::*;
-use self::TestEvent::*;
-pub use self::TestFn::*;
-pub use self::TestName::*;
-pub use self::TestResult::*;
-
-use std::any::Any;
-use std::borrow::Cow;
-use std::boxed::FnBox;
-use std::cmp;
-use std::collections::BTreeMap;
-use std::env;
-use std::fmt;
-use std::fs::File;
-use std::io;
-use std::io::prelude::*;
-use std::panic::{catch_unwind, AssertUnwindSafe};
-use std::path::PathBuf;
-use std::process;
-use std::process::Termination;
-use std::sync::mpsc::{channel, Sender};
-use std::sync::{Arc, Mutex};
-use std::thread;
-use std::time::{Duration, Instant};
-
-const TEST_WARN_TIMEOUT_S: u64 = 60;
-const QUIET_MODE_MAX_COLUMN: usize = 100; // insert a '\n' after 100 tests in quiet mode
-
-// to be used by rustc to compile tests in libtest
-pub mod test {
- pub use crate::{
- assert_test_result, filter_tests, parse_opts, run_test, test_main, test_main_static,
- Bencher, DynTestFn, DynTestName, Metric, MetricMap, Options, RunIgnored, ShouldPanic,
- StaticBenchFn, StaticTestFn, StaticTestName, TestDesc, TestDescAndFn, TestName, TestOpts,
- TestResult, TrFailed, TrFailedMsg, TrIgnored, TrOk,
- };
-}
-
-mod formatters;
-pub mod stats;
-
-use crate::formatters::{JsonFormatter, OutputFormatter, PrettyFormatter, TerseFormatter};
-
-/// Whether to execute tests concurrently or not
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub enum Concurrent {
- Yes,
- No,
-}
-
-// The name of a test. By convention this follows the rules for rust
-// paths; i.e., it should be a series of identifiers separated by double
-// colons. This way if some test runner wants to arrange the tests
-// hierarchically it may.
-
-#[derive(Clone, PartialEq, Eq, Hash, Debug)]
-pub enum TestName {
- StaticTestName(&'static str),
- DynTestName(String),
- AlignedTestName(Cow<'static, str>, NamePadding),
-}
-impl TestName {
- fn as_slice(&self) -> &str {
- match *self {
- StaticTestName(s) => s,
- DynTestName(ref s) => s,
- AlignedTestName(ref s, _) => &*s,
- }
- }
-
- fn padding(&self) -> NamePadding {
- match self {
- &AlignedTestName(_, p) => p,
- _ => PadNone,
- }
- }
-
- fn with_padding(&self, padding: NamePadding) -> TestName {
- let name = match self {
- &TestName::StaticTestName(name) => Cow::Borrowed(name),
- &TestName::DynTestName(ref name) => Cow::Owned(name.clone()),
- &TestName::AlignedTestName(ref name, _) => name.clone(),
- };
-
- TestName::AlignedTestName(name, padding)
- }
-}
-impl fmt::Display for TestName {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- fmt::Display::fmt(self.as_slice(), f)
- }
-}
-
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
-pub enum NamePadding {
- PadNone,
- PadOnRight,
-}
-
-impl TestDesc {
- fn padded_name(&self, column_count: usize, align: NamePadding) -> String {
- let mut name = String::from(self.name.as_slice());
- let fill = column_count.saturating_sub(name.len());
- let pad = " ".repeat(fill);
- match align {
- PadNone => name,
- PadOnRight => {
- name.push_str(&pad);
- name
- }
- }
- }
-}
-
-/// Represents a benchmark function.
-pub trait TDynBenchFn: Send {
- fn run(&self, harness: &mut Bencher);
-}
-
-// A function that runs a test. If the function returns successfully,
-// the test succeeds; if the function panics then the test fails. We
-// may need to come up with a more clever definition of test in order
-// to support isolation of tests into threads.
-pub enum TestFn {
- StaticTestFn(fn()),
- StaticBenchFn(fn(&mut Bencher)),
- DynTestFn(Box<dyn FnBox() + Send>),
- DynBenchFn(Box<dyn TDynBenchFn + 'static>),
-}
-
-impl TestFn {
- fn padding(&self) -> NamePadding {
- match *self {
- StaticTestFn(..) => PadNone,
- StaticBenchFn(..) => PadOnRight,
- DynTestFn(..) => PadNone,
- DynBenchFn(..) => PadOnRight,
- }
- }
-}
-
-impl fmt::Debug for TestFn {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.write_str(match *self {
- StaticTestFn(..) => "StaticTestFn(..)",
- StaticBenchFn(..) => "StaticBenchFn(..)",
- DynTestFn(..) => "DynTestFn(..)",
- DynBenchFn(..) => "DynBenchFn(..)",
- })
- }
-}
-
-/// Manager of the benchmarking runs.
-///
-/// This is fed into functions marked with `#[bench]` to allow for
-/// set-up & tear-down before running a piece of code repeatedly via a
-/// call to `iter`.
-#[derive(Clone)]
-pub struct Bencher {
- mode: BenchMode,
- summary: Option<stats::Summary>,
- pub bytes: u64,
-}
-
-#[derive(Clone, PartialEq, Eq)]
-pub enum BenchMode {
- Auto,
- Single,
-}
-
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
-pub enum ShouldPanic {
- No,
- Yes,
- YesWithMessage(&'static str),
-}
-
-// The definition of a single test. A test runner will run a list of
-// these.
-#[derive(Clone, Debug, PartialEq, Eq, Hash)]
-pub struct TestDesc {
- pub name: TestName,
- pub ignore: bool,
- pub should_panic: ShouldPanic,
- pub allow_fail: bool,
-}
-
-#[derive(Debug)]
-pub struct TestDescAndFn {
- pub desc: TestDesc,
- pub testfn: TestFn,
-}
-
-#[derive(Clone, PartialEq, Debug, Copy)]
-pub struct Metric {
- value: f64,
- noise: f64,
-}
-
-impl Metric {
- pub fn new(value: f64, noise: f64) -> Metric {
- Metric { value, noise }
- }
-}
-
-/// In case we want to add other options as well, just add them in this struct.
-#[derive(Copy, Clone, Debug)]
-pub struct Options {
- display_output: bool,
-}
-
-impl Options {
- pub fn new() -> Options {
- Options {
- display_output: false,
- }
- }
-
- pub fn display_output(mut self, display_output: bool) -> Options {
- self.display_output = display_output;
- self
- }
-}
-
-// The default console test runner. It accepts the command line
-// arguments and a vector of test_descs.
-pub fn test_main(args: &[String], tests: Vec<TestDescAndFn>, options: Options) {
- let mut opts = match parse_opts(args) {
- Some(Ok(o)) => o,
- Some(Err(msg)) => {
- eprintln!("error: {}", msg);
- process::exit(101);
- }
- None => return,
- };
-
- opts.options = options;
- if opts.list {
- if let Err(e) = list_tests_console(&opts, tests) {
- eprintln!("error: io error when listing tests: {:?}", e);
- process::exit(101);
- }
- } else {
- match run_tests_console(&opts, tests) {
- Ok(true) => {}
- Ok(false) => process::exit(101),
- Err(e) => {
- eprintln!("error: io error when listing tests: {:?}", e);
- process::exit(101);
- }
- }
- }
-}
-
-// A variant optimized for invocation with a static test vector.
-// This will panic (intentionally) when fed any dynamic tests, because
-// it is copying the static values out into a dynamic vector and cannot
-// copy dynamic values. It is doing this because from this point on
-// a Vec<TestDescAndFn> is used in order to effect ownership-transfer
-// semantics into parallel test runners, which in turn requires a Vec<>
-// rather than a &[].
-pub fn test_main_static(tests: &[&TestDescAndFn]) {
- let args = env::args().collect::<Vec<_>>();
- let owned_tests = tests
- .iter()
- .map(|t| match t.testfn {
- StaticTestFn(f) => TestDescAndFn {
- testfn: StaticTestFn(f),
- desc: t.desc.clone(),
- },
- StaticBenchFn(f) => TestDescAndFn {
- testfn: StaticBenchFn(f),
- desc: t.desc.clone(),
- },
- _ => panic!("non-static tests passed to test::test_main_static"),
- })
- .collect();
- test_main(&args, owned_tests, Options::new())
-}
-
-/// Invoked when unit tests terminate. Should panic if the unit
-/// Tests is considered a failure. By default, invokes `report()`
-/// and checks for a `0` result.
-pub fn assert_test_result<T: Termination>(result: T) {
- let code = result.report();
- assert_eq!(
- code, 0,
- "the test returned a termination value with a non-zero status code ({}) \
- which indicates a failure",
- code
- );
-}
-
-#[derive(Copy, Clone, Debug)]
-pub enum ColorConfig {
- AutoColor,
- AlwaysColor,
- NeverColor,
-}
-
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub enum OutputFormat {
- Pretty,
- Terse,
- Json,
-}
-
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub enum RunIgnored {
- Yes,
- No,
- Only,
-}
-
-#[derive(Debug)]
-pub struct TestOpts {
- pub list: bool,
- pub filter: Option<String>,
- pub filter_exact: bool,
- pub exclude_should_panic: bool,
- pub run_ignored: RunIgnored,
- pub run_tests: bool,
- pub bench_benchmarks: bool,
- pub logfile: Option<PathBuf>,
- pub nocapture: bool,
- pub color: ColorConfig,
- pub format: OutputFormat,
- pub test_threads: Option<usize>,
- pub skip: Vec<String>,
- pub options: Options,
-}
-
-impl TestOpts {
- #[cfg(test)]
- fn new() -> TestOpts {
- TestOpts {
- list: false,
- filter: None,
- filter_exact: false,
- exclude_should_panic: false,
- run_ignored: RunIgnored::No,
- run_tests: false,
- bench_benchmarks: false,
- logfile: None,
- nocapture: false,
- color: AutoColor,
- format: OutputFormat::Pretty,
- test_threads: None,
- skip: vec![],
- options: Options::new(),
- }
- }
-}
-
-/// Result of parsing the options.
-pub type OptRes = Result<TestOpts, String>;
-
-fn optgroups() -> getopts::Options {
- let mut opts = getopts::Options::new();
- opts.optflag("", "include-ignored", "Run ignored and not ignored tests")
- .optflag("", "ignored", "Run only ignored tests")
- .optflag("", "exclude-should-panic", "Excludes tests marked as should_panic")
- .optflag("", "test", "Run tests and not benchmarks")
- .optflag("", "bench", "Run benchmarks instead of tests")
- .optflag("", "list", "List all tests and benchmarks")
- .optflag("h", "help", "Display this message (longer with --help)")
- .optopt(
- "",
- "logfile",
- "Write logs to the specified file instead \
- of stdout",
- "PATH",
- )
- .optflag(
- "",
- "nocapture",
- "don't capture stdout/stderr of each \
- task, allow printing directly",
- )
- .optopt(
- "",
- "test-threads",
- "Number of threads used for running tests \
- in parallel",
- "n_threads",
- )
- .optmulti(
- "",
- "skip",
- "Skip tests whose names contain FILTER (this flag can \
- be used multiple times)",
- "FILTER",
- )
- .optflag(
- "q",
- "quiet",
- "Display one character per test instead of one line. \
- Alias to --format=terse",
- )
- .optflag(
- "",
- "exact",
- "Exactly match filters rather than by substring",
- )
- .optopt(
- "",
- "color",
- "Configure coloring of output:
- auto = colorize if stdout is a tty and tests are run on serially (default);
- always = always colorize output;
- never = never colorize output;",
- "auto|always|never",
- )
- .optopt(
- "",
- "format",
- "Configure formatting of output:
- pretty = Print verbose output;
- terse = Display one character per test;
- json = Output a json document",
- "pretty|terse|json",
- )
- .optopt(
- "Z",
- "",
- "Enable nightly-only flags:
- unstable-options = Allow use of experimental features",
- "unstable-options",
- );
- return opts;
-}
-
-fn usage(binary: &str, options: &getopts::Options) {
- let message = format!("Usage: {} [OPTIONS] [FILTER]", binary);
- println!(
- r#"{usage}
-
-The FILTER string is tested against the name of all tests, and only those
-tests whose names contain the filter are run.
-
-By default, all tests are run in parallel. This can be altered with the
---test-threads flag or the RUST_TEST_THREADS environment variable when running
-tests (set it to 1).
-
-All tests have their standard output and standard error captured by default.
-This can be overridden with the --nocapture flag or setting RUST_TEST_NOCAPTURE
-environment variable to a value other than "0". Logging is not captured by default.
-
-Test Attributes:
-
- #[test] - Indicates a function is a test to be run. This function
- takes no arguments.
- #[bench] - Indicates a function is a benchmark to be run. This
- function takes one argument (test::Bencher).
- #[should_panic] - This function (also labeled with #[test]) will only pass if
- the code causes a panic (an assertion failure or panic!)
- A message may be provided, which the failure string must
- contain: #[should_panic(expected = "foo")].
- #[ignore] - When applied to a function which is already attributed as a
- test, then the test runner will ignore these tests during
- normal test runs. Running with --ignored or --include-ignored will run
- these tests."#,
- usage = options.usage(&message)
- );
-}
-
-// FIXME: Copied from libsyntax until linkage errors are resolved. Issue #47566
-fn is_nightly() -> bool {
- // Whether this is a feature-staged build, i.e., on the beta or stable channel
- let disable_unstable_features = option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some();
- // Whether we should enable unstable features for bootstrapping
- let bootstrap = env::var("RUSTC_BOOTSTRAP").is_ok();
-
- bootstrap || !disable_unstable_features
-}
-
-// Parses command line arguments into test options
-pub fn parse_opts(args: &[String]) -> Option<OptRes> {
- let mut allow_unstable = false;
- let opts = optgroups();
- let args = args.get(1..).unwrap_or(args);
- let matches = match opts.parse(args) {
- Ok(m) => m,
- Err(f) => return Some(Err(f.to_string())),
- };
-
- if let Some(opt) = matches.opt_str("Z") {
- if !is_nightly() {
- return Some(Err(
- "the option `Z` is only accepted on the nightly compiler".into(),
- ));
- }
-
- match &*opt {
- "unstable-options" => {
- allow_unstable = true;
- }
- _ => {
- return Some(Err("Unrecognized option to `Z`".into()));
- }
- }
- };
-
- if matches.opt_present("h") {
- usage(&args[0], &opts);
- return None;
- }
-
- let filter = if !matches.free.is_empty() {
- Some(matches.free[0].clone())
- } else {
- None
- };
-
- let exclude_should_panic = matches.opt_present("exclude-should-panic");
- if !allow_unstable && exclude_should_panic {
- return Some(Err(
- "The \"exclude-should-panic\" flag is only accepted on the nightly compiler".into(),
- ));
- }
-
- let include_ignored = matches.opt_present("include-ignored");
- if !allow_unstable && include_ignored {
- return Some(Err(
- "The \"include-ignored\" flag is only accepted on the nightly compiler".into(),
- ));
- }
-
- let run_ignored = match (include_ignored, matches.opt_present("ignored")) {
- (true, true) => {
- return Some(Err(
- "the options --include-ignored and --ignored are mutually exclusive".into(),
- ));
- }
- (true, false) => RunIgnored::Yes,
- (false, true) => RunIgnored::Only,
- (false, false) => RunIgnored::No,
- };
- let quiet = matches.opt_present("quiet");
- let exact = matches.opt_present("exact");
- let list = matches.opt_present("list");
-
- let logfile = matches.opt_str("logfile");
- let logfile = logfile.map(|s| PathBuf::from(&s));
-
- let bench_benchmarks = matches.opt_present("bench");
- let run_tests = !bench_benchmarks || matches.opt_present("test");
-
- let mut nocapture = matches.opt_present("nocapture");
- if !nocapture {
- nocapture = match env::var("RUST_TEST_NOCAPTURE") {
- Ok(val) => &val != "0",
- Err(_) => false,
- };
- }
-
- let test_threads = match matches.opt_str("test-threads") {
- Some(n_str) => match n_str.parse::<usize>() {
- Ok(0) => return Some(Err("argument for --test-threads must not be 0".to_string())),
- Ok(n) => Some(n),
- Err(e) => {
- return Some(Err(format!(
- "argument for --test-threads must be a number > 0 \
- (error: {})",
- e
- )));
- }
- },
- None => None,
- };
-
- let color = match matches.opt_str("color").as_ref().map(|s| &**s) {
- Some("auto") | None => AutoColor,
- Some("always") => AlwaysColor,
- Some("never") => NeverColor,
-
- Some(v) => {
- return Some(Err(format!(
- "argument for --color must be auto, always, or never (was \
- {})",
- v
- )));
- }
- };
-
- let format = match matches.opt_str("format").as_ref().map(|s| &**s) {
- None if quiet => OutputFormat::Terse,
- Some("pretty") | None => OutputFormat::Pretty,
- Some("terse") => OutputFormat::Terse,
- Some("json") => {
- if !allow_unstable {
- return Some(Err(
- "The \"json\" format is only accepted on the nightly compiler".into(),
- ));
- }
- OutputFormat::Json
- }
-
- Some(v) => {
- return Some(Err(format!(
- "argument for --format must be pretty, terse, or json (was \
- {})",
- v
- )));
- }
- };
-
- let test_opts = TestOpts {
- list,
- filter,
- filter_exact: exact,
- exclude_should_panic,
- run_ignored,
- run_tests,
- bench_benchmarks,
- logfile,
- nocapture,
- color,
- format,
- test_threads,
- skip: matches.opt_strs("skip"),
- options: Options::new(),
- };
-
- Some(Ok(test_opts))
-}
-
-#[derive(Clone, PartialEq)]
-pub struct BenchSamples {
- ns_iter_summ: stats::Summary,
- mb_s: usize,
-}
-
-#[derive(Clone, PartialEq)]
-pub enum TestResult {
- TrOk,
- TrFailed,
- TrFailedMsg(String),
- TrIgnored,
- TrAllowedFail,
- TrBench(BenchSamples),
-}
-
-unsafe impl Send for TestResult {}
-
-enum OutputLocation<T> {
- Pretty(Box<term::StdoutTerminal>),
- Raw(T),
-}
-
-impl<T: Write> Write for OutputLocation<T> {
- fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
- match *self {
- Pretty(ref mut term) => term.write(buf),
- Raw(ref mut stdout) => stdout.write(buf),
- }
- }
-
- fn flush(&mut self) -> io::Result<()> {
- match *self {
- Pretty(ref mut term) => term.flush(),
- Raw(ref mut stdout) => stdout.flush(),
- }
- }
-}
-
-struct ConsoleTestState {
- log_out: Option<File>,
- total: usize,
- passed: usize,
- failed: usize,
- ignored: usize,
- allowed_fail: usize,
- filtered_out: usize,
- measured: usize,
- metrics: MetricMap,
- failures: Vec<(TestDesc, Vec<u8>)>,
- not_failures: Vec<(TestDesc, Vec<u8>)>,
- options: Options,
-}
-
-impl ConsoleTestState {
- pub fn new(opts: &TestOpts) -> io::Result<ConsoleTestState> {
- let log_out = match opts.logfile {
- Some(ref path) => Some(File::create(path)?),
- None => None,
- };
-
- Ok(ConsoleTestState {
- log_out,
- total: 0,
- passed: 0,
- failed: 0,
- ignored: 0,
- allowed_fail: 0,
- filtered_out: 0,
- measured: 0,
- metrics: MetricMap::new(),
- failures: Vec::new(),
- not_failures: Vec::new(),
- options: opts.options,
- })
- }
-
- pub fn write_log<S: AsRef<str>>(&mut self, msg: S) -> io::Result<()> {
- let msg = msg.as_ref();
- match self.log_out {
- None => Ok(()),
- Some(ref mut o) => o.write_all(msg.as_bytes()),
- }
- }
-
- pub fn write_log_result(&mut self, test: &TestDesc, result: &TestResult) -> io::Result<()> {
- self.write_log(format!(
- "{} {}\n",
- match *result {
- TrOk => "ok".to_owned(),
- TrFailed => "failed".to_owned(),
- TrFailedMsg(ref msg) => format!("failed: {}", msg),
- TrIgnored => "ignored".to_owned(),
- TrAllowedFail => "failed (allowed)".to_owned(),
- TrBench(ref bs) => fmt_bench_samples(bs),
- },
- test.name
- ))
- }
-
- fn current_test_count(&self) -> usize {
- self.passed + self.failed + self.ignored + self.measured + self.allowed_fail
- }
-}
-
-// Format a number with thousands separators
-fn fmt_thousands_sep(mut n: usize, sep: char) -> String {
- use std::fmt::Write;
- let mut output = String::new();
- let mut trailing = false;
- for &pow in &[9, 6, 3, 0] {
- let base = 10_usize.pow(pow);
- if pow == 0 || trailing || n / base != 0 {
- if !trailing {
- output.write_fmt(format_args!("{}", n / base)).unwrap();
- } else {
- output.write_fmt(format_args!("{:03}", n / base)).unwrap();
- }
- if pow != 0 {
- output.push(sep);
- }
- trailing = true;
- }
- n %= base;
- }
-
- output
-}
-
-pub fn fmt_bench_samples(bs: &BenchSamples) -> String {
- use std::fmt::Write;
- let mut output = String::new();
-
- let median = bs.ns_iter_summ.median as usize;
- let deviation = (bs.ns_iter_summ.max - bs.ns_iter_summ.min) as usize;
-
- output
- .write_fmt(format_args!(
- "{:>11} ns/iter (+/- {})",
- fmt_thousands_sep(median, ','),
- fmt_thousands_sep(deviation, ',')
- ))
- .unwrap();
- if bs.mb_s != 0 {
- output
- .write_fmt(format_args!(" = {} MB/s", bs.mb_s))
- .unwrap();
- }
- output
-}
-
-// List the tests to console, and optionally to logfile. Filters are honored.
-pub fn list_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> io::Result<()> {
- let mut output = match term::stdout() {
- None => Raw(io::stdout()),
- Some(t) => Pretty(t),
- };
-
- let quiet = opts.format == OutputFormat::Terse;
- let mut st = ConsoleTestState::new(opts)?;
-
- let mut ntest = 0;
- let mut nbench = 0;
-
- for test in filter_tests(&opts, tests) {
- use crate::TestFn::*;
-
- let TestDescAndFn {
- desc: TestDesc { name, .. },
- testfn,
- } = test;
-
- let fntype = match testfn {
- StaticTestFn(..) | DynTestFn(..) => {
- ntest += 1;
- "test"
- }
- StaticBenchFn(..) | DynBenchFn(..) => {
- nbench += 1;
- "benchmark"
- }
- };
-
- writeln!(output, "{}: {}", name, fntype)?;
- st.write_log(format!("{} {}\n", fntype, name))?;
- }
-
- fn plural(count: u32, s: &str) -> String {
- match count {
- 1 => format!("{} {}", 1, s),
- n => format!("{} {}s", n, s),
- }
- }
-
- if !quiet {
- if ntest != 0 || nbench != 0 {
- writeln!(output, "")?;
- }
-
- writeln!(
- output,
- "{}, {}",
- plural(ntest, "test"),
- plural(nbench, "benchmark")
- )?;
- }
-
- Ok(())
-}
-
-// A simple console test runner
-pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> io::Result<bool> {
- fn callback(
- event: &TestEvent,
- st: &mut ConsoleTestState,
- out: &mut dyn OutputFormatter,
- ) -> io::Result<()> {
- match (*event).clone() {
- TeFiltered(ref filtered_tests) => {
- st.total = filtered_tests.len();
- out.write_run_start(filtered_tests.len())
- }
- TeFilteredOut(filtered_out) => Ok(st.filtered_out = filtered_out),
- TeWait(ref test) => out.write_test_start(test),
- TeTimeout(ref test) => out.write_timeout(test),
- TeResult(test, result, stdout) => {
- st.write_log_result(&test, &result)?;
- out.write_result(&test, &result, &*stdout)?;
- match result {
- TrOk => {
- st.passed += 1;
- st.not_failures.push((test, stdout));
- }
- TrIgnored => st.ignored += 1,
- TrAllowedFail => st.allowed_fail += 1,
- TrBench(bs) => {
- st.metrics.insert_metric(
- test.name.as_slice(),
- bs.ns_iter_summ.median,
- bs.ns_iter_summ.max - bs.ns_iter_summ.min,
- );
- st.measured += 1
- }
- TrFailed => {
- st.failed += 1;
- st.failures.push((test, stdout));
- }
- TrFailedMsg(msg) => {
- st.failed += 1;
- let mut stdout = stdout;
- stdout.extend_from_slice(format!("note: {}", msg).as_bytes());
- st.failures.push((test, stdout));
- }
- }
- Ok(())
- }
- }
- }
-
- let output = match term::stdout() {
- None => Raw(io::stdout()),
- Some(t) => Pretty(t),
- };
-
- let max_name_len = tests
- .iter()
- .max_by_key(|t| len_if_padded(*t))
- .map(|t| t.desc.name.as_slice().len())
- .unwrap_or(0);
-
- let is_multithreaded = opts.test_threads.unwrap_or_else(get_concurrency) > 1;
-
- let mut out: Box<dyn OutputFormatter> = match opts.format {
- OutputFormat::Pretty => Box::new(PrettyFormatter::new(
- output,
- use_color(opts),
- max_name_len,
- is_multithreaded,
- )),
- OutputFormat::Terse => Box::new(TerseFormatter::new(
- output,
- use_color(opts),
- max_name_len,
- is_multithreaded,
- )),
- OutputFormat::Json => Box::new(JsonFormatter::new(output)),
- };
- let mut st = ConsoleTestState::new(opts)?;
- fn len_if_padded(t: &TestDescAndFn) -> usize {
- match t.testfn.padding() {
- PadNone => 0,
- PadOnRight => t.desc.name.as_slice().len(),
- }
- }
-
- run_tests(opts, tests, |x| callback(&x, &mut st, &mut *out))?;
-
- assert!(st.current_test_count() == st.total);
-
- return out.write_run_finish(&st);
-}
-
-#[test]
-fn should_sort_failures_before_printing_them() {
- let test_a = TestDesc {
- name: StaticTestName("a"),
- ignore: false,
- should_panic: ShouldPanic::No,
- allow_fail: false,
- };
-
- let test_b = TestDesc {
- name: StaticTestName("b"),
- ignore: false,
- should_panic: ShouldPanic::No,
- allow_fail: false,
- };
-
- let mut out = PrettyFormatter::new(Raw(Vec::new()), false, 10, false);
-
- let st = ConsoleTestState {
- log_out: None,
- total: 0,
- passed: 0,
- failed: 0,
- ignored: 0,
- allowed_fail: 0,
- filtered_out: 0,
- measured: 0,
- metrics: MetricMap::new(),
- failures: vec![(test_b, Vec::new()), (test_a, Vec::new())],
- options: Options::new(),
- not_failures: Vec::new(),
- };
-
- out.write_failures(&st).unwrap();
- let s = match out.output_location() {
- &Raw(ref m) => String::from_utf8_lossy(&m[..]),
- &Pretty(_) => unreachable!(),
- };
-
- let apos = s.find("a").unwrap();
- let bpos = s.find("b").unwrap();
- assert!(apos < bpos);
-}
-
-fn use_color(opts: &TestOpts) -> bool {
- match opts.color {
- AutoColor => !opts.nocapture && stdout_isatty(),
- AlwaysColor => true,
- NeverColor => false,
- }
-}
-
-#[cfg(any(
- target_os = "cloudabi",
- target_os = "redox",
- all(target_arch = "wasm32", not(target_os = "emscripten")),
- all(target_vendor = "fortanix", target_env = "sgx")
-))]
-fn stdout_isatty() -> bool {
- // FIXME: Implement isatty on Redox and SGX
- false
-}
-#[cfg(unix)]
-fn stdout_isatty() -> bool {
- unsafe { libc::isatty(libc::STDOUT_FILENO) != 0 }
-}
-#[cfg(windows)]
-fn stdout_isatty() -> bool {
- type DWORD = u32;
- type BOOL = i32;
- type HANDLE = *mut u8;
- type LPDWORD = *mut u32;
- const STD_OUTPUT_HANDLE: DWORD = -11i32 as DWORD;
- extern "system" {
- fn GetStdHandle(which: DWORD) -> HANDLE;
- fn GetConsoleMode(hConsoleHandle: HANDLE, lpMode: LPDWORD) -> BOOL;
- }
- unsafe {
- let handle = GetStdHandle(STD_OUTPUT_HANDLE);
- let mut out = 0;
- GetConsoleMode(handle, &mut out) != 0
- }
-}
-
-#[derive(Clone)]
-pub enum TestEvent {
- TeFiltered(Vec<TestDesc>),
- TeWait(TestDesc),
- TeResult(TestDesc, TestResult, Vec<u8>),
- TeTimeout(TestDesc),
- TeFilteredOut(usize),
-}
-
-pub type MonitorMsg = (TestDesc, TestResult, Vec<u8>);
-
-struct Sink(Arc<Mutex<Vec<u8>>>);
-impl Write for Sink {
- fn write(&mut self, data: &[u8]) -> io::Result<usize> {
- Write::write(&mut *self.0.lock().unwrap(), data)
- }
- fn flush(&mut self) -> io::Result<()> {
- Ok(())
- }
-}
-
-pub fn run_tests<F>(opts: &TestOpts, tests: Vec<TestDescAndFn>, mut callback: F) -> io::Result<()>
-where
- F: FnMut(TestEvent) -> io::Result<()>,
-{
- use std::collections::{self, HashMap};
- use std::hash::BuildHasherDefault;
- use std::sync::mpsc::RecvTimeoutError;
- // Use a deterministic hasher
- type TestMap =
- HashMap<TestDesc, Instant, BuildHasherDefault<collections::hash_map::DefaultHasher>>;
-
- let tests_len = tests.len();
-
- let mut filtered_tests = filter_tests(opts, tests);
- if !opts.bench_benchmarks {
- filtered_tests = convert_benchmarks_to_tests(filtered_tests);
- }
-
- let filtered_tests = {
- let mut filtered_tests = filtered_tests;
- for test in filtered_tests.iter_mut() {
- test.desc.name = test.desc.name.with_padding(test.testfn.padding());
- }
-
- filtered_tests
- };
-
- let filtered_out = tests_len - filtered_tests.len();
- callback(TeFilteredOut(filtered_out))?;
-
- let filtered_descs = filtered_tests.iter().map(|t| t.desc.clone()).collect();
-
- callback(TeFiltered(filtered_descs))?;
-
- let (filtered_tests, filtered_benchs): (Vec<_>, _) =
- filtered_tests.into_iter().partition(|e| match e.testfn {
- StaticTestFn(_) | DynTestFn(_) => true,
- _ => false,
- });
-
- let concurrency = opts.test_threads.unwrap_or_else(get_concurrency);
-
- let mut remaining = filtered_tests;
- remaining.reverse();
- let mut pending = 0;
-
- let (tx, rx) = channel::<MonitorMsg>();
-
- let mut running_tests: TestMap = HashMap::default();
-
- fn get_timed_out_tests(running_tests: &mut TestMap) -> Vec<TestDesc> {
- let now = Instant::now();
- let timed_out = running_tests
- .iter()
- .filter_map(|(desc, timeout)| {
- if &now >= timeout {
- Some(desc.clone())
- } else {
- None
- }
- })
- .collect();
- for test in &timed_out {
- running_tests.remove(test);
- }
- timed_out
- };
-
- fn calc_timeout(running_tests: &TestMap) -> Option<Duration> {
- running_tests.values().min().map(|next_timeout| {
- let now = Instant::now();
- if *next_timeout >= now {
- *next_timeout - now
- } else {
- Duration::new(0, 0)
- }
- })
- };
-
- if concurrency == 1 {
- while !remaining.is_empty() {
- let test = remaining.pop().unwrap();
- callback(TeWait(test.desc.clone()))?;
- run_test(opts, !opts.run_tests, test, tx.clone(), Concurrent::No);
- let (test, result, stdout) = rx.recv().unwrap();
- callback(TeResult(test, result, stdout))?;
- }
- } else {
- while pending > 0 || !remaining.is_empty() {
- while pending < concurrency && !remaining.is_empty() {
- let test = remaining.pop().unwrap();
- let timeout = Instant::now() + Duration::from_secs(TEST_WARN_TIMEOUT_S);
- running_tests.insert(test.desc.clone(), timeout);
- callback(TeWait(test.desc.clone()))?; //here no pad
- run_test(opts, !opts.run_tests, test, tx.clone(), Concurrent::Yes);
- pending += 1;
- }
-
- let mut res;
- loop {
- if let Some(timeout) = calc_timeout(&running_tests) {
- res = rx.recv_timeout(timeout);
- for test in get_timed_out_tests(&mut running_tests) {
- callback(TeTimeout(test))?;
- }
- if res != Err(RecvTimeoutError::Timeout) {
- break;
- }
- } else {
- res = rx.recv().map_err(|_| RecvTimeoutError::Disconnected);
- break;
- }
- }
-
- let (desc, result, stdout) = res.unwrap();
- running_tests.remove(&desc);
-
- callback(TeResult(desc, result, stdout))?;
- pending -= 1;
- }
- }
-
- if opts.bench_benchmarks {
- // All benchmarks run at the end, in serial.
- for b in filtered_benchs {
- callback(TeWait(b.desc.clone()))?;
- run_test(opts, false, b, tx.clone(), Concurrent::No);
- let (test, result, stdout) = rx.recv().unwrap();
- callback(TeResult(test, result, stdout))?;
- }
- }
- Ok(())
-}
-
-#[allow(deprecated)]
-fn get_concurrency() -> usize {
- return match env::var("RUST_TEST_THREADS") {
- Ok(s) => {
- let opt_n: Option<usize> = s.parse().ok();
- match opt_n {
- Some(n) if n > 0 => n,
- _ => panic!(
- "RUST_TEST_THREADS is `{}`, should be a positive integer.",
- s
- ),
- }
- }
- Err(..) => num_cpus(),
- };
-
- #[cfg(windows)]
- #[allow(nonstandard_style)]
- fn num_cpus() -> usize {
- #[repr(C)]
- struct SYSTEM_INFO {
- wProcessorArchitecture: u16,
- wReserved: u16,
- dwPageSize: u32,
- lpMinimumApplicationAddress: *mut u8,
- lpMaximumApplicationAddress: *mut u8,
- dwActiveProcessorMask: *mut u8,
- dwNumberOfProcessors: u32,
- dwProcessorType: u32,
- dwAllocationGranularity: u32,
- wProcessorLevel: u16,
- wProcessorRevision: u16,
- }
- extern "system" {
- fn GetSystemInfo(info: *mut SYSTEM_INFO) -> i32;
- }
- unsafe {
- let mut sysinfo = std::mem::zeroed();
- GetSystemInfo(&mut sysinfo);
- sysinfo.dwNumberOfProcessors as usize
- }
- }
-
- #[cfg(target_os = "redox")]
- fn num_cpus() -> usize {
- // FIXME: Implement num_cpus on Redox
- 1
- }
-
- #[cfg(any(
- all(target_arch = "wasm32", not(target_os = "emscripten")),
- all(target_vendor = "fortanix", target_env = "sgx")
- ))]
- fn num_cpus() -> usize {
- 1
- }
-
- #[cfg(any(
- target_os = "android",
- target_os = "cloudabi",
- target_os = "emscripten",
- target_os = "fuchsia",
- target_os = "ios",
- target_os = "linux",
- target_os = "macos",
- target_os = "solaris"
- ))]
- fn num_cpus() -> usize {
- unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as usize }
- }
-
- #[cfg(any(
- target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "bitrig",
- target_os = "netbsd"
- ))]
- fn num_cpus() -> usize {
- use std::ptr;
-
- let mut cpus: libc::c_uint = 0;
- let mut cpus_size = std::mem::size_of_val(&cpus);
-
- unsafe {
- cpus = libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as libc::c_uint;
- }
- if cpus < 1 {
- let mut mib = [libc::CTL_HW, libc::HW_NCPU, 0, 0];
- unsafe {
- libc::sysctl(
- mib.as_mut_ptr(),
- 2,
- &mut cpus as *mut _ as *mut _,
- &mut cpus_size as *mut _ as *mut _,
- ptr::null_mut(),
- 0,
- );
- }
- if cpus < 1 {
- cpus = 1;
- }
- }
- cpus as usize
- }
-
- #[cfg(target_os = "openbsd")]
- fn num_cpus() -> usize {
- use std::ptr;
-
- let mut cpus: libc::c_uint = 0;
- let mut cpus_size = std::mem::size_of_val(&cpus);
- let mut mib = [libc::CTL_HW, libc::HW_NCPU, 0, 0];
-
- unsafe {
- libc::sysctl(
- mib.as_mut_ptr(),
- 2,
- &mut cpus as *mut _ as *mut _,
- &mut cpus_size as *mut _ as *mut _,
- ptr::null_mut(),
- 0,
- );
- }
- if cpus < 1 {
- cpus = 1;
- }
- cpus as usize
- }
-
- #[cfg(target_os = "haiku")]
- fn num_cpus() -> usize {
- // FIXME: implement
- 1
- }
-
- #[cfg(target_os = "l4re")]
- fn num_cpus() -> usize {
- // FIXME: implement
- 1
- }
-}
-
-pub fn filter_tests(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> Vec<TestDescAndFn> {
- let mut filtered = tests;
- let matches_filter = |test: &TestDescAndFn, filter: &str| {
- let test_name = test.desc.name.as_slice();
-
- match opts.filter_exact {
- true => test_name == filter,
- false => test_name.contains(filter),
- }
- };
-
- // Remove tests that don't match the test filter
- if let Some(ref filter) = opts.filter {
- filtered.retain(|test| matches_filter(test, filter));
- }
-
- // Skip tests that match any of the skip filters
- filtered.retain(|test| !opts.skip.iter().any(|sf| matches_filter(test, sf)));
-
- // Excludes #[should_panic] tests
- if opts.exclude_should_panic {
- filtered.retain(|test| test.desc.should_panic == ShouldPanic::No);
- }
-
- // maybe unignore tests
- match opts.run_ignored {
- RunIgnored::Yes => {
- filtered
- .iter_mut()
- .for_each(|test| test.desc.ignore = false);
- }
- RunIgnored::Only => {
- filtered.retain(|test| test.desc.ignore);
- filtered
- .iter_mut()
- .for_each(|test| test.desc.ignore = false);
- }
- RunIgnored::No => {}
- }
-
- // Sort the tests alphabetically
- filtered.sort_by(|t1, t2| t1.desc.name.as_slice().cmp(t2.desc.name.as_slice()));
-
- filtered
-}
-
-pub fn convert_benchmarks_to_tests(tests: Vec<TestDescAndFn>) -> Vec<TestDescAndFn> {
- // convert benchmarks to tests, if we're not benchmarking them
- tests
- .into_iter()
- .map(|x| {
- let testfn = match x.testfn {
- DynBenchFn(bench) => DynTestFn(Box::new(move || {
- bench::run_once(|b| __rust_begin_short_backtrace(|| bench.run(b)))
- })),
- StaticBenchFn(benchfn) => DynTestFn(Box::new(move || {
- bench::run_once(|b| __rust_begin_short_backtrace(|| benchfn(b)))
- })),
- f => f,
- };
- TestDescAndFn {
- desc: x.desc,
- testfn,
- }
- })
- .collect()
-}
-
-pub fn run_test(
- opts: &TestOpts,
- force_ignore: bool,
- test: TestDescAndFn,
- monitor_ch: Sender<MonitorMsg>,
- concurrency: Concurrent,
-) {
- let TestDescAndFn { desc, testfn } = test;
-
- let ignore_because_panic_abort = cfg!(target_arch = "wasm32")
- && !cfg!(target_os = "emscripten")
- && desc.should_panic != ShouldPanic::No;
-
- if force_ignore || desc.ignore || ignore_because_panic_abort {
- monitor_ch.send((desc, TrIgnored, Vec::new())).unwrap();
- return;
- }
-
- fn run_test_inner(
- desc: TestDesc,
- monitor_ch: Sender<MonitorMsg>,
- nocapture: bool,
- testfn: Box<dyn FnBox() + Send>,
- concurrency: Concurrent,
- ) {
- // Buffer for capturing standard I/O
- let data = Arc::new(Mutex::new(Vec::new()));
- let data2 = data.clone();
-
- let name = desc.name.clone();
- let runtest = move || {
- let oldio = if !nocapture {
- Some((
- io::set_print(Some(Box::new(Sink(data2.clone())))),
- io::set_panic(Some(Box::new(Sink(data2)))),
- ))
- } else {
- None
- };
-
- let result = catch_unwind(AssertUnwindSafe(testfn));
-
- if let Some((printio, panicio)) = oldio {
- io::set_print(printio);
- io::set_panic(panicio);
- };
-
- let test_result = calc_result(&desc, result);
- let stdout = data.lock().unwrap().to_vec();
- monitor_ch
- .send((desc.clone(), test_result, stdout))
- .unwrap();
- };
-
- // If the platform is single-threaded we're just going to run
- // the test synchronously, regardless of the concurrency
- // level.
- let supports_threads = !cfg!(target_os = "emscripten") && !cfg!(target_arch = "wasm32");
- if concurrency == Concurrent::Yes && supports_threads {
- let cfg = thread::Builder::new().name(name.as_slice().to_owned());
- cfg.spawn(runtest).unwrap();
- } else {
- runtest();
- }
- }
-
- match testfn {
- DynBenchFn(bencher) => {
- crate::bench::benchmark(desc, monitor_ch, opts.nocapture, |harness| {
- bencher.run(harness)
- });
- }
- StaticBenchFn(benchfn) => {
- crate::bench::benchmark(desc, monitor_ch, opts.nocapture, |harness| {
- (benchfn.clone())(harness)
- });
- }
- DynTestFn(f) => {
- let cb = move || __rust_begin_short_backtrace(f);
- run_test_inner(desc, monitor_ch, opts.nocapture, Box::new(cb), concurrency)
- }
- StaticTestFn(f) => run_test_inner(
- desc,
- monitor_ch,
- opts.nocapture,
- Box::new(move || __rust_begin_short_backtrace(f)),
- concurrency,
- ),
- }
-}
-
-/// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`.
-#[inline(never)]
-fn __rust_begin_short_backtrace<F: FnOnce()>(f: F) {
- f()
-}
-
-fn calc_result(desc: &TestDesc, task_result: Result<(), Box<dyn Any + Send>>) -> TestResult {
- match (&desc.should_panic, task_result) {
- (&ShouldPanic::No, Ok(())) | (&ShouldPanic::Yes, Err(_)) => TrOk,
- (&ShouldPanic::YesWithMessage(msg), Err(ref err)) => {
- if err
- .downcast_ref::<String>()
- .map(|e| &**e)
- .or_else(|| err.downcast_ref::<&'static str>().map(|e| *e))
- .map(|e| e.contains(msg))
- .unwrap_or(false)
- {
- TrOk
- } else {
- if desc.allow_fail {
- TrAllowedFail
- } else {
- TrFailedMsg(format!("Panic did not include expected string '{}'", msg))
- }
- }
- }
- _ if desc.allow_fail => TrAllowedFail,
- _ => TrFailed,
- }
-}
-
-#[derive(Clone, PartialEq)]
-pub struct MetricMap(BTreeMap<String, Metric>);
-
-impl MetricMap {
- pub fn new() -> MetricMap {
- MetricMap(BTreeMap::new())
- }
-
- /// Insert a named `value` (+/- `noise`) metric into the map. The value
- /// must be non-negative. The `noise` indicates the uncertainty of the
- /// metric, which doubles as the "noise range" of acceptable
- /// pairwise-regressions on this named value, when comparing from one
- /// metric to the next using `compare_to_old`.
- ///
- /// If `noise` is positive, then it means this metric is of a value
- /// you want to see grow smaller, so a change larger than `noise` in the
- /// positive direction represents a regression.
- ///
- /// If `noise` is negative, then it means this metric is of a value
- /// you want to see grow larger, so a change larger than `noise` in the
- /// negative direction represents a regression.
- pub fn insert_metric(&mut self, name: &str, value: f64, noise: f64) {
- let m = Metric { value, noise };
- self.0.insert(name.to_owned(), m);
- }
-
- pub fn fmt_metrics(&self) -> String {
- let v = self
- .0
- .iter()
- .map(|(k, v)| format!("{}: {} (+/- {})", *k, v.value, v.noise))
- .collect::<Vec<_>>();
- v.join(", ")
- }
-}
-
-// Benchmarking
+// FIXME: we should be more explicit about the exact APIs that we
+// export to users.
+pub use libtest::{
+ assert_test_result, filter_tests, parse_opts, run_test, test_main, test_main_static,
+ Bencher, DynTestFn, DynTestName, Metric, MetricMap, Options, RunIgnored, ShouldPanic,
+ StaticBenchFn, StaticTestFn, StaticTestName, TestDesc, TestDescAndFn, TestName, TestOpts,
+ TestResult, TrFailed, TrFailedMsg, TrIgnored, TrOk, stats::Summary
+};
/// A function that is opaque to the optimizer, to allow benchmarks to
/// pretend to use outputs to assist in avoiding dead-code
@@ -1603,645 +45,27 @@
dummy
}
-impl Bencher {
- /// Callback for benchmark functions to run in their body.
- pub fn iter<T, F>(&mut self, mut inner: F)
- where
- F: FnMut() -> T,
- {
- if self.mode == BenchMode::Single {
- ns_iter_inner(&mut inner, 1);
- return;
- }
-
- self.summary = Some(iter(&mut inner));
- }
-
- pub fn bench<F>(&mut self, mut f: F) -> Option<stats::Summary>
- where
- F: FnMut(&mut Bencher),
- {
- f(self);
- return self.summary;
- }
-}
-
-fn ns_from_dur(dur: Duration) -> u64 {
- dur.as_secs() * 1_000_000_000 + (dur.subsec_nanos() as u64)
-}
-
-fn ns_iter_inner<T, F>(inner: &mut F, k: u64) -> u64
-where
- F: FnMut() -> T,
-{
- let start = Instant::now();
- for _ in 0..k {
- black_box(inner());
- }
- return ns_from_dur(start.elapsed());
-}
-
-pub fn iter<T, F>(inner: &mut F) -> stats::Summary
-where
- F: FnMut() -> T,
-{
- // Initial bench run to get ballpark figure.
- let ns_single = ns_iter_inner(inner, 1);
-
- // Try to estimate iter count for 1ms falling back to 1m
- // iterations if first run took < 1ns.
- let ns_target_total = 1_000_000; // 1ms
- let mut n = ns_target_total / cmp::max(1, ns_single);
-
- // if the first run took more than 1ms we don't want to just
- // be left doing 0 iterations on every loop. The unfortunate
- // side effect of not being able to do as many runs is
- // automatically handled by the statistical analysis below
- // (i.e., larger error bars).
- n = cmp::max(1, n);
-
- let mut total_run = Duration::new(0, 0);
- let samples: &mut [f64] = &mut [0.0_f64; 50];
- loop {
- let loop_start = Instant::now();
-
- for p in &mut *samples {
- *p = ns_iter_inner(inner, n) as f64 / n as f64;
- }
-
- stats::winsorize(samples, 5.0);
- let summ = stats::Summary::new(samples);
-
- for p in &mut *samples {
- let ns = ns_iter_inner(inner, 5 * n);
- *p = ns as f64 / (5 * n) as f64;
- }
-
- stats::winsorize(samples, 5.0);
- let summ5 = stats::Summary::new(samples);
-
- let loop_run = loop_start.elapsed();
-
- // If we've run for 100ms and seem to have converged to a
- // stable median.
- if loop_run > Duration::from_millis(100)
- && summ.median_abs_dev_pct < 1.0
- && summ.median - summ5.median < summ5.median_abs_dev
- {
- return summ5;
- }
-
- total_run = total_run + loop_run;
- // Longest we ever run for is 3s.
- if total_run > Duration::from_secs(3) {
- return summ5;
- }
-
- // If we overflow here just return the results so far. We check a
- // multiplier of 10 because we're about to multiply by 2 and the
- // next iteration of the loop will also multiply by 5 (to calculate
- // the summ5 result)
- n = match n.checked_mul(10) {
- Some(_) => n * 2,
- None => {
- return summ5;
- }
- };
- }
-}
-
-pub mod bench {
- use super::{BenchMode, BenchSamples, Bencher, MonitorMsg, Sender, Sink, TestDesc, TestResult};
- use crate::stats;
- use std::cmp;
- use std::io;
- use std::panic::{catch_unwind, AssertUnwindSafe};
- use std::sync::{Arc, Mutex};
-
- pub fn benchmark<F>(desc: TestDesc, monitor_ch: Sender<MonitorMsg>, nocapture: bool, f: F)
- where
- F: FnMut(&mut Bencher),
- {
- let mut bs = Bencher {
- mode: BenchMode::Auto,
- summary: None,
- bytes: 0,
- };
-
- let data = Arc::new(Mutex::new(Vec::new()));
- let data2 = data.clone();
-
- let oldio = if !nocapture {
- Some((
- io::set_print(Some(Box::new(Sink(data2.clone())))),
- io::set_panic(Some(Box::new(Sink(data2)))),
- ))
- } else {
- None
- };
-
- let result = catch_unwind(AssertUnwindSafe(|| bs.bench(f)));
-
- if let Some((printio, panicio)) = oldio {
- io::set_print(printio);
- io::set_panic(panicio);
- };
-
- let test_result = match result {
- //bs.bench(f) {
- Ok(Some(ns_iter_summ)) => {
- let ns_iter = cmp::max(ns_iter_summ.median as u64, 1);
- let mb_s = bs.bytes * 1000 / ns_iter;
-
- let bs = BenchSamples {
- ns_iter_summ,
- mb_s: mb_s as usize,
- };
- TestResult::TrBench(bs)
- }
- Ok(None) => {
- // iter not called, so no data.
- // FIXME: error in this case?
- let samples: &mut [f64] = &mut [0.0_f64; 1];
- let bs = BenchSamples {
- ns_iter_summ: stats::Summary::new(samples),
- mb_s: 0,
- };
- TestResult::TrBench(bs)
- }
- Err(_) => TestResult::TrFailed,
- };
-
- let stdout = data.lock().unwrap().to_vec();
- monitor_ch.send((desc, test_result, stdout)).unwrap();
- }
-
- pub fn run_once<F>(f: F)
- where
- F: FnMut(&mut Bencher),
- {
- let mut bs = Bencher {
- mode: BenchMode::Single,
- summary: None,
- bytes: 0,
- };
- bs.bench(f);
- }
-}
-
#[cfg(test)]
mod tests {
- use crate::bench;
- use crate::test::{
- filter_tests, parse_opts, run_test, DynTestFn, DynTestName, MetricMap, RunIgnored,
- ShouldPanic, StaticTestName, TestDesc, TestDescAndFn, TestOpts, TrFailed, TrFailedMsg,
- TrIgnored, TrOk,
- };
use crate::Bencher;
- use crate::Concurrent;
- use std::sync::mpsc::channel;
+ use libtest::stats::Stats;
- fn one_ignored_one_unignored_test() -> Vec<TestDescAndFn> {
- vec![
- TestDescAndFn {
- desc: TestDesc {
- name: StaticTestName("1"),
- ignore: true,
- should_panic: ShouldPanic::No,
- allow_fail: false,
- },
- testfn: DynTestFn(Box::new(move || {})),
- },
- TestDescAndFn {
- desc: TestDesc {
- name: StaticTestName("2"),
- ignore: false,
- should_panic: ShouldPanic::No,
- allow_fail: false,
- },
- testfn: DynTestFn(Box::new(move || {})),
- },
- ]
+ #[bench]
+ pub fn sum_three_items(b: &mut Bencher) {
+ b.iter(|| {
+ [1e20f64, 1.5f64, -1e20f64].sum();
+ })
}
- #[test]
- pub fn do_not_run_ignored_tests() {
- fn f() {
- panic!();
- }
- let desc = TestDescAndFn {
- desc: TestDesc {
- name: StaticTestName("whatever"),
- ignore: true,
- should_panic: ShouldPanic::No,
- allow_fail: false,
- },
- testfn: DynTestFn(Box::new(f)),
- };
- let (tx, rx) = channel();
- run_test(&TestOpts::new(), false, desc, tx, Concurrent::No);
- let (_, res, _) = rx.recv().unwrap();
- assert!(res != TrOk);
+ #[bench]
+ pub fn sum_many_f64(b: &mut Bencher) {
+ let nums = [-1e30f64, 1e60, 1e30, 1.0, -1e60];
+ let v = (0..500).map(|i| nums[i % 5]).collect::<Vec<_>>();
+ b.iter(|| {
+ v.sum();
+ })
}
- #[test]
- pub fn ignored_tests_result_in_ignored() {
- fn f() {}
- let desc = TestDescAndFn {
- desc: TestDesc {
- name: StaticTestName("whatever"),
- ignore: true,
- should_panic: ShouldPanic::No,
- allow_fail: false,
- },
- testfn: DynTestFn(Box::new(f)),
- };
- let (tx, rx) = channel();
- run_test(&TestOpts::new(), false, desc, tx, Concurrent::No);
- let (_, res, _) = rx.recv().unwrap();
- assert!(res == TrIgnored);
- }
-
- #[test]
- fn test_should_panic() {
- fn f() {
- panic!();
- }
- let desc = TestDescAndFn {
- desc: TestDesc {
- name: StaticTestName("whatever"),
- ignore: false,
- should_panic: ShouldPanic::Yes,
- allow_fail: false,
- },
- testfn: DynTestFn(Box::new(f)),
- };
- let (tx, rx) = channel();
- run_test(&TestOpts::new(), false, desc, tx, Concurrent::No);
- let (_, res, _) = rx.recv().unwrap();
- assert!(res == TrOk);
- }
-
- #[test]
- fn test_should_panic_good_message() {
- fn f() {
- panic!("an error message");
- }
- let desc = TestDescAndFn {
- desc: TestDesc {
- name: StaticTestName("whatever"),
- ignore: false,
- should_panic: ShouldPanic::YesWithMessage("error message"),
- allow_fail: false,
- },
- testfn: DynTestFn(Box::new(f)),
- };
- let (tx, rx) = channel();
- run_test(&TestOpts::new(), false, desc, tx, Concurrent::No);
- let (_, res, _) = rx.recv().unwrap();
- assert!(res == TrOk);
- }
-
- #[test]
- fn test_should_panic_bad_message() {
- fn f() {
- panic!("an error message");
- }
- let expected = "foobar";
- let failed_msg = "Panic did not include expected string";
- let desc = TestDescAndFn {
- desc: TestDesc {
- name: StaticTestName("whatever"),
- ignore: false,
- should_panic: ShouldPanic::YesWithMessage(expected),
- allow_fail: false,
- },
- testfn: DynTestFn(Box::new(f)),
- };
- let (tx, rx) = channel();
- run_test(&TestOpts::new(), false, desc, tx, Concurrent::No);
- let (_, res, _) = rx.recv().unwrap();
- assert!(res == TrFailedMsg(format!("{} '{}'", failed_msg, expected)));
- }
-
- #[test]
- fn test_should_panic_but_succeeds() {
- fn f() {}
- let desc = TestDescAndFn {
- desc: TestDesc {
- name: StaticTestName("whatever"),
- ignore: false,
- should_panic: ShouldPanic::Yes,
- allow_fail: false,
- },
- testfn: DynTestFn(Box::new(f)),
- };
- let (tx, rx) = channel();
- run_test(&TestOpts::new(), false, desc, tx, Concurrent::No);
- let (_, res, _) = rx.recv().unwrap();
- assert!(res == TrFailed);
- }
-
- #[test]
- fn parse_ignored_flag() {
- let args = vec![
- "progname".to_string(),
- "filter".to_string(),
- "--ignored".to_string(),
- ];
- let opts = parse_opts(&args).unwrap().unwrap();
- assert_eq!(opts.run_ignored, RunIgnored::Only);
- }
-
- #[test]
- fn parse_include_ignored_flag() {
- let args = vec![
- "progname".to_string(),
- "filter".to_string(),
- "-Zunstable-options".to_string(),
- "--include-ignored".to_string(),
- ];
- let opts = parse_opts(&args).unwrap().unwrap();
- assert_eq!(opts.run_ignored, RunIgnored::Yes);
- }
-
- #[test]
- pub fn filter_for_ignored_option() {
- // When we run ignored tests the test filter should filter out all the
- // unignored tests and flip the ignore flag on the rest to false
-
- let mut opts = TestOpts::new();
- opts.run_tests = true;
- opts.run_ignored = RunIgnored::Only;
-
- let tests = one_ignored_one_unignored_test();
- let filtered = filter_tests(&opts, tests);
-
- assert_eq!(filtered.len(), 1);
- assert_eq!(filtered[0].desc.name.to_string(), "1");
- assert!(!filtered[0].desc.ignore);
- }
-
- #[test]
- pub fn run_include_ignored_option() {
- // When we "--include-ignored" tests, the ignore flag should be set to false on
- // all tests and no test filtered out
-
- let mut opts = TestOpts::new();
- opts.run_tests = true;
- opts.run_ignored = RunIgnored::Yes;
-
- let tests = one_ignored_one_unignored_test();
- let filtered = filter_tests(&opts, tests);
-
- assert_eq!(filtered.len(), 2);
- assert!(!filtered[0].desc.ignore);
- assert!(!filtered[1].desc.ignore);
- }
-
- #[test]
- pub fn exclude_should_panic_option() {
- let mut opts = TestOpts::new();
- opts.run_tests = true;
- opts.exclude_should_panic = true;
-
- let mut tests = one_ignored_one_unignored_test();
- tests.push(TestDescAndFn {
- desc: TestDesc {
- name: StaticTestName("3"),
- ignore: false,
- should_panic: ShouldPanic::Yes,
- allow_fail: false,
- },
- testfn: DynTestFn(Box::new(move || {})),
- });
-
- let filtered = filter_tests(&opts, tests);
-
- assert_eq!(filtered.len(), 2);
- assert!(filtered.iter().all(|test| test.desc.should_panic == ShouldPanic::No));
- }
-
- #[test]
- pub fn exact_filter_match() {
- fn tests() -> Vec<TestDescAndFn> {
- vec!["base", "base::test", "base::test1", "base::test2"]
- .into_iter()
- .map(|name| TestDescAndFn {
- desc: TestDesc {
- name: StaticTestName(name),
- ignore: false,
- should_panic: ShouldPanic::No,
- allow_fail: false,
- },
- testfn: DynTestFn(Box::new(move || {})),
- })
- .collect()
- }
-
- let substr = filter_tests(
- &TestOpts {
- filter: Some("base".into()),
- ..TestOpts::new()
- },
- tests(),
- );
- assert_eq!(substr.len(), 4);
-
- let substr = filter_tests(
- &TestOpts {
- filter: Some("bas".into()),
- ..TestOpts::new()
- },
- tests(),
- );
- assert_eq!(substr.len(), 4);
-
- let substr = filter_tests(
- &TestOpts {
- filter: Some("::test".into()),
- ..TestOpts::new()
- },
- tests(),
- );
- assert_eq!(substr.len(), 3);
-
- let substr = filter_tests(
- &TestOpts {
- filter: Some("base::test".into()),
- ..TestOpts::new()
- },
- tests(),
- );
- assert_eq!(substr.len(), 3);
-
- let exact = filter_tests(
- &TestOpts {
- filter: Some("base".into()),
- filter_exact: true,
- ..TestOpts::new()
- },
- tests(),
- );
- assert_eq!(exact.len(), 1);
-
- let exact = filter_tests(
- &TestOpts {
- filter: Some("bas".into()),
- filter_exact: true,
- ..TestOpts::new()
- },
- tests(),
- );
- assert_eq!(exact.len(), 0);
-
- let exact = filter_tests(
- &TestOpts {
- filter: Some("::test".into()),
- filter_exact: true,
- ..TestOpts::new()
- },
- tests(),
- );
- assert_eq!(exact.len(), 0);
-
- let exact = filter_tests(
- &TestOpts {
- filter: Some("base::test".into()),
- filter_exact: true,
- ..TestOpts::new()
- },
- tests(),
- );
- assert_eq!(exact.len(), 1);
- }
-
- #[test]
- pub fn sort_tests() {
- let mut opts = TestOpts::new();
- opts.run_tests = true;
-
- let names = vec![
- "sha1::test".to_string(),
- "isize::test_to_str".to_string(),
- "isize::test_pow".to_string(),
- "test::do_not_run_ignored_tests".to_string(),
- "test::ignored_tests_result_in_ignored".to_string(),
- "test::first_free_arg_should_be_a_filter".to_string(),
- "test::parse_ignored_flag".to_string(),
- "test::parse_include_ignored_flag".to_string(),
- "test::filter_for_ignored_option".to_string(),
- "test::run_include_ignored_option".to_string(),
- "test::sort_tests".to_string(),
- ];
- let tests = {
- fn testfn() {}
- let mut tests = Vec::new();
- for name in &names {
- let test = TestDescAndFn {
- desc: TestDesc {
- name: DynTestName((*name).clone()),
- ignore: false,
- should_panic: ShouldPanic::No,
- allow_fail: false,
- },
- testfn: DynTestFn(Box::new(testfn)),
- };
- tests.push(test);
- }
- tests
- };
- let filtered = filter_tests(&opts, tests);
-
- let expected = vec![
- "isize::test_pow".to_string(),
- "isize::test_to_str".to_string(),
- "sha1::test".to_string(),
- "test::do_not_run_ignored_tests".to_string(),
- "test::filter_for_ignored_option".to_string(),
- "test::first_free_arg_should_be_a_filter".to_string(),
- "test::ignored_tests_result_in_ignored".to_string(),
- "test::parse_ignored_flag".to_string(),
- "test::parse_include_ignored_flag".to_string(),
- "test::run_include_ignored_option".to_string(),
- "test::sort_tests".to_string(),
- ];
-
- for (a, b) in expected.iter().zip(filtered) {
- assert!(*a == b.desc.name.to_string());
- }
- }
-
- #[test]
- pub fn test_metricmap_compare() {
- let mut m1 = MetricMap::new();
- let mut m2 = MetricMap::new();
- m1.insert_metric("in-both-noise", 1000.0, 200.0);
- m2.insert_metric("in-both-noise", 1100.0, 200.0);
-
- m1.insert_metric("in-first-noise", 1000.0, 2.0);
- m2.insert_metric("in-second-noise", 1000.0, 2.0);
-
- m1.insert_metric("in-both-want-downwards-but-regressed", 1000.0, 10.0);
- m2.insert_metric("in-both-want-downwards-but-regressed", 2000.0, 10.0);
-
- m1.insert_metric("in-both-want-downwards-and-improved", 2000.0, 10.0);
- m2.insert_metric("in-both-want-downwards-and-improved", 1000.0, 10.0);
-
- m1.insert_metric("in-both-want-upwards-but-regressed", 2000.0, -10.0);
- m2.insert_metric("in-both-want-upwards-but-regressed", 1000.0, -10.0);
-
- m1.insert_metric("in-both-want-upwards-and-improved", 1000.0, -10.0);
- m2.insert_metric("in-both-want-upwards-and-improved", 2000.0, -10.0);
- }
-
- #[test]
- pub fn test_bench_once_no_iter() {
- fn f(_: &mut Bencher) {}
- bench::run_once(f);
- }
-
- #[test]
- pub fn test_bench_once_iter() {
- fn f(b: &mut Bencher) {
- b.iter(|| {})
- }
- bench::run_once(f);
- }
-
- #[test]
- pub fn test_bench_no_iter() {
- fn f(_: &mut Bencher) {}
-
- let (tx, rx) = channel();
-
- let desc = TestDesc {
- name: StaticTestName("f"),
- ignore: false,
- should_panic: ShouldPanic::No,
- allow_fail: false,
- };
-
- crate::bench::benchmark(desc, tx, true, f);
- rx.recv().unwrap();
- }
-
- #[test]
- pub fn test_bench_iter() {
- fn f(b: &mut Bencher) {
- b.iter(|| {})
- }
-
- let (tx, rx) = channel();
-
- let desc = TestDesc {
- name: StaticTestName("f"),
- ignore: false,
- should_panic: ShouldPanic::No,
- allow_fail: false,
- };
-
- crate::bench::benchmark(desc, tx, true, f);
- rx.recv().unwrap();
- }
+ #[bench]
+ pub fn no_iter(_: &mut Bencher) {}
}
diff --git a/src/libtest/stats.rs b/src/libtest/stats.rs
deleted file mode 100644
index 5c9421d..0000000
--- a/src/libtest/stats.rs
+++ /dev/null
@@ -1,922 +0,0 @@
-#![allow(missing_docs)]
-#![allow(deprecated)] // Float
-
-use std::cmp::Ordering::{self, Equal, Greater, Less};
-use std::mem;
-
-fn local_cmp(x: f64, y: f64) -> Ordering {
- // arbitrarily decide that NaNs are larger than everything.
- if y.is_nan() {
- Less
- } else if x.is_nan() {
- Greater
- } else if x < y {
- Less
- } else if x == y {
- Equal
- } else {
- Greater
- }
-}
-
-fn local_sort(v: &mut [f64]) {
- v.sort_by(|x: &f64, y: &f64| local_cmp(*x, *y));
-}
-
-/// Trait that provides simple descriptive statistics on a univariate set of numeric samples.
-pub trait Stats {
- /// Sum of the samples.
- ///
- /// Note: this method sacrifices performance at the altar of accuracy
- /// Depends on IEEE-754 arithmetic guarantees. See proof of correctness at:
- /// ["Adaptive Precision Floating-Point Arithmetic and Fast Robust Geometric
- /// Predicates"][paper]
- ///
- /// [paper]: http://www.cs.cmu.edu/~quake-papers/robust-arithmetic.ps
- fn sum(&self) -> f64;
-
- /// Minimum value of the samples.
- fn min(&self) -> f64;
-
- /// Maximum value of the samples.
- fn max(&self) -> f64;
-
- /// Arithmetic mean (average) of the samples: sum divided by sample-count.
- ///
- /// See: <https://en.wikipedia.org/wiki/Arithmetic_mean>
- fn mean(&self) -> f64;
-
- /// Median of the samples: value separating the lower half of the samples from the higher half.
- /// Equal to `self.percentile(50.0)`.
- ///
- /// See: <https://en.wikipedia.org/wiki/Median>
- fn median(&self) -> f64;
-
- /// Variance of the samples: bias-corrected mean of the squares of the differences of each
- /// sample from the sample mean. Note that this calculates the _sample variance_ rather than the
- /// population variance, which is assumed to be unknown. It therefore corrects the `(n-1)/n`
- /// bias that would appear if we calculated a population variance, by dividing by `(n-1)` rather
- /// than `n`.
- ///
- /// See: <https://en.wikipedia.org/wiki/Variance>
- fn var(&self) -> f64;
-
- /// Standard deviation: the square root of the sample variance.
- ///
- /// Note: this is not a robust statistic for non-normal distributions. Prefer the
- /// `median_abs_dev` for unknown distributions.
- ///
- /// See: <https://en.wikipedia.org/wiki/Standard_deviation>
- fn std_dev(&self) -> f64;
-
- /// Standard deviation as a percent of the mean value. See `std_dev` and `mean`.
- ///
- /// Note: this is not a robust statistic for non-normal distributions. Prefer the
- /// `median_abs_dev_pct` for unknown distributions.
- fn std_dev_pct(&self) -> f64;
-
- /// Scaled median of the absolute deviations of each sample from the sample median. This is a
- /// robust (distribution-agnostic) estimator of sample variability. Use this in preference to
- /// `std_dev` if you cannot assume your sample is normally distributed. Note that this is scaled
- /// by the constant `1.4826` to allow its use as a consistent estimator for the standard
- /// deviation.
- ///
- /// See: <http://en.wikipedia.org/wiki/Median_absolute_deviation>
- fn median_abs_dev(&self) -> f64;
-
- /// Median absolute deviation as a percent of the median. See `median_abs_dev` and `median`.
- fn median_abs_dev_pct(&self) -> f64;
-
- /// Percentile: the value below which `pct` percent of the values in `self` fall. For example,
- /// percentile(95.0) will return the value `v` such that 95% of the samples `s` in `self`
- /// satisfy `s <= v`.
- ///
- /// Calculated by linear interpolation between closest ranks.
- ///
- /// See: <http://en.wikipedia.org/wiki/Percentile>
- fn percentile(&self, pct: f64) -> f64;
-
- /// Quartiles of the sample: three values that divide the sample into four equal groups, each
- /// with 1/4 of the data. The middle value is the median. See `median` and `percentile`. This
- /// function may calculate the 3 quartiles more efficiently than 3 calls to `percentile`, but
- /// is otherwise equivalent.
- ///
- /// See also: <https://en.wikipedia.org/wiki/Quartile>
- fn quartiles(&self) -> (f64, f64, f64);
-
- /// Inter-quartile range: the difference between the 25th percentile (1st quartile) and the 75th
- /// percentile (3rd quartile). See `quartiles`.
- ///
- /// See also: <https://en.wikipedia.org/wiki/Interquartile_range>
- fn iqr(&self) -> f64;
-}
-
-/// Extracted collection of all the summary statistics of a sample set.
-#[derive(Clone, PartialEq, Copy)]
-#[allow(missing_docs)]
-pub struct Summary {
- pub sum: f64,
- pub min: f64,
- pub max: f64,
- pub mean: f64,
- pub median: f64,
- pub var: f64,
- pub std_dev: f64,
- pub std_dev_pct: f64,
- pub median_abs_dev: f64,
- pub median_abs_dev_pct: f64,
- pub quartiles: (f64, f64, f64),
- pub iqr: f64,
-}
-
-impl Summary {
- /// Construct a new summary of a sample set.
- pub fn new(samples: &[f64]) -> Summary {
- Summary {
- sum: samples.sum(),
- min: samples.min(),
- max: samples.max(),
- mean: samples.mean(),
- median: samples.median(),
- var: samples.var(),
- std_dev: samples.std_dev(),
- std_dev_pct: samples.std_dev_pct(),
- median_abs_dev: samples.median_abs_dev(),
- median_abs_dev_pct: samples.median_abs_dev_pct(),
- quartiles: samples.quartiles(),
- iqr: samples.iqr(),
- }
- }
-}
-
-impl Stats for [f64] {
- // FIXME #11059 handle NaN, inf and overflow
- fn sum(&self) -> f64 {
- let mut partials = vec![];
-
- for &x in self {
- let mut x = x;
- let mut j = 0;
- // This inner loop applies `hi`/`lo` summation to each
- // partial so that the list of partial sums remains exact.
- for i in 0..partials.len() {
- let mut y: f64 = partials[i];
- if x.abs() < y.abs() {
- mem::swap(&mut x, &mut y);
- }
- // Rounded `x+y` is stored in `hi` with round-off stored in
- // `lo`. Together `hi+lo` are exactly equal to `x+y`.
- let hi = x + y;
- let lo = y - (hi - x);
- if lo != 0.0 {
- partials[j] = lo;
- j += 1;
- }
- x = hi;
- }
- if j >= partials.len() {
- partials.push(x);
- } else {
- partials[j] = x;
- partials.truncate(j + 1);
- }
- }
- let zero: f64 = 0.0;
- partials.iter().fold(zero, |p, q| p + *q)
- }
-
- fn min(&self) -> f64 {
- assert!(!self.is_empty());
- self.iter().fold(self[0], |p, q| p.min(*q))
- }
-
- fn max(&self) -> f64 {
- assert!(!self.is_empty());
- self.iter().fold(self[0], |p, q| p.max(*q))
- }
-
- fn mean(&self) -> f64 {
- assert!(!self.is_empty());
- self.sum() / (self.len() as f64)
- }
-
- fn median(&self) -> f64 {
- self.percentile(50 as f64)
- }
-
- fn var(&self) -> f64 {
- if self.len() < 2 {
- 0.0
- } else {
- let mean = self.mean();
- let mut v: f64 = 0.0;
- for s in self {
- let x = *s - mean;
- v = v + x * x;
- }
- // N.B., this is _supposed to be_ len-1, not len. If you
- // change it back to len, you will be calculating a
- // population variance, not a sample variance.
- let denom = (self.len() - 1) as f64;
- v / denom
- }
- }
-
- fn std_dev(&self) -> f64 {
- self.var().sqrt()
- }
-
- fn std_dev_pct(&self) -> f64 {
- let hundred = 100 as f64;
- (self.std_dev() / self.mean()) * hundred
- }
-
- fn median_abs_dev(&self) -> f64 {
- let med = self.median();
- let abs_devs: Vec<f64> = self.iter().map(|&v| (med - v).abs()).collect();
- // This constant is derived by smarter statistics brains than me, but it is
- // consistent with how R and other packages treat the MAD.
- let number = 1.4826;
- abs_devs.median() * number
- }
-
- fn median_abs_dev_pct(&self) -> f64 {
- let hundred = 100 as f64;
- (self.median_abs_dev() / self.median()) * hundred
- }
-
- fn percentile(&self, pct: f64) -> f64 {
- let mut tmp = self.to_vec();
- local_sort(&mut tmp);
- percentile_of_sorted(&tmp, pct)
- }
-
- fn quartiles(&self) -> (f64, f64, f64) {
- let mut tmp = self.to_vec();
- local_sort(&mut tmp);
- let first = 25f64;
- let a = percentile_of_sorted(&tmp, first);
- let second = 50f64;
- let b = percentile_of_sorted(&tmp, second);
- let third = 75f64;
- let c = percentile_of_sorted(&tmp, third);
- (a, b, c)
- }
-
- fn iqr(&self) -> f64 {
- let (a, _, c) = self.quartiles();
- c - a
- }
-}
-
-// Helper function: extract a value representing the `pct` percentile of a sorted sample-set, using
-// linear interpolation. If samples are not sorted, return nonsensical value.
-fn percentile_of_sorted(sorted_samples: &[f64], pct: f64) -> f64 {
- assert!(!sorted_samples.is_empty());
- if sorted_samples.len() == 1 {
- return sorted_samples[0];
- }
- let zero: f64 = 0.0;
- assert!(zero <= pct);
- let hundred = 100f64;
- assert!(pct <= hundred);
- if pct == hundred {
- return sorted_samples[sorted_samples.len() - 1];
- }
- let length = (sorted_samples.len() - 1) as f64;
- let rank = (pct / hundred) * length;
- let lrank = rank.floor();
- let d = rank - lrank;
- let n = lrank as usize;
- let lo = sorted_samples[n];
- let hi = sorted_samples[n + 1];
- lo + (hi - lo) * d
-}
-
-/// Winsorize a set of samples, replacing values above the `100-pct` percentile
-/// and below the `pct` percentile with those percentiles themselves. This is a
-/// way of minimizing the effect of outliers, at the cost of biasing the sample.
-/// It differs from trimming in that it does not change the number of samples,
-/// just changes the values of those that are outliers.
-///
-/// See: <http://en.wikipedia.org/wiki/Winsorising>
-pub fn winsorize(samples: &mut [f64], pct: f64) {
- let mut tmp = samples.to_vec();
- local_sort(&mut tmp);
- let lo = percentile_of_sorted(&tmp, pct);
- let hundred = 100 as f64;
- let hi = percentile_of_sorted(&tmp, hundred - pct);
- for samp in samples {
- if *samp > hi {
- *samp = hi
- } else if *samp < lo {
- *samp = lo
- }
- }
-}
-
-// Test vectors generated from R, using the script src/etc/stat-test-vectors.r.
-
-#[cfg(test)]
-mod tests {
- use crate::stats::Stats;
- use crate::stats::Summary;
- use std::f64;
- use std::io::prelude::*;
- use std::io;
-
- macro_rules! assert_approx_eq {
- ($a: expr, $b: expr) => {{
- let (a, b) = (&$a, &$b);
- assert!(
- (*a - *b).abs() < 1.0e-6,
- "{} is not approximately equal to {}",
- *a,
- *b
- );
- }};
- }
-
- fn check(samples: &[f64], summ: &Summary) {
- let summ2 = Summary::new(samples);
-
- let mut w = io::sink();
- let w = &mut w;
- (write!(w, "\n")).unwrap();
-
- assert_eq!(summ.sum, summ2.sum);
- assert_eq!(summ.min, summ2.min);
- assert_eq!(summ.max, summ2.max);
- assert_eq!(summ.mean, summ2.mean);
- assert_eq!(summ.median, summ2.median);
-
- // We needed a few more digits to get exact equality on these
- // but they're within float epsilon, which is 1.0e-6.
- assert_approx_eq!(summ.var, summ2.var);
- assert_approx_eq!(summ.std_dev, summ2.std_dev);
- assert_approx_eq!(summ.std_dev_pct, summ2.std_dev_pct);
- assert_approx_eq!(summ.median_abs_dev, summ2.median_abs_dev);
- assert_approx_eq!(summ.median_abs_dev_pct, summ2.median_abs_dev_pct);
-
- assert_eq!(summ.quartiles, summ2.quartiles);
- assert_eq!(summ.iqr, summ2.iqr);
- }
-
- #[test]
- fn test_min_max_nan() {
- let xs = &[1.0, 2.0, f64::NAN, 3.0, 4.0];
- let summary = Summary::new(xs);
- assert_eq!(summary.min, 1.0);
- assert_eq!(summary.max, 4.0);
- }
-
- #[test]
- fn test_norm2() {
- let val = &[958.0000000000, 924.0000000000];
- let summ = &Summary {
- sum: 1882.0000000000,
- min: 924.0000000000,
- max: 958.0000000000,
- mean: 941.0000000000,
- median: 941.0000000000,
- var: 578.0000000000,
- std_dev: 24.0416305603,
- std_dev_pct: 2.5549022912,
- median_abs_dev: 25.2042000000,
- median_abs_dev_pct: 2.6784484591,
- quartiles: (932.5000000000, 941.0000000000, 949.5000000000),
- iqr: 17.0000000000,
- };
- check(val, summ);
- }
- #[test]
- fn test_norm10narrow() {
- let val = &[
- 966.0000000000,
- 985.0000000000,
- 1110.0000000000,
- 848.0000000000,
- 821.0000000000,
- 975.0000000000,
- 962.0000000000,
- 1157.0000000000,
- 1217.0000000000,
- 955.0000000000,
- ];
- let summ = &Summary {
- sum: 9996.0000000000,
- min: 821.0000000000,
- max: 1217.0000000000,
- mean: 999.6000000000,
- median: 970.5000000000,
- var: 16050.7111111111,
- std_dev: 126.6914010938,
- std_dev_pct: 12.6742097933,
- median_abs_dev: 102.2994000000,
- median_abs_dev_pct: 10.5408964451,
- quartiles: (956.7500000000, 970.5000000000, 1078.7500000000),
- iqr: 122.0000000000,
- };
- check(val, summ);
- }
- #[test]
- fn test_norm10medium() {
- let val = &[
- 954.0000000000,
- 1064.0000000000,
- 855.0000000000,
- 1000.0000000000,
- 743.0000000000,
- 1084.0000000000,
- 704.0000000000,
- 1023.0000000000,
- 357.0000000000,
- 869.0000000000,
- ];
- let summ = &Summary {
- sum: 8653.0000000000,
- min: 357.0000000000,
- max: 1084.0000000000,
- mean: 865.3000000000,
- median: 911.5000000000,
- var: 48628.4555555556,
- std_dev: 220.5186059170,
- std_dev_pct: 25.4846418487,
- median_abs_dev: 195.7032000000,
- median_abs_dev_pct: 21.4704552935,
- quartiles: (771.0000000000, 911.5000000000, 1017.2500000000),
- iqr: 246.2500000000,
- };
- check(val, summ);
- }
- #[test]
- fn test_norm10wide() {
- let val = &[
- 505.0000000000,
- 497.0000000000,
- 1591.0000000000,
- 887.0000000000,
- 1026.0000000000,
- 136.0000000000,
- 1580.0000000000,
- 940.0000000000,
- 754.0000000000,
- 1433.0000000000,
- ];
- let summ = &Summary {
- sum: 9349.0000000000,
- min: 136.0000000000,
- max: 1591.0000000000,
- mean: 934.9000000000,
- median: 913.5000000000,
- var: 239208.9888888889,
- std_dev: 489.0899599142,
- std_dev_pct: 52.3146817750,
- median_abs_dev: 611.5725000000,
- median_abs_dev_pct: 66.9482758621,
- quartiles: (567.2500000000, 913.5000000000, 1331.2500000000),
- iqr: 764.0000000000,
- };
- check(val, summ);
- }
- #[test]
- fn test_norm25verynarrow() {
- let val = &[
- 991.0000000000,
- 1018.0000000000,
- 998.0000000000,
- 1013.0000000000,
- 974.0000000000,
- 1007.0000000000,
- 1014.0000000000,
- 999.0000000000,
- 1011.0000000000,
- 978.0000000000,
- 985.0000000000,
- 999.0000000000,
- 983.0000000000,
- 982.0000000000,
- 1015.0000000000,
- 1002.0000000000,
- 977.0000000000,
- 948.0000000000,
- 1040.0000000000,
- 974.0000000000,
- 996.0000000000,
- 989.0000000000,
- 1015.0000000000,
- 994.0000000000,
- 1024.0000000000,
- ];
- let summ = &Summary {
- sum: 24926.0000000000,
- min: 948.0000000000,
- max: 1040.0000000000,
- mean: 997.0400000000,
- median: 998.0000000000,
- var: 393.2066666667,
- std_dev: 19.8294393937,
- std_dev_pct: 1.9888308788,
- median_abs_dev: 22.2390000000,
- median_abs_dev_pct: 2.2283567134,
- quartiles: (983.0000000000, 998.0000000000, 1013.0000000000),
- iqr: 30.0000000000,
- };
- check(val, summ);
- }
- #[test]
- fn test_exp10a() {
- let val = &[
- 23.0000000000,
- 11.0000000000,
- 2.0000000000,
- 57.0000000000,
- 4.0000000000,
- 12.0000000000,
- 5.0000000000,
- 29.0000000000,
- 3.0000000000,
- 21.0000000000,
- ];
- let summ = &Summary {
- sum: 167.0000000000,
- min: 2.0000000000,
- max: 57.0000000000,
- mean: 16.7000000000,
- median: 11.5000000000,
- var: 287.7888888889,
- std_dev: 16.9643416875,
- std_dev_pct: 101.5828843560,
- median_abs_dev: 13.3434000000,
- median_abs_dev_pct: 116.0295652174,
- quartiles: (4.2500000000, 11.5000000000, 22.5000000000),
- iqr: 18.2500000000,
- };
- check(val, summ);
- }
- #[test]
- fn test_exp10b() {
- let val = &[
- 24.0000000000,
- 17.0000000000,
- 6.0000000000,
- 38.0000000000,
- 25.0000000000,
- 7.0000000000,
- 51.0000000000,
- 2.0000000000,
- 61.0000000000,
- 32.0000000000,
- ];
- let summ = &Summary {
- sum: 263.0000000000,
- min: 2.0000000000,
- max: 61.0000000000,
- mean: 26.3000000000,
- median: 24.5000000000,
- var: 383.5666666667,
- std_dev: 19.5848580967,
- std_dev_pct: 74.4671410520,
- median_abs_dev: 22.9803000000,
- median_abs_dev_pct: 93.7971428571,
- quartiles: (9.5000000000, 24.5000000000, 36.5000000000),
- iqr: 27.0000000000,
- };
- check(val, summ);
- }
- #[test]
- fn test_exp10c() {
- let val = &[
- 71.0000000000,
- 2.0000000000,
- 32.0000000000,
- 1.0000000000,
- 6.0000000000,
- 28.0000000000,
- 13.0000000000,
- 37.0000000000,
- 16.0000000000,
- 36.0000000000,
- ];
- let summ = &Summary {
- sum: 242.0000000000,
- min: 1.0000000000,
- max: 71.0000000000,
- mean: 24.2000000000,
- median: 22.0000000000,
- var: 458.1777777778,
- std_dev: 21.4050876611,
- std_dev_pct: 88.4507754589,
- median_abs_dev: 21.4977000000,
- median_abs_dev_pct: 97.7168181818,
- quartiles: (7.7500000000, 22.0000000000, 35.0000000000),
- iqr: 27.2500000000,
- };
- check(val, summ);
- }
- #[test]
- fn test_exp25() {
- let val = &[
- 3.0000000000,
- 24.0000000000,
- 1.0000000000,
- 19.0000000000,
- 7.0000000000,
- 5.0000000000,
- 30.0000000000,
- 39.0000000000,
- 31.0000000000,
- 13.0000000000,
- 25.0000000000,
- 48.0000000000,
- 1.0000000000,
- 6.0000000000,
- 42.0000000000,
- 63.0000000000,
- 2.0000000000,
- 12.0000000000,
- 108.0000000000,
- 26.0000000000,
- 1.0000000000,
- 7.0000000000,
- 44.0000000000,
- 25.0000000000,
- 11.0000000000,
- ];
- let summ = &Summary {
- sum: 593.0000000000,
- min: 1.0000000000,
- max: 108.0000000000,
- mean: 23.7200000000,
- median: 19.0000000000,
- var: 601.0433333333,
- std_dev: 24.5161851301,
- std_dev_pct: 103.3565983562,
- median_abs_dev: 19.2738000000,
- median_abs_dev_pct: 101.4410526316,
- quartiles: (6.0000000000, 19.0000000000, 31.0000000000),
- iqr: 25.0000000000,
- };
- check(val, summ);
- }
- #[test]
- fn test_binom25() {
- let val = &[
- 18.0000000000,
- 17.0000000000,
- 27.0000000000,
- 15.0000000000,
- 21.0000000000,
- 25.0000000000,
- 17.0000000000,
- 24.0000000000,
- 25.0000000000,
- 24.0000000000,
- 26.0000000000,
- 26.0000000000,
- 23.0000000000,
- 15.0000000000,
- 23.0000000000,
- 17.0000000000,
- 18.0000000000,
- 18.0000000000,
- 21.0000000000,
- 16.0000000000,
- 15.0000000000,
- 31.0000000000,
- 20.0000000000,
- 17.0000000000,
- 15.0000000000,
- ];
- let summ = &Summary {
- sum: 514.0000000000,
- min: 15.0000000000,
- max: 31.0000000000,
- mean: 20.5600000000,
- median: 20.0000000000,
- var: 20.8400000000,
- std_dev: 4.5650848842,
- std_dev_pct: 22.2037202539,
- median_abs_dev: 5.9304000000,
- median_abs_dev_pct: 29.6520000000,
- quartiles: (17.0000000000, 20.0000000000, 24.0000000000),
- iqr: 7.0000000000,
- };
- check(val, summ);
- }
- #[test]
- fn test_pois25lambda30() {
- let val = &[
- 27.0000000000,
- 33.0000000000,
- 34.0000000000,
- 34.0000000000,
- 24.0000000000,
- 39.0000000000,
- 28.0000000000,
- 27.0000000000,
- 31.0000000000,
- 28.0000000000,
- 38.0000000000,
- 21.0000000000,
- 33.0000000000,
- 36.0000000000,
- 29.0000000000,
- 37.0000000000,
- 32.0000000000,
- 34.0000000000,
- 31.0000000000,
- 39.0000000000,
- 25.0000000000,
- 31.0000000000,
- 32.0000000000,
- 40.0000000000,
- 24.0000000000,
- ];
- let summ = &Summary {
- sum: 787.0000000000,
- min: 21.0000000000,
- max: 40.0000000000,
- mean: 31.4800000000,
- median: 32.0000000000,
- var: 26.5933333333,
- std_dev: 5.1568724372,
- std_dev_pct: 16.3814245145,
- median_abs_dev: 5.9304000000,
- median_abs_dev_pct: 18.5325000000,
- quartiles: (28.0000000000, 32.0000000000, 34.0000000000),
- iqr: 6.0000000000,
- };
- check(val, summ);
- }
- #[test]
- fn test_pois25lambda40() {
- let val = &[
- 42.0000000000,
- 50.0000000000,
- 42.0000000000,
- 46.0000000000,
- 34.0000000000,
- 45.0000000000,
- 34.0000000000,
- 49.0000000000,
- 39.0000000000,
- 28.0000000000,
- 40.0000000000,
- 35.0000000000,
- 37.0000000000,
- 39.0000000000,
- 46.0000000000,
- 44.0000000000,
- 32.0000000000,
- 45.0000000000,
- 42.0000000000,
- 37.0000000000,
- 48.0000000000,
- 42.0000000000,
- 33.0000000000,
- 42.0000000000,
- 48.0000000000,
- ];
- let summ = &Summary {
- sum: 1019.0000000000,
- min: 28.0000000000,
- max: 50.0000000000,
- mean: 40.7600000000,
- median: 42.0000000000,
- var: 34.4400000000,
- std_dev: 5.8685603004,
- std_dev_pct: 14.3978417577,
- median_abs_dev: 5.9304000000,
- median_abs_dev_pct: 14.1200000000,
- quartiles: (37.0000000000, 42.0000000000, 45.0000000000),
- iqr: 8.0000000000,
- };
- check(val, summ);
- }
- #[test]
- fn test_pois25lambda50() {
- let val = &[
- 45.0000000000,
- 43.0000000000,
- 44.0000000000,
- 61.0000000000,
- 51.0000000000,
- 53.0000000000,
- 59.0000000000,
- 52.0000000000,
- 49.0000000000,
- 51.0000000000,
- 51.0000000000,
- 50.0000000000,
- 49.0000000000,
- 56.0000000000,
- 42.0000000000,
- 52.0000000000,
- 51.0000000000,
- 43.0000000000,
- 48.0000000000,
- 48.0000000000,
- 50.0000000000,
- 42.0000000000,
- 43.0000000000,
- 42.0000000000,
- 60.0000000000,
- ];
- let summ = &Summary {
- sum: 1235.0000000000,
- min: 42.0000000000,
- max: 61.0000000000,
- mean: 49.4000000000,
- median: 50.0000000000,
- var: 31.6666666667,
- std_dev: 5.6273143387,
- std_dev_pct: 11.3913245723,
- median_abs_dev: 4.4478000000,
- median_abs_dev_pct: 8.8956000000,
- quartiles: (44.0000000000, 50.0000000000, 52.0000000000),
- iqr: 8.0000000000,
- };
- check(val, summ);
- }
- #[test]
- fn test_unif25() {
- let val = &[
- 99.0000000000,
- 55.0000000000,
- 92.0000000000,
- 79.0000000000,
- 14.0000000000,
- 2.0000000000,
- 33.0000000000,
- 49.0000000000,
- 3.0000000000,
- 32.0000000000,
- 84.0000000000,
- 59.0000000000,
- 22.0000000000,
- 86.0000000000,
- 76.0000000000,
- 31.0000000000,
- 29.0000000000,
- 11.0000000000,
- 41.0000000000,
- 53.0000000000,
- 45.0000000000,
- 44.0000000000,
- 98.0000000000,
- 98.0000000000,
- 7.0000000000,
- ];
- let summ = &Summary {
- sum: 1242.0000000000,
- min: 2.0000000000,
- max: 99.0000000000,
- mean: 49.6800000000,
- median: 45.0000000000,
- var: 1015.6433333333,
- std_dev: 31.8691595957,
- std_dev_pct: 64.1488719719,
- median_abs_dev: 45.9606000000,
- median_abs_dev_pct: 102.1346666667,
- quartiles: (29.0000000000, 45.0000000000, 79.0000000000),
- iqr: 50.0000000000,
- };
- check(val, summ);
- }
-
- #[test]
- fn test_sum_f64s() {
- assert_eq!([0.5f64, 3.2321f64, 1.5678f64].sum(), 5.2999);
- }
- #[test]
- fn test_sum_f64_between_ints_that_sum_to_0() {
- assert_eq!([1e30f64, 1.2f64, -1e30f64].sum(), 1.2);
- }
-}
-
-#[cfg(test)]
-mod bench {
- extern crate test;
- use self::test::Bencher;
- use crate::stats::Stats;
-
- #[bench]
- pub fn sum_three_items(b: &mut Bencher) {
- b.iter(|| {
- [1e20f64, 1.5f64, -1e20f64].sum();
- })
- }
- #[bench]
- pub fn sum_many_f64(b: &mut Bencher) {
- let nums = [-1e30f64, 1e60, 1e30, 1.0, -1e60];
- let v = (0..500).map(|i| nums[i % 5]).collect::<Vec<_>>();
-
- b.iter(|| {
- v.sum();
- })
- }
-
- #[bench]
- pub fn no_iter(_: &mut Bencher) {}
-}
diff --git a/src/llvm-project b/src/llvm-project
index 38ad31b..4fc9fb8 160000
--- a/src/llvm-project
+++ b/src/llvm-project
@@ -1 +1 @@
-Subproject commit 38ad31bde8ff681d862dc0f96930a5dd9b7a472e
+Subproject commit 4fc9fb8245abe24680192535870c4522644a4212
diff --git a/src/test/assembly/auxiliary/breakpoint-panic-handler.rs b/src/test/assembly/auxiliary/breakpoint-panic-handler.rs
new file mode 100644
index 0000000..d54c118
--- /dev/null
+++ b/src/test/assembly/auxiliary/breakpoint-panic-handler.rs
@@ -0,0 +1,8 @@
+#![feature(core_intrinsics)]
+#![no_std]
+
+#[panic_handler]
+unsafe fn breakpoint_panic_handler(_: &::core::panic::PanicInfo) -> ! {
+ core::intrinsics::breakpoint();
+ core::hint::unreachable_unchecked();
+}
diff --git a/src/test/run-make/nvptx-dylib-crate/dep.rs b/src/test/assembly/auxiliary/non-inline-dependency.rs
similarity index 100%
rename from src/test/run-make/nvptx-dylib-crate/dep.rs
rename to src/test/assembly/auxiliary/non-inline-dependency.rs
diff --git a/src/test/assembly/nvptx-arch-default.rs b/src/test/assembly/nvptx-arch-default.rs
new file mode 100644
index 0000000..7fe71c3
--- /dev/null
+++ b/src/test/assembly/nvptx-arch-default.rs
@@ -0,0 +1,12 @@
+// assembly-output: ptx-linker
+// compile-flags: --crate-type cdylib
+// only-nvptx64
+
+#![no_std]
+
+// aux-build: breakpoint-panic-handler.rs
+extern crate breakpoint_panic_handler;
+
+// Verify default target arch with ptx-linker.
+// CHECK: .target sm_30
+// CHECK: .address_size 64
diff --git a/src/test/assembly/nvptx-arch-emit-asm.rs b/src/test/assembly/nvptx-arch-emit-asm.rs
new file mode 100644
index 0000000..0ca1772
--- /dev/null
+++ b/src/test/assembly/nvptx-arch-emit-asm.rs
@@ -0,0 +1,9 @@
+// assembly-output: emit-asm
+// compile-flags: --crate-type rlib
+// only-nvptx64
+
+#![no_std]
+
+// Verify default arch without ptx-linker involved.
+// CHECK: .target sm_30
+// CHECK: .address_size 64
diff --git a/src/test/assembly/nvptx-arch-link-arg.rs b/src/test/assembly/nvptx-arch-link-arg.rs
new file mode 100644
index 0000000..f6b6e8c
--- /dev/null
+++ b/src/test/assembly/nvptx-arch-link-arg.rs
@@ -0,0 +1,12 @@
+// assembly-output: ptx-linker
+// compile-flags: --crate-type cdylib -C link-arg=--arch=sm_60
+// only-nvptx64
+
+#![no_std]
+
+// aux-build: breakpoint-panic-handler.rs
+extern crate breakpoint_panic_handler;
+
+// Verify target arch override via `link-arg`.
+// CHECK: .target sm_60
+// CHECK: .address_size 64
diff --git a/src/test/assembly/nvptx-arch-target-cpu.rs b/src/test/assembly/nvptx-arch-target-cpu.rs
new file mode 100644
index 0000000..08a7a19
--- /dev/null
+++ b/src/test/assembly/nvptx-arch-target-cpu.rs
@@ -0,0 +1,12 @@
+// assembly-output: ptx-linker
+// compile-flags: --crate-type cdylib -C target-cpu=sm_50
+// only-nvptx64
+
+#![no_std]
+
+// aux-build: breakpoint-panic-handler.rs
+extern crate breakpoint_panic_handler;
+
+// Verify target arch override via `target-cpu`.
+// CHECK: .target sm_50
+// CHECK: .address_size 64
diff --git a/src/test/assembly/nvptx-atomics.rs b/src/test/assembly/nvptx-atomics.rs
new file mode 100644
index 0000000..3bbd7b3
--- /dev/null
+++ b/src/test/assembly/nvptx-atomics.rs
@@ -0,0 +1,85 @@
+// assembly-output: ptx-linker
+// compile-flags: --crate-type cdylib
+// only-nvptx64
+
+#![feature(abi_ptx, core_intrinsics)]
+#![no_std]
+
+use core::intrinsics::*;
+
+// aux-build: breakpoint-panic-handler.rs
+extern crate breakpoint_panic_handler;
+
+// Currently, LLVM NVPTX backend can only emit atomic instructions with
+// `relaxed` (PTX default) ordering. But it's also useful to make sure
+// the backend won't fail with other orders. Apparently, the backend
+// doesn't support fences as well. As a workaround `llvm.nvvm.membar.*`
+// could work, and perhaps on the long run, all the atomic operations
+// should rather be provided by `core::arch::nvptx`.
+
+// Also, PTX ISA doesn't have atomic `load`, `store` and `nand`.
+
+// FIXME(denzp): add tests for `core::sync::atomic::*`.
+
+#[no_mangle]
+pub unsafe extern "ptx-kernel" fn atomics_kernel(a: *mut u32) {
+ // CHECK: atom.global.and.b32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
+ // CHECK: atom.global.and.b32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
+ atomic_and(a, 1);
+ atomic_and_relaxed(a, 1);
+
+ // CHECK: atom.global.cas.b32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1, 2;
+ // CHECK: atom.global.cas.b32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1, 2;
+ atomic_cxchg(a, 1, 2);
+ atomic_cxchg_relaxed(a, 1, 2);
+
+ // CHECK: atom.global.max.s32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
+ // CHECK: atom.global.max.s32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
+ atomic_max(a, 1);
+ atomic_max_relaxed(a, 1);
+
+ // CHECK: atom.global.min.s32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
+ // CHECK: atom.global.min.s32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
+ atomic_min(a, 1);
+ atomic_min_relaxed(a, 1);
+
+ // CHECK: atom.global.or.b32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
+ // CHECK: atom.global.or.b32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
+ atomic_or(a, 1);
+ atomic_or_relaxed(a, 1);
+
+ // CHECK: atom.global.max.u32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
+ // CHECK: atom.global.max.u32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
+ atomic_umax(a, 1);
+ atomic_umax_relaxed(a, 1);
+
+ // CHECK: atom.global.min.u32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
+ // CHECK: atom.global.min.u32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
+ atomic_umin(a, 1);
+ atomic_umin_relaxed(a, 1);
+
+ // CHECK: atom.global.add.u32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
+ // CHECK: atom.global.add.u32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
+ atomic_xadd(a, 1);
+ atomic_xadd_relaxed(a, 1);
+
+ // CHECK: atom.global.exch.b32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
+ // CHECK: atom.global.exch.b32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
+ atomic_xchg(a, 1);
+ atomic_xchg_relaxed(a, 1);
+
+ // CHECK: atom.global.xor.b32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
+ // CHECK: atom.global.xor.b32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
+ atomic_xor(a, 1);
+ atomic_xor_relaxed(a, 1);
+
+ // CHECK: mov.u32 %[[sub_0_arg:r[0-9]+]], 100;
+ // CHECK: neg.s32 temp, %[[sub_0_arg]];
+ // CHECK: atom.global.add.u32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], temp;
+ atomic_xsub(a, 100);
+
+ // CHECK: mov.u32 %[[sub_1_arg:r[0-9]+]], 200;
+ // CHECK: neg.s32 temp, %[[sub_1_arg]];
+ // CHECK: atom.global.add.u32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], temp;
+ atomic_xsub_relaxed(a, 200);
+}
diff --git a/src/test/assembly/nvptx-internalizing.rs b/src/test/assembly/nvptx-internalizing.rs
new file mode 100644
index 0000000..db82264
--- /dev/null
+++ b/src/test/assembly/nvptx-internalizing.rs
@@ -0,0 +1,27 @@
+// assembly-output: ptx-linker
+// compile-flags: --crate-type cdylib
+// only-nvptx64
+
+#![feature(abi_ptx)]
+#![no_std]
+
+// aux-build: breakpoint-panic-handler.rs
+extern crate breakpoint_panic_handler;
+
+// aux-build: non-inline-dependency.rs
+extern crate non_inline_dependency as dep;
+
+// Verify that no extra function declarations are present.
+// CHECK-NOT: .func
+
+// CHECK: .visible .entry top_kernel(
+#[no_mangle]
+pub unsafe extern "ptx-kernel" fn top_kernel(a: *const u32, b: *mut u32) {
+ // CHECK: add.s32 %{{r[0-9]+}}, %{{r[0-9]+}}, 5;
+ *b = *a + 5;
+}
+
+// Verify that no extra function definitions are here.
+// CHECK-NOT: .func
+// CHECK-NOT: .entry
+
diff --git a/src/test/assembly/nvptx-linking-binary.rs b/src/test/assembly/nvptx-linking-binary.rs
new file mode 100644
index 0000000..d88ed91
--- /dev/null
+++ b/src/test/assembly/nvptx-linking-binary.rs
@@ -0,0 +1,39 @@
+// assembly-output: ptx-linker
+// compile-flags: --crate-type bin
+// only-nvptx64
+
+#![feature(abi_ptx)]
+#![no_main]
+#![no_std]
+
+// aux-build: breakpoint-panic-handler.rs
+extern crate breakpoint_panic_handler;
+
+// aux-build: non-inline-dependency.rs
+extern crate non_inline_dependency as dep;
+
+// Make sure declarations are there.
+// CHECK: .func (.param .b32 func_retval0) wrapping_external_fn
+// CHECK: .func (.param .b32 func_retval0) panicking_external_fn
+
+// CHECK-LABEL: .visible .entry top_kernel(
+#[no_mangle]
+pub unsafe extern "ptx-kernel" fn top_kernel(a: *const u32, b: *mut u32) {
+ // CHECK: call.uni (retval0),
+ // CHECK-NEXT: wrapping_external_fn
+ // CHECK: ld.param.b32 %[[LHS:r[0-9]+]], [retval0+0];
+ let lhs = dep::wrapping_external_fn(*a);
+
+ // CHECK: call.uni (retval0),
+ // CHECK-NEXT: panicking_external_fn
+ // CHECK: ld.param.b32 %[[RHS:r[0-9]+]], [retval0+0];
+ let rhs = dep::panicking_external_fn(*a);
+
+ // CHECK: add.s32 %[[RES:r[0-9]+]], %[[RHS]], %[[LHS]];
+ // CHECK: st.global.u32 [%{{rd[0-9]+}}], %[[RES]];
+ *b = lhs + rhs;
+}
+
+// Verify that external function bodies are available.
+// CHECK: .func (.param .b32 func_retval0) wrapping_external_fn
+// CHECK: .func (.param .b32 func_retval0) panicking_external_fn
diff --git a/src/test/assembly/nvptx-linking-cdylib.rs b/src/test/assembly/nvptx-linking-cdylib.rs
new file mode 100644
index 0000000..1145f56
--- /dev/null
+++ b/src/test/assembly/nvptx-linking-cdylib.rs
@@ -0,0 +1,38 @@
+// assembly-output: ptx-linker
+// compile-flags: --crate-type cdylib
+// only-nvptx64
+
+#![feature(abi_ptx)]
+#![no_std]
+
+// aux-build: breakpoint-panic-handler.rs
+extern crate breakpoint_panic_handler;
+
+// aux-build: non-inline-dependency.rs
+extern crate non_inline_dependency as dep;
+
+// Make sure declarations are there.
+// CHECK: .func (.param .b32 func_retval0) wrapping_external_fn
+// CHECK: .func (.param .b32 func_retval0) panicking_external_fn
+
+// CHECK-LABEL: .visible .entry top_kernel(
+#[no_mangle]
+pub unsafe extern "ptx-kernel" fn top_kernel(a: *const u32, b: *mut u32) {
+ // CHECK: call.uni (retval0),
+ // CHECK-NEXT: wrapping_external_fn
+ // CHECK: ld.param.b32 %[[LHS:r[0-9]+]], [retval0+0];
+ let lhs = dep::wrapping_external_fn(*a);
+
+ // CHECK: call.uni (retval0),
+ // CHECK-NEXT: panicking_external_fn
+ // CHECK: ld.param.b32 %[[RHS:r[0-9]+]], [retval0+0];
+ let rhs = dep::panicking_external_fn(*a);
+
+ // CHECK: add.s32 %[[RES:r[0-9]+]], %[[RHS]], %[[LHS]];
+ // CHECK: st.global.u32 [%{{rd[0-9]+}}], %[[RES]];
+ *b = lhs + rhs;
+}
+
+// Verify that external function bodies are available.
+// CHECK: .func (.param .b32 func_retval0) wrapping_external_fn
+// CHECK: .func (.param .b32 func_retval0) panicking_external_fn
diff --git a/src/test/run-make/nvptx-emit-asm/kernel.rs b/src/test/assembly/nvptx-safe-naming.rs
similarity index 63%
rename from src/test/run-make/nvptx-emit-asm/kernel.rs
rename to src/test/assembly/nvptx-safe-naming.rs
index b71e18d..ab6f914 100644
--- a/src/test/run-make/nvptx-emit-asm/kernel.rs
+++ b/src/test/assembly/nvptx-safe-naming.rs
@@ -1,13 +1,15 @@
-#![no_std]
-#![deny(warnings)]
-#![feature(abi_ptx)]
+// assembly-output: ptx-linker
+// compile-flags: --crate-type cdylib
+// only-nvptx64
-// Verify the default CUDA arch.
-// CHECK: .target sm_30
-// CHECK: .address_size 64
+#![feature(abi_ptx)]
+#![no_std]
+
+// aux-build: breakpoint-panic-handler.rs
+extern crate breakpoint_panic_handler;
// Verify function name doesn't contain unacceaptable characters.
-// CHECK: .func (.param .b32 func_retval0) [[IMPL_FN:_ZN[a-zA-Z0-9$_]+square[a-zA-Z0-9$_]+]]
+// CHECK: .func (.param .b32 func_retval0) [[IMPL_FN:[a-zA-Z0-9$_]+square[a-zA-Z0-9$_]+]](
// CHECK-LABEL: .visible .entry top_kernel(
#[no_mangle]
@@ -33,9 +35,3 @@
}
}
}
-
-// Verify that external function bodies are available.
-// CHECK: .func (.param .b32 func_retval0) [[IMPL_FN]]
-// CHECK: {
-// CHECK: mul.lo.s32 %{{r[0-9]+}}, %{{r[0-9]+}}, %{{r[0-9]+}}
-// CHECK: }
diff --git a/src/test/compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs b/src/test/compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs
deleted file mode 100644
index 16630e2..0000000
--- a/src/test/compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-// force-host
-
-#![feature(plugin_registrar)]
-#![feature(box_syntax, rustc_private)]
-
-// Load rustc as a plugin to get macros.
-#[macro_use]
-extern crate rustc;
-extern crate rustc_plugin;
-
-use rustc::hir;
-use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass, LateLintPassObject, LintArray};
-use rustc_plugin::Registry;
-
-declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'");
-
-declare_lint!(PLEASE_LINT, Warn, "Warn about items named 'pleaselintme'");
-
-struct Pass;
-
-impl LintPass for Pass {
- fn name(&self) -> &'static str {
- "Pass"
- }
-
- fn get_lints(&self) -> LintArray {
- lint_array!(TEST_LINT, PLEASE_LINT)
- }
-}
-
-impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
- fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
- match &*it.ident.as_str() {
- "lintme" => cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'"),
- "pleaselintme" => cx.span_lint(PLEASE_LINT, it.span, "item is named 'pleaselintme'"),
- _ => {}
- }
- }
-}
-
-#[plugin_registrar]
-pub fn plugin_registrar(reg: &mut Registry) {
- reg.register_late_lint_pass(box Pass);
- reg.register_lint_group("lint_me", None, vec![TEST_LINT, PLEASE_LINT]);
-}
diff --git a/src/test/incremental/hashes/consts.rs b/src/test/incremental/hashes/consts.rs
index 0ab0915..516276a 100644
--- a/src/test/incremental/hashes/consts.rs
+++ b/src/test/incremental/hashes/consts.rs
@@ -29,7 +29,7 @@
const CONST_CHANGE_TYPE_1: i32 = 0;
#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="Hir,HirBody,TypeOfItem")]
+#[rustc_clean(cfg="cfail2", except="Hir,HirBody,type_of")]
#[rustc_clean(cfg="cfail3")]
const CONST_CHANGE_TYPE_1: u32 = 0;
@@ -39,7 +39,7 @@
const CONST_CHANGE_TYPE_2: Option<u32> = None;
#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="Hir,HirBody,TypeOfItem")]
+#[rustc_clean(cfg="cfail2", except="Hir,HirBody,type_of")]
#[rustc_clean(cfg="cfail3")]
const CONST_CHANGE_TYPE_2: Option<u64> = None;
@@ -99,11 +99,11 @@
#[cfg(not(cfail1))]
use super::ReferencedType2 as Type;
- #[rustc_clean(cfg="cfail2", except="Hir,HirBody,TypeOfItem")]
+ #[rustc_clean(cfg="cfail2", except="Hir,HirBody,type_of")]
#[rustc_clean(cfg="cfail3")]
const CONST_CHANGE_TYPE_INDIRECTLY_1: Type = Type;
- #[rustc_clean(cfg="cfail2", except="Hir,HirBody,TypeOfItem")]
+ #[rustc_clean(cfg="cfail2", except="Hir,HirBody,type_of")]
#[rustc_clean(cfg="cfail3")]
const CONST_CHANGE_TYPE_INDIRECTLY_2: Option<Type> = None;
}
diff --git a/src/test/incremental/hashes/enum_defs.rs b/src/test/incremental/hashes/enum_defs.rs
index 2944762..aa2dc79 100644
--- a/src/test/incremental/hashes/enum_defs.rs
+++ b/src/test/incremental/hashes/enum_defs.rs
@@ -42,7 +42,7 @@
}
#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="Hir,HirBody,TypeOfItem")]
+#[rustc_clean(cfg="cfail2", except="Hir,HirBody,type_of")]
#[rustc_clean(cfg="cfail3")]
enum EnumChangeNameCStyleVariant {
Variant1,
@@ -59,7 +59,7 @@
}
#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="Hir,HirBody,TypeOfItem")]
+#[rustc_clean(cfg="cfail2", except="Hir,HirBody,type_of")]
#[rustc_clean(cfg="cfail3")]
enum EnumChangeNameTupleStyleVariant {
Variant1,
@@ -76,7 +76,7 @@
}
#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="Hir,HirBody,TypeOfItem")]
+#[rustc_clean(cfg="cfail2", except="Hir,HirBody,type_of")]
#[rustc_clean(cfg="cfail3")]
enum EnumChangeNameStructStyleVariant {
Variant1,
@@ -109,7 +109,7 @@
}
#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="Hir,HirBody,TypeOfItem")]
+#[rustc_clean(cfg="cfail2", except="Hir,HirBody,type_of")]
#[rustc_clean(cfg="cfail3")]
enum EnumChangeValueCStyleVariant1 {
Variant1,
@@ -125,7 +125,7 @@
}
#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="Hir,HirBody,TypeOfItem")]
+#[rustc_clean(cfg="cfail2", except="Hir,HirBody,type_of")]
#[rustc_clean(cfg="cfail3")]
enum EnumAddCStyleVariant {
Variant1,
@@ -142,7 +142,7 @@
}
#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="Hir,HirBody,TypeOfItem")]
+#[rustc_clean(cfg="cfail2", except="Hir,HirBody,type_of")]
#[rustc_clean(cfg="cfail3")]
enum EnumRemoveCStyleVariant {
Variant1,
@@ -157,7 +157,7 @@
}
#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="Hir,HirBody,TypeOfItem")]
+#[rustc_clean(cfg="cfail2", except="Hir,HirBody,type_of")]
#[rustc_clean(cfg="cfail3")]
enum EnumAddTupleStyleVariant {
Variant1,
@@ -174,7 +174,7 @@
}
#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="Hir,HirBody,TypeOfItem")]
+#[rustc_clean(cfg="cfail2", except="Hir,HirBody,type_of")]
#[rustc_clean(cfg="cfail3")]
enum EnumRemoveTupleStyleVariant {
Variant1,
@@ -189,7 +189,7 @@
}
#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="Hir,HirBody,TypeOfItem")]
+#[rustc_clean(cfg="cfail2", except="Hir,HirBody,type_of")]
#[rustc_clean(cfg="cfail3")]
enum EnumAddStructStyleVariant {
Variant1,
@@ -206,7 +206,7 @@
}
#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="Hir,HirBody,TypeOfItem")]
+#[rustc_clean(cfg="cfail2", except="Hir,HirBody,type_of")]
#[rustc_clean(cfg="cfail3")]
enum EnumRemoveStructStyleVariant {
Variant1,
@@ -257,7 +257,7 @@
}
#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="Hir,HirBody,TypeOfItem")]
+#[rustc_clean(cfg="cfail2", except="Hir,HirBody,type_of")]
#[rustc_clean(cfg="cfail3")]
enum EnumChangeFieldNameStructStyleVariant {
Variant1 { a: u32, c: u32 },
@@ -289,7 +289,7 @@
}
#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="Hir,HirBody,TypeOfItem")]
+#[rustc_clean(cfg="cfail2", except="Hir,HirBody,type_of")]
#[rustc_clean(cfg="cfail3")]
enum EnumChangeFieldOrderStructStyleVariant {
Variant1 { b: f32, a: u32 },
@@ -304,7 +304,7 @@
}
#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="Hir,HirBody,TypeOfItem")]
+#[rustc_clean(cfg="cfail2", except="Hir,HirBody,type_of")]
#[rustc_clean(cfg="cfail3")]
enum EnumAddFieldTupleStyleVariant {
Variant1(u32, u32, u32),
@@ -319,7 +319,7 @@
}
#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="Hir,HirBody,TypeOfItem")]
+#[rustc_clean(cfg="cfail2", except="Hir,HirBody,type_of")]
#[rustc_clean(cfg="cfail3")]
enum EnumAddFieldStructStyleVariant {
Variant1 { a: u32, b: u32, c: u32 },
@@ -353,7 +353,7 @@
}
#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="Hir,HirBody,TypeOfItem")]
+#[rustc_clean(cfg="cfail2", except="Hir,HirBody,type_of")]
#[rustc_clean(cfg="cfail3")]
#[repr(C)]
enum EnumAddReprC {
@@ -402,7 +402,7 @@
}
#[cfg(not(cfail1))]
-#[rustc_dirty(cfg="cfail2", except="PredicatesOfItem")]
+#[rustc_dirty(cfg="cfail2", except="predicates_of")]
#[rustc_clean(cfg="cfail3")]
enum EnumChangeNameOfLifetimeParameter<'b> {
Variant1(&'b u32),
@@ -418,7 +418,7 @@
}
#[cfg(not(cfail1))]
-#[rustc_dirty(cfg="cfail2", except="PredicatesOfItem")]
+#[rustc_dirty(cfg="cfail2", except="predicates_of")]
#[rustc_clean(cfg="cfail3")]
enum EnumAddLifetimeParameter<'a, 'b> {
Variant1(&'a u32),
@@ -435,7 +435,7 @@
}
#[cfg(not(cfail1))]
-#[rustc_dirty(cfg="cfail2", except="GenericsOfItem,TypeOfItem")]
+#[rustc_dirty(cfg="cfail2", except="generics_of,type_of")]
#[rustc_clean(cfg="cfail3")]
enum EnumAddLifetimeParameterBound<'a, 'b: 'a> {
Variant1(&'a u32),
@@ -450,7 +450,7 @@
}
#[cfg(not(cfail1))]
-#[rustc_dirty(cfg="cfail2", except="TypeOfItem")]
+#[rustc_dirty(cfg="cfail2", except="type_of")]
#[rustc_clean(cfg="cfail3")]
enum EnumAddLifetimeBoundToParameter<'a, T: 'a> {
Variant1(T),
@@ -482,7 +482,7 @@
}
#[cfg(not(cfail1))]
-#[rustc_dirty(cfg="cfail2", except="GenericsOfItem,TypeOfItem")]
+#[rustc_dirty(cfg="cfail2", except="generics_of,type_of")]
#[rustc_clean(cfg="cfail3")]
enum EnumAddLifetimeParameterBoundWhere<'a, 'b> where 'b: 'a {
Variant1(&'a u32),
@@ -499,7 +499,7 @@
}
#[cfg(not(cfail1))]
-#[rustc_dirty(cfg="cfail2", except="TypeOfItem")]
+#[rustc_dirty(cfg="cfail2", except="type_of")]
#[rustc_clean(cfg="cfail3")]
enum EnumAddLifetimeBoundToParameterWhere<'a, T> where T: 'a {
Variant1(T),
@@ -618,7 +618,7 @@
#[cfg(not(cfail1))]
use super::ReferencedTrait2 as Trait;
- #[rustc_clean(cfg="cfail2", except="Hir,HirBody,PredicatesOfItem")]
+ #[rustc_clean(cfg="cfail2", except="Hir,HirBody,predicates_of")]
#[rustc_clean(cfg="cfail3")]
enum Enum<T: Trait> {
Variant1(T)
@@ -634,7 +634,7 @@
#[cfg(not(cfail1))]
use super::ReferencedTrait2 as Trait;
- #[rustc_clean(cfg="cfail2", except="Hir,HirBody,PredicatesOfItem")]
+ #[rustc_clean(cfg="cfail2", except="Hir,HirBody,predicates_of")]
#[rustc_clean(cfg="cfail3")]
enum Enum<T> where T: Trait {
Variant1(T)
diff --git a/src/test/incremental/hashes/function_interfaces.rs b/src/test/incremental/hashes/function_interfaces.rs
index 4330b00..fccec70 100644
--- a/src/test/incremental/hashes/function_interfaces.rs
+++ b/src/test/incremental/hashes/function_interfaces.rs
@@ -117,7 +117,7 @@
#[cfg(not(cfail1))]
#[rustc_clean(cfg = "cfail2",
- except = "Hir, HirBody, GenericsOfItem, TypeOfItem, PredicatesOfItem")]
+ except = "Hir, HirBody, generics_of, type_of, predicates_of")]
#[rustc_clean(cfg = "cfail3")]
pub fn type_parameter<T>() {}
@@ -128,7 +128,7 @@
pub fn lifetime_parameter() {}
#[cfg(not(cfail1))]
-#[rustc_clean(cfg = "cfail2", except = "Hir, HirBody, GenericsOfItem")]
+#[rustc_clean(cfg = "cfail2", except = "Hir, HirBody, generics_of")]
#[rustc_clean(cfg = "cfail3")]
pub fn lifetime_parameter<'a>() {}
@@ -139,7 +139,7 @@
pub fn trait_bound<T>() {}
#[cfg(not(cfail1))]
-#[rustc_clean(cfg = "cfail2", except = "Hir, HirBody, PredicatesOfItem")]
+#[rustc_clean(cfg = "cfail2", except = "Hir, HirBody, predicates_of")]
#[rustc_clean(cfg = "cfail3")]
pub fn trait_bound<T: Eq>() {}
@@ -150,7 +150,7 @@
pub fn builtin_bound<T>() {}
#[cfg(not(cfail1))]
-#[rustc_clean(cfg = "cfail2", except = "Hir, HirBody, PredicatesOfItem")]
+#[rustc_clean(cfg = "cfail2", except = "Hir, HirBody, predicates_of")]
#[rustc_clean(cfg = "cfail3")]
pub fn builtin_bound<T: Send>() {}
@@ -162,7 +162,7 @@
#[cfg(not(cfail1))]
#[rustc_clean(cfg = "cfail2",
- except = "Hir, HirBody, GenericsOfItem, TypeOfItem, PredicatesOfItem")]
+ except = "Hir, HirBody, generics_of, type_of, predicates_of")]
#[rustc_clean(cfg = "cfail3")]
pub fn lifetime_bound<'a, T: 'a>() {}
@@ -173,7 +173,7 @@
pub fn second_trait_bound<T: Eq>() {}
#[cfg(not(cfail1))]
-#[rustc_clean(cfg = "cfail2", except = "Hir, HirBody, PredicatesOfItem")]
+#[rustc_clean(cfg = "cfail2", except = "Hir, HirBody, predicates_of")]
#[rustc_clean(cfg = "cfail3")]
pub fn second_trait_bound<T: Eq + Clone>() {}
@@ -184,7 +184,7 @@
pub fn second_builtin_bound<T: Send>() {}
#[cfg(not(cfail1))]
-#[rustc_clean(cfg = "cfail2", except = "Hir, HirBody, PredicatesOfItem")]
+#[rustc_clean(cfg = "cfail2", except = "Hir, HirBody, predicates_of")]
#[rustc_clean(cfg = "cfail3")]
pub fn second_builtin_bound<T: Send + Sized>() {}
@@ -196,7 +196,7 @@
#[cfg(not(cfail1))]
#[rustc_clean(cfg = "cfail2",
- except = "Hir, HirBody, GenericsOfItem, TypeOfItem, PredicatesOfItem")]
+ except = "Hir, HirBody, generics_of, type_of, predicates_of")]
#[rustc_clean(cfg = "cfail3")]
pub fn second_lifetime_bound<'a, 'b, T: 'a + 'b>() {}
@@ -326,7 +326,7 @@
#[cfg(not(cfail1))]
use super::ReferencedTrait2 as Trait;
- #[rustc_clean(cfg = "cfail2", except = "Hir, HirBody, PredicatesOfItem")]
+ #[rustc_clean(cfg = "cfail2", except = "Hir, HirBody, predicates_of")]
#[rustc_clean(cfg = "cfail3")]
pub fn indirect_trait_bound<T: Trait>(p: T) {}
}
@@ -340,7 +340,7 @@
#[cfg(not(cfail1))]
use super::ReferencedTrait2 as Trait;
- #[rustc_clean(cfg = "cfail2", except = "Hir, HirBody, PredicatesOfItem")]
+ #[rustc_clean(cfg = "cfail2", except = "Hir, HirBody, predicates_of")]
#[rustc_clean(cfg = "cfail3")]
pub fn indirect_trait_bound_where<T>(p: T)
where
diff --git a/src/test/incremental/hashes/inherent_impls.rs b/src/test/incremental/hashes/inherent_impls.rs
index d1574ae..ebafd07 100644
--- a/src/test/incremental/hashes/inherent_impls.rs
+++ b/src/test/incremental/hashes/inherent_impls.rs
@@ -97,7 +97,7 @@
#[rustc_clean(cfg="cfail2", except="Hir,HirBody")]
#[rustc_clean(cfg="cfail3")]
impl Foo {
- #[rustc_dirty(cfg="cfail2", except="TypeOfItem,PredicatesOfItem")]
+ #[rustc_dirty(cfg="cfail2", except="type_of,predicates_of")]
#[rustc_clean(cfg="cfail3")]
pub fn method_selfness(&self) { }
}
@@ -334,7 +334,7 @@
// appear dirty, that might be the cause. -nmatsakis
#[rustc_clean(
cfg="cfail2",
- except="Hir,HirBody,GenericsOfItem,PredicatesOfItem,TypeOfItem",
+ except="Hir,HirBody,generics_of,predicates_of,type_of",
)]
#[rustc_clean(cfg="cfail3")]
pub fn add_type_parameter_to_method<T>(&self) { }
@@ -354,7 +354,7 @@
impl Foo {
#[rustc_clean(
cfg="cfail2",
- except="Hir,HirBody,GenericsOfItem,PredicatesOfItem,TypeOfItem,TypeckTables"
+ except="Hir,HirBody,generics_of,predicates_of,type_of,TypeckTables"
)]
#[rustc_clean(cfg="cfail3")]
pub fn add_lifetime_bound_to_lifetime_param_of_method<'a, 'b: 'a>(&self) { }
@@ -381,8 +381,8 @@
// generics before the body, then the `HirId` for things in the
// body will be affected. So if you start to see `TypeckTables`
// appear dirty, that might be the cause. -nmatsakis
- #[rustc_clean(cfg="cfail2", except="Hir,HirBody,GenericsOfItem,PredicatesOfItem,\
- TypeOfItem")]
+ #[rustc_clean(cfg="cfail2", except="Hir,HirBody,generics_of,predicates_of,\
+ type_of")]
#[rustc_clean(cfg="cfail3")]
pub fn add_lifetime_bound_to_type_param_of_method<'a, T: 'a>(&self) { }
}
@@ -408,7 +408,7 @@
// generics before the body, then the `HirId` for things in the
// body will be affected. So if you start to see `TypeckTables`
// appear dirty, that might be the cause. -nmatsakis
- #[rustc_clean(cfg="cfail2", except="Hir,HirBody,PredicatesOfItem")]
+ #[rustc_clean(cfg="cfail2", except="Hir,HirBody,predicates_of")]
#[rustc_clean(cfg="cfail3")]
pub fn add_trait_bound_to_type_param_of_method<T: Clone>(&self) { }
}
@@ -442,12 +442,12 @@
}
#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="Hir,HirBody,GenericsOfItem")]
+#[rustc_clean(cfg="cfail2", except="Hir,HirBody,generics_of")]
#[rustc_clean(cfg="cfail3")]
impl<T> Bar<T> {
#[rustc_clean(
cfg="cfail2",
- except="GenericsOfItem,FnSignature,TypeckTables,TypeOfItem,MirOptimized,MirBuilt"
+ except="generics_of,FnSignature,TypeckTables,type_of,MirOptimized,MirBuilt"
)]
#[rustc_clean(cfg="cfail3")]
pub fn add_type_parameter_to_impl(&self) { }
diff --git a/src/test/incremental/hashes/statics.rs b/src/test/incremental/hashes/statics.rs
index c3db436..3bee2ac 100644
--- a/src/test/incremental/hashes/statics.rs
+++ b/src/test/incremental/hashes/statics.rs
@@ -74,7 +74,7 @@
static STATIC_CHANGE_TYPE_1: i16 = 0;
#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="Hir,HirBody,TypeOfItem")]
+#[rustc_clean(cfg="cfail2", except="Hir,HirBody,type_of")]
#[rustc_clean(cfg="cfail3")]
static STATIC_CHANGE_TYPE_1: u64 = 0;
@@ -84,7 +84,7 @@
static STATIC_CHANGE_TYPE_2: Option<i8> = None;
#[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="Hir,HirBody,TypeOfItem")]
+#[rustc_clean(cfg="cfail2", except="Hir,HirBody,type_of")]
#[rustc_clean(cfg="cfail3")]
static STATIC_CHANGE_TYPE_2: Option<u16> = None;
@@ -144,11 +144,11 @@
#[cfg(not(cfail1))]
use super::ReferencedType2 as Type;
- #[rustc_clean(cfg="cfail2", except="Hir,HirBody,TypeOfItem")]
+ #[rustc_clean(cfg="cfail2", except="Hir,HirBody,type_of")]
#[rustc_clean(cfg="cfail3")]
static STATIC_CHANGE_TYPE_INDIRECTLY_1: Type = Type;
- #[rustc_clean(cfg="cfail2", except="Hir,HirBody,TypeOfItem")]
+ #[rustc_clean(cfg="cfail2", except="Hir,HirBody,type_of")]
#[rustc_clean(cfg="cfail3")]
static STATIC_CHANGE_TYPE_INDIRECTLY_2: Option<Type> = None;
}
diff --git a/src/test/incremental/hashes/struct_defs.rs b/src/test/incremental/hashes/struct_defs.rs
index 9fca1ce..8d32e33 100644
--- a/src/test/incremental/hashes/struct_defs.rs
+++ b/src/test/incremental/hashes/struct_defs.rs
@@ -26,14 +26,14 @@
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
-#[rustc_dirty(label="TypeOfItem", cfg="cfail2")]
-#[rustc_clean(label="GenericsOfItem", cfg="cfail2")]
-#[rustc_clean(label="PredicatesOfItem", cfg="cfail2")]
+#[rustc_dirty(label="type_of", cfg="cfail2")]
+#[rustc_clean(label="generics_of", cfg="cfail2")]
+#[rustc_clean(label="predicates_of", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
-#[rustc_clean(label="TypeOfItem", cfg="cfail3")]
-#[rustc_clean(label="GenericsOfItem", cfg="cfail3")]
-#[rustc_clean(label="PredicatesOfItem", cfg="cfail3")]
+#[rustc_clean(label="type_of", cfg="cfail3")]
+#[rustc_clean(label="generics_of", cfg="cfail3")]
+#[rustc_clean(label="predicates_of", cfg="cfail3")]
#[repr(packed)]
pub struct LayoutPacked;
@@ -43,14 +43,14 @@
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
-#[rustc_dirty(label="TypeOfItem", cfg="cfail2")]
-#[rustc_clean(label="GenericsOfItem", cfg="cfail2")]
-#[rustc_clean(label="PredicatesOfItem", cfg="cfail2")]
+#[rustc_dirty(label="type_of", cfg="cfail2")]
+#[rustc_clean(label="generics_of", cfg="cfail2")]
+#[rustc_clean(label="predicates_of", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
-#[rustc_clean(label="TypeOfItem", cfg="cfail3")]
-#[rustc_clean(label="GenericsOfItem", cfg="cfail3")]
-#[rustc_clean(label="PredicatesOfItem", cfg="cfail3")]
+#[rustc_clean(label="type_of", cfg="cfail3")]
+#[rustc_clean(label="generics_of", cfg="cfail3")]
+#[rustc_clean(label="predicates_of", cfg="cfail3")]
#[repr(C)]
struct LayoutC;
@@ -63,14 +63,14 @@
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
-#[rustc_clean(label="TypeOfItem", cfg="cfail2")]
-#[rustc_clean(label="GenericsOfItem", cfg="cfail2")]
-#[rustc_clean(label="PredicatesOfItem", cfg="cfail2")]
+#[rustc_clean(label="type_of", cfg="cfail2")]
+#[rustc_clean(label="generics_of", cfg="cfail2")]
+#[rustc_clean(label="predicates_of", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
-#[rustc_clean(label="TypeOfItem", cfg="cfail3")]
-#[rustc_clean(label="GenericsOfItem", cfg="cfail3")]
-#[rustc_clean(label="PredicatesOfItem", cfg="cfail3")]
+#[rustc_clean(label="type_of", cfg="cfail3")]
+#[rustc_clean(label="generics_of", cfg="cfail3")]
+#[rustc_clean(label="predicates_of", cfg="cfail3")]
// Note that changing the type of a field does not change the type of the struct or enum, but
// adding/removing fields or changing a fields name or visibility does.
struct TupleStructFieldType(
@@ -86,14 +86,14 @@
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
-#[rustc_dirty(label="TypeOfItem", cfg="cfail2")]
-#[rustc_clean(label="GenericsOfItem", cfg="cfail2")]
-#[rustc_clean(label="PredicatesOfItem", cfg="cfail2")]
+#[rustc_dirty(label="type_of", cfg="cfail2")]
+#[rustc_clean(label="generics_of", cfg="cfail2")]
+#[rustc_clean(label="predicates_of", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
-#[rustc_clean(label="TypeOfItem", cfg="cfail3")]
-#[rustc_clean(label="GenericsOfItem", cfg="cfail3")]
-#[rustc_clean(label="PredicatesOfItem", cfg="cfail3")]
+#[rustc_clean(label="type_of", cfg="cfail3")]
+#[rustc_clean(label="generics_of", cfg="cfail3")]
+#[rustc_clean(label="predicates_of", cfg="cfail3")]
struct TupleStructAddField(
i32,
u32
@@ -108,14 +108,14 @@
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
-#[rustc_dirty(label="TypeOfItem", cfg="cfail2")]
-#[rustc_clean(label="GenericsOfItem", cfg="cfail2")]
-#[rustc_clean(label="PredicatesOfItem", cfg="cfail2")]
+#[rustc_dirty(label="type_of", cfg="cfail2")]
+#[rustc_clean(label="generics_of", cfg="cfail2")]
+#[rustc_clean(label="predicates_of", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
-#[rustc_clean(label="TypeOfItem", cfg="cfail3")]
-#[rustc_clean(label="GenericsOfItem", cfg="cfail3")]
-#[rustc_clean(label="PredicatesOfItem", cfg="cfail3")]
+#[rustc_clean(label="type_of", cfg="cfail3")]
+#[rustc_clean(label="generics_of", cfg="cfail3")]
+#[rustc_clean(label="predicates_of", cfg="cfail3")]
struct TupleStructFieldVisibility(pub char);
@@ -127,14 +127,14 @@
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
-#[rustc_clean(label="TypeOfItem", cfg="cfail2")]
-#[rustc_clean(label="GenericsOfItem", cfg="cfail2")]
-#[rustc_clean(label="PredicatesOfItem", cfg="cfail2")]
+#[rustc_clean(label="type_of", cfg="cfail2")]
+#[rustc_clean(label="generics_of", cfg="cfail2")]
+#[rustc_clean(label="predicates_of", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
-#[rustc_clean(label="TypeOfItem", cfg="cfail3")]
-#[rustc_clean(label="GenericsOfItem", cfg="cfail3")]
-#[rustc_clean(label="PredicatesOfItem", cfg="cfail3")]
+#[rustc_clean(label="type_of", cfg="cfail3")]
+#[rustc_clean(label="generics_of", cfg="cfail3")]
+#[rustc_clean(label="predicates_of", cfg="cfail3")]
// Note that changing the type of a field does not change the type of the struct or enum, but
// adding/removing fields or changing a fields name or visibility does.
struct RecordStructFieldType {
@@ -150,14 +150,14 @@
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
-#[rustc_dirty(label="TypeOfItem", cfg="cfail2")]
-#[rustc_clean(label="GenericsOfItem", cfg="cfail2")]
-#[rustc_clean(label="PredicatesOfItem", cfg="cfail2")]
+#[rustc_dirty(label="type_of", cfg="cfail2")]
+#[rustc_clean(label="generics_of", cfg="cfail2")]
+#[rustc_clean(label="predicates_of", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
-#[rustc_clean(label="TypeOfItem", cfg="cfail3")]
-#[rustc_clean(label="GenericsOfItem", cfg="cfail3")]
-#[rustc_clean(label="PredicatesOfItem", cfg="cfail3")]
+#[rustc_clean(label="type_of", cfg="cfail3")]
+#[rustc_clean(label="generics_of", cfg="cfail3")]
+#[rustc_clean(label="predicates_of", cfg="cfail3")]
struct RecordStructFieldName { y: f32 }
@@ -169,14 +169,14 @@
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
-#[rustc_dirty(label="TypeOfItem", cfg="cfail2")]
-#[rustc_clean(label="GenericsOfItem", cfg="cfail2")]
-#[rustc_clean(label="PredicatesOfItem", cfg="cfail2")]
+#[rustc_dirty(label="type_of", cfg="cfail2")]
+#[rustc_clean(label="generics_of", cfg="cfail2")]
+#[rustc_clean(label="predicates_of", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
-#[rustc_clean(label="TypeOfItem", cfg="cfail3")]
-#[rustc_clean(label="GenericsOfItem", cfg="cfail3")]
-#[rustc_clean(label="PredicatesOfItem", cfg="cfail3")]
+#[rustc_clean(label="type_of", cfg="cfail3")]
+#[rustc_clean(label="generics_of", cfg="cfail3")]
+#[rustc_clean(label="predicates_of", cfg="cfail3")]
struct RecordStructAddField {
x: f32,
y: () }
@@ -190,14 +190,14 @@
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
-#[rustc_dirty(label="TypeOfItem", cfg="cfail2")]
-#[rustc_clean(label="GenericsOfItem", cfg="cfail2")]
-#[rustc_clean(label="PredicatesOfItem", cfg="cfail2")]
+#[rustc_dirty(label="type_of", cfg="cfail2")]
+#[rustc_clean(label="generics_of", cfg="cfail2")]
+#[rustc_clean(label="predicates_of", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
-#[rustc_clean(label="TypeOfItem", cfg="cfail3")]
-#[rustc_clean(label="GenericsOfItem", cfg="cfail3")]
-#[rustc_clean(label="PredicatesOfItem", cfg="cfail3")]
+#[rustc_clean(label="type_of", cfg="cfail3")]
+#[rustc_clean(label="generics_of", cfg="cfail3")]
+#[rustc_clean(label="predicates_of", cfg="cfail3")]
struct RecordStructFieldVisibility {
pub x: f32
}
@@ -211,14 +211,14 @@
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
-#[rustc_dirty(label="TypeOfItem", cfg="cfail2")]
-#[rustc_dirty(label="GenericsOfItem", cfg="cfail2")]
-#[rustc_clean(label="PredicatesOfItem", cfg="cfail2")]
+#[rustc_dirty(label="type_of", cfg="cfail2")]
+#[rustc_dirty(label="generics_of", cfg="cfail2")]
+#[rustc_clean(label="predicates_of", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
-#[rustc_clean(label="TypeOfItem", cfg="cfail3")]
-#[rustc_clean(label="GenericsOfItem", cfg="cfail3")]
-#[rustc_clean(label="PredicatesOfItem", cfg="cfail3")]
+#[rustc_clean(label="type_of", cfg="cfail3")]
+#[rustc_clean(label="generics_of", cfg="cfail3")]
+#[rustc_clean(label="predicates_of", cfg="cfail3")]
struct AddLifetimeParameter<'a, 'b>(&'a f32, &'b f64);
@@ -230,14 +230,14 @@
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
-#[rustc_clean(label="TypeOfItem", cfg="cfail2")]
-#[rustc_clean(label="GenericsOfItem", cfg="cfail2")]
-#[rustc_dirty(label="PredicatesOfItem", cfg="cfail2")]
+#[rustc_clean(label="type_of", cfg="cfail2")]
+#[rustc_clean(label="generics_of", cfg="cfail2")]
+#[rustc_dirty(label="predicates_of", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
-#[rustc_clean(label="TypeOfItem", cfg="cfail3")]
-#[rustc_clean(label="GenericsOfItem", cfg="cfail3")]
-#[rustc_clean(label="PredicatesOfItem", cfg="cfail3")]
+#[rustc_clean(label="type_of", cfg="cfail3")]
+#[rustc_clean(label="generics_of", cfg="cfail3")]
+#[rustc_clean(label="predicates_of", cfg="cfail3")]
struct AddLifetimeParameterBound<'a, 'b: 'a>(
&'a f32,
&'b f64
@@ -249,14 +249,14 @@
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
-#[rustc_clean(label="TypeOfItem", cfg="cfail2")]
-#[rustc_clean(label="GenericsOfItem", cfg="cfail2")]
-#[rustc_dirty(label="PredicatesOfItem", cfg="cfail2")]
+#[rustc_clean(label="type_of", cfg="cfail2")]
+#[rustc_clean(label="generics_of", cfg="cfail2")]
+#[rustc_dirty(label="predicates_of", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
-#[rustc_clean(label="TypeOfItem", cfg="cfail3")]
-#[rustc_clean(label="GenericsOfItem", cfg="cfail3")]
-#[rustc_clean(label="PredicatesOfItem", cfg="cfail3")]
+#[rustc_clean(label="type_of", cfg="cfail3")]
+#[rustc_clean(label="generics_of", cfg="cfail3")]
+#[rustc_clean(label="predicates_of", cfg="cfail3")]
struct AddLifetimeParameterBoundWhereClause<'a, 'b>(
&'a f32,
&'b f64)
@@ -271,14 +271,14 @@
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
-#[rustc_dirty(label="TypeOfItem", cfg="cfail2")]
-#[rustc_dirty(label="GenericsOfItem", cfg="cfail2")]
-#[rustc_dirty(label="PredicatesOfItem", cfg="cfail2")]
+#[rustc_dirty(label="type_of", cfg="cfail2")]
+#[rustc_dirty(label="generics_of", cfg="cfail2")]
+#[rustc_dirty(label="predicates_of", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
-#[rustc_clean(label="TypeOfItem", cfg="cfail3")]
-#[rustc_clean(label="GenericsOfItem", cfg="cfail3")]
-#[rustc_clean(label="PredicatesOfItem", cfg="cfail3")]
+#[rustc_clean(label="type_of", cfg="cfail3")]
+#[rustc_clean(label="generics_of", cfg="cfail3")]
+#[rustc_clean(label="predicates_of", cfg="cfail3")]
struct AddTypeParameter<T1, T2>(
// The field contains the parent's Generics, so it's dirty even though its
// type hasn't changed.
@@ -295,14 +295,14 @@
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
-#[rustc_clean(label="TypeOfItem", cfg="cfail2")]
-#[rustc_clean(label="GenericsOfItem", cfg="cfail2")]
-#[rustc_dirty(label="PredicatesOfItem", cfg="cfail2")]
+#[rustc_clean(label="type_of", cfg="cfail2")]
+#[rustc_clean(label="generics_of", cfg="cfail2")]
+#[rustc_dirty(label="predicates_of", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
-#[rustc_clean(label="TypeOfItem", cfg="cfail3")]
-#[rustc_clean(label="GenericsOfItem", cfg="cfail3")]
-#[rustc_clean(label="PredicatesOfItem", cfg="cfail3")]
+#[rustc_clean(label="type_of", cfg="cfail3")]
+#[rustc_clean(label="generics_of", cfg="cfail3")]
+#[rustc_clean(label="predicates_of", cfg="cfail3")]
struct AddTypeParameterBound<T: Send>(
T
);
@@ -314,14 +314,14 @@
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
-#[rustc_clean(label="TypeOfItem", cfg="cfail2")]
-#[rustc_clean(label="GenericsOfItem", cfg="cfail2")]
-#[rustc_dirty(label="PredicatesOfItem", cfg="cfail2")]
+#[rustc_clean(label="type_of", cfg="cfail2")]
+#[rustc_clean(label="generics_of", cfg="cfail2")]
+#[rustc_dirty(label="predicates_of", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
-#[rustc_clean(label="TypeOfItem", cfg="cfail3")]
-#[rustc_clean(label="GenericsOfItem", cfg="cfail3")]
-#[rustc_clean(label="PredicatesOfItem", cfg="cfail3")]
+#[rustc_clean(label="type_of", cfg="cfail3")]
+#[rustc_clean(label="generics_of", cfg="cfail3")]
+#[rustc_clean(label="predicates_of", cfg="cfail3")]
struct AddTypeParameterBoundWhereClause<T>(
T
) where T: Sync;
@@ -334,14 +334,14 @@
// Note: there is no #[cfg(...)], so this is ALWAYS compiled
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="HirBody", cfg="cfail2")]
-#[rustc_clean(label="TypeOfItem", cfg="cfail2")]
-#[rustc_clean(label="GenericsOfItem", cfg="cfail2")]
-#[rustc_clean(label="PredicatesOfItem", cfg="cfail2")]
+#[rustc_clean(label="type_of", cfg="cfail2")]
+#[rustc_clean(label="generics_of", cfg="cfail2")]
+#[rustc_clean(label="predicates_of", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
-#[rustc_clean(label="TypeOfItem", cfg="cfail3")]
-#[rustc_clean(label="GenericsOfItem", cfg="cfail3")]
-#[rustc_clean(label="PredicatesOfItem", cfg="cfail3")]
+#[rustc_clean(label="type_of", cfg="cfail3")]
+#[rustc_clean(label="generics_of", cfg="cfail3")]
+#[rustc_clean(label="predicates_of", cfg="cfail3")]
pub struct EmptyStruct;
@@ -353,14 +353,14 @@
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
-#[rustc_clean(label="TypeOfItem", cfg="cfail2")]
-#[rustc_clean(label="GenericsOfItem", cfg="cfail2")]
-#[rustc_clean(label="PredicatesOfItem", cfg="cfail2")]
+#[rustc_clean(label="type_of", cfg="cfail2")]
+#[rustc_clean(label="generics_of", cfg="cfail2")]
+#[rustc_clean(label="predicates_of", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
-#[rustc_clean(label="TypeOfItem", cfg="cfail3")]
-#[rustc_clean(label="GenericsOfItem", cfg="cfail3")]
-#[rustc_clean(label="PredicatesOfItem", cfg="cfail3")]
+#[rustc_clean(label="type_of", cfg="cfail3")]
+#[rustc_clean(label="generics_of", cfg="cfail3")]
+#[rustc_clean(label="predicates_of", cfg="cfail3")]
pub struct Visibility;
struct ReferencedType1;
@@ -375,14 +375,14 @@
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
- #[rustc_clean(label="TypeOfItem", cfg="cfail2")]
- #[rustc_clean(label="GenericsOfItem", cfg="cfail2")]
- #[rustc_clean(label="PredicatesOfItem", cfg="cfail2")]
+ #[rustc_clean(label="type_of", cfg="cfail2")]
+ #[rustc_clean(label="generics_of", cfg="cfail2")]
+ #[rustc_clean(label="predicates_of", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
- #[rustc_clean(label="TypeOfItem", cfg="cfail3")]
- #[rustc_clean(label="GenericsOfItem", cfg="cfail3")]
- #[rustc_clean(label="PredicatesOfItem", cfg="cfail3")]
+ #[rustc_clean(label="type_of", cfg="cfail3")]
+ #[rustc_clean(label="generics_of", cfg="cfail3")]
+ #[rustc_clean(label="predicates_of", cfg="cfail3")]
struct TupleStruct(
FieldType
);
@@ -398,14 +398,14 @@
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
- #[rustc_clean(label="TypeOfItem", cfg="cfail2")]
- #[rustc_clean(label="GenericsOfItem", cfg="cfail2")]
- #[rustc_clean(label="PredicatesOfItem", cfg="cfail2")]
+ #[rustc_clean(label="type_of", cfg="cfail2")]
+ #[rustc_clean(label="generics_of", cfg="cfail2")]
+ #[rustc_clean(label="predicates_of", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
- #[rustc_clean(label="TypeOfItem", cfg="cfail3")]
- #[rustc_clean(label="GenericsOfItem", cfg="cfail3")]
- #[rustc_clean(label="PredicatesOfItem", cfg="cfail3")]
+ #[rustc_clean(label="type_of", cfg="cfail3")]
+ #[rustc_clean(label="generics_of", cfg="cfail3")]
+ #[rustc_clean(label="predicates_of", cfg="cfail3")]
struct RecordStruct {
_x: FieldType
}
@@ -426,14 +426,14 @@
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
- #[rustc_clean(label="TypeOfItem", cfg="cfail2")]
- #[rustc_clean(label="GenericsOfItem", cfg="cfail2")]
- #[rustc_dirty(label="PredicatesOfItem", cfg="cfail2")]
+ #[rustc_clean(label="type_of", cfg="cfail2")]
+ #[rustc_clean(label="generics_of", cfg="cfail2")]
+ #[rustc_dirty(label="predicates_of", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
- #[rustc_clean(label="TypeOfItem", cfg="cfail3")]
- #[rustc_clean(label="GenericsOfItem", cfg="cfail3")]
- #[rustc_clean(label="PredicatesOfItem", cfg="cfail3")]
+ #[rustc_clean(label="type_of", cfg="cfail3")]
+ #[rustc_clean(label="generics_of", cfg="cfail3")]
+ #[rustc_clean(label="predicates_of", cfg="cfail3")]
struct Struct<T: Trait>(T);
}
@@ -446,13 +446,13 @@
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
- #[rustc_clean(label="TypeOfItem", cfg="cfail2")]
- #[rustc_clean(label="GenericsOfItem", cfg="cfail2")]
- #[rustc_dirty(label="PredicatesOfItem", cfg="cfail2")]
+ #[rustc_clean(label="type_of", cfg="cfail2")]
+ #[rustc_clean(label="generics_of", cfg="cfail2")]
+ #[rustc_dirty(label="predicates_of", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
- #[rustc_clean(label="TypeOfItem", cfg="cfail3")]
- #[rustc_clean(label="GenericsOfItem", cfg="cfail3")]
- #[rustc_clean(label="PredicatesOfItem", cfg="cfail3")]
+ #[rustc_clean(label="type_of", cfg="cfail3")]
+ #[rustc_clean(label="generics_of", cfg="cfail3")]
+ #[rustc_clean(label="predicates_of", cfg="cfail3")]
struct Struct<T>(T) where T : Trait;
}
diff --git a/src/test/mir-opt/basic_assignment.rs b/src/test/mir-opt/basic_assignment.rs
index 3ce43cc..c771013 100644
--- a/src/test/mir-opt/basic_assignment.rs
+++ b/src/test/mir-opt/basic_assignment.rs
@@ -48,7 +48,7 @@
// drop(_6) -> [return: bb6, unwind: bb4];
// }
// ...
-// bb5: {
+// bb5 (cleanup): {
// drop(_6) -> bb4;
// }
// END rustc.main.SimplifyCfg-initial.after.mir
diff --git a/src/test/mir-opt/box_expr.rs b/src/test/mir-opt/box_expr.rs
index ad5cf42..14d302f 100644
--- a/src/test/mir-opt/box_expr.rs
+++ b/src/test/mir-opt/box_expr.rs
@@ -38,7 +38,7 @@
// (*_2) = const S::new() -> [return: bb2, unwind: bb3];
// }
//
-// bb1: {
+// bb1 (cleanup): {
// resume;
// }
//
@@ -47,7 +47,7 @@
// drop(_2) -> bb4;
// }
//
-// bb3: {
+// bb3 (cleanup): {
// drop(_2) -> bb1;
// }
//
@@ -62,11 +62,11 @@
// drop(_4) -> [return: bb8, unwind: bb6];
// }
//
-// bb6: {
+// bb6 (cleanup): {
// drop(_1) -> bb1;
// }
//
-// bb7: {
+// bb7 (cleanup): {
// drop(_4) -> bb6;
// }
//
diff --git a/src/test/mir-opt/generator-drop-cleanup.rs b/src/test/mir-opt/generator-drop-cleanup.rs
new file mode 100644
index 0000000..48398691
--- /dev/null
+++ b/src/test/mir-opt/generator-drop-cleanup.rs
@@ -0,0 +1,43 @@
+#![feature(generators, generator_trait)]
+
+// Regression test for #58892, generator drop shims should not have blocks
+// spuriously marked as cleanup
+
+fn main() {
+ let gen = || {
+ yield;
+ };
+}
+
+// END RUST SOURCE
+
+// START rustc.main-{{closure}}.generator_drop.0.mir
+// bb0: {
+// switchInt(((*_1).0: u32)) -> [0u32: bb4, 3u32: bb7, otherwise: bb8];
+// }
+// bb1: {
+// goto -> bb5;
+// }
+// bb2: {
+// return;
+// }
+// bb3: {
+// return;
+// }
+// bb4: {
+// goto -> bb6;
+// }
+// bb5: {
+// goto -> bb2;
+// }
+// bb6: {
+// goto -> bb3;
+// }
+// bb7: {
+// StorageLive(_3);
+// goto -> bb1;
+// }
+// bb8: {
+// return;
+// }
+// END rustc.main-{{closure}}.generator_drop.0.mir
diff --git a/src/test/mir-opt/issue-38669.rs b/src/test/mir-opt/issue-38669.rs
index 618ee2f..047e623 100644
--- a/src/test/mir-opt/issue-38669.rs
+++ b/src/test/mir-opt/issue-38669.rs
@@ -18,7 +18,7 @@
// FakeRead(ForLet, _1);
// goto -> bb2;
// }
-// bb1: {
+// bb1 (cleanup): {
// resume;
// }
// bb2: {
diff --git a/src/test/mir-opt/issue-49232.rs b/src/test/mir-opt/issue-49232.rs
index 0f0401a..5f4f4ab 100644
--- a/src/test/mir-opt/issue-49232.rs
+++ b/src/test/mir-opt/issue-49232.rs
@@ -43,7 +43,7 @@
// FakeRead(ForMatchedPlace, _3);
// switchInt(_3) -> [false: bb9, otherwise: bb8];
// }
-// bb4: {
+// bb4 (cleanup): {
// resume;
// }
// bb5: {
diff --git a/src/test/mir-opt/loop_test.rs b/src/test/mir-opt/loop_test.rs
index e44743a..34891ee 100644
--- a/src/test/mir-opt/loop_test.rs
+++ b/src/test/mir-opt/loop_test.rs
@@ -18,7 +18,7 @@
// END RUST SOURCE
// START rustc.main.SimplifyCfg-qualify-consts.after.mir
// ...
-// bb1: { // The cleanup block
+// bb1 (cleanup): {
// resume;
// }
// ...
diff --git a/src/test/mir-opt/match_false_edges.rs b/src/test/mir-opt/match_false_edges.rs
index 9eeef85..0cbf048 100644
--- a/src/test/mir-opt/match_false_edges.rs
+++ b/src/test/mir-opt/match_false_edges.rs
@@ -47,7 +47,7 @@
// _3 = discriminant(_2);
// switchInt(move _3) -> [0isize: bb4, 1isize: bb2, otherwise: bb7];
// }
-// bb1: {
+// bb1 (cleanup): {
// resume;
// }
// bb2: {
@@ -116,7 +116,7 @@
// _3 = discriminant(_2);
// switchInt(move _3) -> [0isize: bb3, 1isize: bb2, otherwise: bb7];
// }
-// bb1: {
+// bb1 (cleanup): {
// resume;
// }
// bb2: {
@@ -185,7 +185,7 @@
// _3 = discriminant(_2);
// switchInt(move _3) -> [1isize: bb2, otherwise: bb3];
// }
-// bb1: {
+// bb1 (cleanup): {
// resume;
// }
// bb2: {
diff --git a/src/test/mir-opt/packed-struct-drop-aligned.rs b/src/test/mir-opt/packed-struct-drop-aligned.rs
index 01402f2..167a6eb 100644
--- a/src/test/mir-opt/packed-struct-drop-aligned.rs
+++ b/src/test/mir-opt/packed-struct-drop-aligned.rs
@@ -38,14 +38,14 @@
// _6 = move (_1.0: Aligned);
// drop(_6) -> [return: bb4, unwind: bb3];
// }
-// bb1: {
+// bb1 (cleanup): {
// resume;
// }
// bb2: {
// StorageDead(_1);
// return;
// }
-// bb3: {
+// bb3 (cleanup): {
// (_1.0: Aligned) = move _4;
// drop(_1) -> bb1;
// }
diff --git a/src/test/mir-opt/remove_fake_borrows.rs b/src/test/mir-opt/remove_fake_borrows.rs
index 48d1c99..1443484 100644
--- a/src/test/mir-opt/remove_fake_borrows.rs
+++ b/src/test/mir-opt/remove_fake_borrows.rs
@@ -63,7 +63,7 @@
// StorageDead(_8);
// return;
// }
-// bb10: {
+// bb10 (cleanup): {
// resume;
// }
// END rustc.match_guard.CleanupNonCodegenStatements.before.mir
@@ -114,7 +114,7 @@
// StorageDead(_8);
// return;
// }
-// bb10: {
+// bb10 (cleanup): {
// resume;
// }
// END rustc.match_guard.CleanupNonCodegenStatements.after.mir
diff --git a/src/test/mir-opt/simplify_match.rs b/src/test/mir-opt/simplify_match.rs
new file mode 100644
index 0000000..0192aa0
--- /dev/null
+++ b/src/test/mir-opt/simplify_match.rs
@@ -0,0 +1,22 @@
+fn main() {
+ match { let x = false; x } {
+ true => println!("hello world!"),
+ false => {},
+ }
+}
+
+// END RUST SOURCE
+// START rustc.main.SimplifyBranches-after-copy-prop.before.mir
+// bb0: {
+// ...
+// switchInt(const false) -> [false: bb3, otherwise: bb1];
+// }
+// bb1: {
+// END rustc.main.SimplifyBranches-after-copy-prop.before.mir
+// START rustc.main.SimplifyBranches-after-copy-prop.after.mir
+// bb0: {
+// ...
+// goto -> bb3;
+// }
+// bb1: {
+// END rustc.main.SimplifyBranches-after-copy-prop.after.mir
diff --git a/src/test/mir-opt/unusual-item-types.rs b/src/test/mir-opt/unusual-item-types.rs
index fe85baa..ef41373 100644
--- a/src/test/mir-opt/unusual-item-types.rs
+++ b/src/test/mir-opt/unusual-item-types.rs
@@ -7,11 +7,18 @@
const ASSOCIATED_CONSTANT: i32 = 2;
}
+// See #59021
+enum Test {
+ X(usize),
+ Y { a: usize },
+}
+
enum E {
V = 5,
}
fn main() {
+ let f = Test::X as fn(usize) -> Test;
let v = Vec::<i32>::new();
}
@@ -22,7 +29,7 @@
// _0 = const 2i32;
// return;
// }
-// bb1: {
+// bb1 (cleanup): {
// resume;
// }
// END rustc.{{impl}}-ASSOCIATED_CONSTANT.mir_map.0.mir
@@ -32,7 +39,7 @@
// _0 = const 5isize;
// return;
// }
-// bb1: {
+// bb1 (cleanup): {
// resume;
// }
// END rustc.E-V-{{constant}}.mir_map.0.mir
@@ -44,16 +51,16 @@
// bb1: {
// return;
// }
-// bb2: {
+// bb2 (cleanup): {
// resume;
// }
// bb3: {
// goto -> bb1;
// }
-// bb4: {
+// bb4 (cleanup): {
// goto -> bb2;
// }
-// bb5: {
+// bb5 (cleanup): {
// drop(((*_1).0: alloc::raw_vec::RawVec<i32>)) -> bb4;
// }
// bb6: {
@@ -64,3 +71,14 @@
// _3 = const std::ops::Drop::drop(move _2) -> [return: bb6, unwind: bb5];
// }
// END rustc.ptr-real_drop_in_place.std__vec__Vec_i32_.AddMovesForPackedDrops.before.mir
+
+// START rustc.Test-X.mir_map.0.mir
+// fn Test::X(_1: usize) -> Test {
+// let mut _0: Test;
+//
+// bb0: {
+// _0 = Test::X(move _1,);
+// return;
+// }
+// }
+// END rustc.Test-X.mir_map.0.mir
diff --git a/src/test/run-fail/generator-resume-after-panic.rs b/src/test/run-fail/generator-resume-after-panic.rs
new file mode 100644
index 0000000..910b490
--- /dev/null
+++ b/src/test/run-fail/generator-resume-after-panic.rs
@@ -0,0 +1,22 @@
+// error-pattern:generator resumed after panicking
+
+// Test that we get the correct message for resuming a panicked generator.
+
+#![feature(generators, generator_trait)]
+
+use std::{
+ ops::Generator,
+ pin::Pin,
+ panic,
+};
+
+fn main() {
+ let mut g = || {
+ panic!();
+ yield;
+ };
+ panic::catch_unwind(panic::AssertUnwindSafe(|| {
+ let x = Pin::new(&mut g).resume();
+ }));
+ Pin::new(&mut g).resume();
+}
diff --git a/src/test/run-make-fulldeps/extern-prelude/Makefile b/src/test/run-make-fulldeps/extern-prelude/Makefile
deleted file mode 100644
index 69af01c..0000000
--- a/src/test/run-make-fulldeps/extern-prelude/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
--include ../tools.mk
-
-all:
- $(RUSTC) ep-lib.rs
- $(RUSTC) ep-vec.rs
-
- $(RUSTC) basic.rs --extern ep_lib=$(TMPDIR)/libep_lib.rlib
- $(RUSTC) shadow-mod.rs --extern ep_lib=$(TMPDIR)/libep_lib.rlib
- $(RUSTC) shadow-prelude.rs --extern Vec=$(TMPDIR)/libep_vec.rlib
- $(RUSTC) relative-only.rs --extern ep_lib=$(TMPDIR)/libep_lib.rlib 2>&1 | $(CGREP) "unresolved import"
- $(RUSTC) relative-only.rs --extern ep_lib=$(TMPDIR)/libep_lib.rlib 2>&1 | $(CGREP) "failed to resolve"
diff --git a/src/test/run-make-fulldeps/extern-prelude/basic.rs b/src/test/run-make-fulldeps/extern-prelude/basic.rs
deleted file mode 100644
index dc7cc1f..0000000
--- a/src/test/run-make-fulldeps/extern-prelude/basic.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-#![feature(extern_prelude)]
-
-fn main() {
- let s = ep_lib::S; // It works
- s.external();
-}
diff --git a/src/test/run-make-fulldeps/extern-prelude/ep-vec.rs b/src/test/run-make-fulldeps/extern-prelude/ep-vec.rs
deleted file mode 100644
index 148a4a9..0000000
--- a/src/test/run-make-fulldeps/extern-prelude/ep-vec.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-#![crate_type = "rlib"]
-
-pub fn new(arg1: f32, arg2: ()) {}
diff --git a/src/test/run-make-fulldeps/extern-prelude/relative-only.rs b/src/test/run-make-fulldeps/extern-prelude/relative-only.rs
deleted file mode 100644
index 0fdf3b4..0000000
--- a/src/test/run-make-fulldeps/extern-prelude/relative-only.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-// Extern prelude names are not available by absolute paths
-
-#![feature(extern_prelude)]
-
-use ep_lib::S;
-
-fn main() {
- let s = ::ep_lib::S;
-}
diff --git a/src/test/run-make-fulldeps/extern-prelude/shadow-mod.rs b/src/test/run-make-fulldeps/extern-prelude/shadow-mod.rs
deleted file mode 100644
index 69411aa..0000000
--- a/src/test/run-make-fulldeps/extern-prelude/shadow-mod.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-// Local module shadows `ep_lib` from extern prelude
-
-mod ep_lib {
- pub struct S;
-
- impl S {
- pub fn internal(&self) {}
- }
-}
-
-fn main() {
- let s = ep_lib::S;
- s.internal(); // OK
-}
diff --git a/src/test/run-make-fulldeps/extern-prelude/shadow-prelude.rs b/src/test/run-make-fulldeps/extern-prelude/shadow-prelude.rs
deleted file mode 100644
index 6c6ce12..0000000
--- a/src/test/run-make-fulldeps/extern-prelude/shadow-prelude.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-// Extern prelude shadows standard library prelude
-
-#![feature(extern_prelude)]
-
-fn main() {
- let x = Vec::new(0f32, ()); // OK
-}
diff --git a/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs
index 641ff18..5330470 100644
--- a/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs
+++ b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs
@@ -3,9 +3,13 @@
extern crate syntax;
extern crate rustc;
extern crate rustc_codegen_utils;
+#[macro_use]
+extern crate rustc_data_structures;
+extern crate rustc_target;
use std::any::Any;
-use std::sync::mpsc;
+use std::sync::{Arc, mpsc};
+use std::path::Path;
use syntax::symbol::Symbol;
use rustc::session::Session;
use rustc::session::config::OutputFilenames;
@@ -14,21 +18,44 @@
use rustc::middle::cstore::MetadataLoader;
use rustc::dep_graph::DepGraph;
use rustc::util::common::ErrorReported;
-use rustc_codegen_utils::codegen_backend::{CodegenBackend, MetadataOnlyCodegenBackend};
+use rustc_codegen_utils::codegen_backend::CodegenBackend;
+use rustc_data_structures::sync::MetadataRef;
+use rustc_data_structures::owning_ref::OwningRef;
+use rustc_target::spec::Target;
-struct TheBackend(Box<CodegenBackend>);
+pub struct NoLlvmMetadataLoader;
+
+impl MetadataLoader for NoLlvmMetadataLoader {
+ fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result<MetadataRef, String> {
+ let buf = std::fs::read(filename).map_err(|e| format!("metadata file open err: {:?}", e))?;
+ let buf: OwningRef<Vec<u8>, [u8]> = OwningRef::new(buf);
+ Ok(rustc_erase_owner!(buf.map_owner_box()))
+ }
+
+ fn get_dylib_metadata(&self, target: &Target, filename: &Path) -> Result<MetadataRef, String> {
+ self.get_rlib_metadata(target, filename)
+ }
+}
+
+struct TheBackend;
impl CodegenBackend for TheBackend {
fn metadata_loader(&self) -> Box<MetadataLoader + Sync> {
- self.0.metadata_loader()
+ Box::new(NoLlvmMetadataLoader)
}
fn provide(&self, providers: &mut Providers) {
- self.0.provide(providers);
+ rustc_codegen_utils::symbol_names::provide(providers);
+
+ providers.target_features_whitelist = |_tcx, _cnum| {
+ Default::default() // Just a dummy
+ };
+ providers.is_reachable_non_generic = |_tcx, _defid| true;
+ providers.exported_symbols = |_tcx, _crate| Arc::new(Vec::new());
}
fn provide_extern(&self, providers: &mut Providers) {
- self.0.provide_extern(providers);
+ providers.is_reachable_non_generic = |_tcx, _defid| true;
}
fn codegen_crate<'a, 'tcx>(
@@ -69,5 +96,5 @@
/// This is the entrypoint for a hot plugged rustc_codegen_llvm
#[no_mangle]
pub fn __rustc_codegen_backend() -> Box<CodegenBackend> {
- Box::new(TheBackend(MetadataOnlyCodegenBackend::boxed()))
+ Box::new(TheBackend)
}
diff --git a/src/test/run-make-fulldeps/redundant-libs/Makefile b/src/test/run-make-fulldeps/redundant-libs/Makefile
new file mode 100644
index 0000000..9486e07
--- /dev/null
+++ b/src/test/run-make-fulldeps/redundant-libs/Makefile
@@ -0,0 +1,27 @@
+-include ../tools.mk
+
+ifdef IS_WINDOWS
+all:
+else
+
+# rustc will remove one of the two redundant references to foo below. Depending
+# on which one gets removed, we'll get a linker error on SOME platforms (like
+# Linux). On these platforms, when a library is referenced, the linker will
+# only pull in the symbols needed _at that point in time_. If a later library
+# depends on additional symbols from the library, they will not have been pulled
+# in, and you'll get undefined symbols errors.
+#
+# So in this example, we need to ensure that rustc keeps the _later_ reference
+# to foo, and not the former one.
+RUSTC_FLAGS = \
+ -l static=bar \
+ -l foo \
+ -l static=baz \
+ -l foo \
+ -Z print-link-args
+
+all: $(call DYLIB,foo) $(call STATICLIB,bar) $(call STATICLIB,baz)
+ $(RUSTC) $(RUSTC_FLAGS) main.rs
+ $(call RUN,main)
+
+endif
diff --git a/src/test/run-make-fulldeps/redundant-libs/bar.c b/src/test/run-make-fulldeps/redundant-libs/bar.c
new file mode 100644
index 0000000..e425999
--- /dev/null
+++ b/src/test/run-make-fulldeps/redundant-libs/bar.c
@@ -0,0 +1 @@
+void bar() {}
diff --git a/src/test/run-make-fulldeps/redundant-libs/baz.c b/src/test/run-make-fulldeps/redundant-libs/baz.c
new file mode 100644
index 0000000..a4e2c2b
--- /dev/null
+++ b/src/test/run-make-fulldeps/redundant-libs/baz.c
@@ -0,0 +1,7 @@
+extern void foo1();
+extern void foo2();
+
+void baz() {
+ foo1();
+ foo2();
+}
diff --git a/src/test/run-make-fulldeps/redundant-libs/foo.c b/src/test/run-make-fulldeps/redundant-libs/foo.c
new file mode 100644
index 0000000..339ee86
--- /dev/null
+++ b/src/test/run-make-fulldeps/redundant-libs/foo.c
@@ -0,0 +1,2 @@
+void foo1() {}
+void foo2() {}
diff --git a/src/test/run-make-fulldeps/redundant-libs/main.rs b/src/test/run-make-fulldeps/redundant-libs/main.rs
new file mode 100644
index 0000000..90d185f
--- /dev/null
+++ b/src/test/run-make-fulldeps/redundant-libs/main.rs
@@ -0,0 +1,11 @@
+extern "C" {
+ fn bar();
+ fn baz();
+}
+
+fn main() {
+ unsafe {
+ bar();
+ baz();
+ }
+}
diff --git a/src/test/run-make/nvptx-binary-crate/Makefile b/src/test/run-make/nvptx-binary-crate/Makefile
deleted file mode 100644
index 2c211b5..0000000
--- a/src/test/run-make/nvptx-binary-crate/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
--include ../../run-make-fulldeps/tools.mk
-
-ifeq ($(TARGET),nvptx64-nvidia-cuda)
-all:
- $(RUSTC) main.rs --crate-type="bin" --target $(TARGET) -O -C link-arg=--arch=sm_60 -o $(TMPDIR)/main.link_arg.ptx
- $(RUSTC) main.rs --crate-type="bin" --target $(TARGET) -O -C target-cpu=sm_60 -o $(TMPDIR)/main.target_cpu.ptx
-
- FileCheck main.rs --input-file $(TMPDIR)/main.link_arg.ptx
- FileCheck main.rs --input-file $(TMPDIR)/main.target_cpu.ptx
-else
-all:
-endif
diff --git a/src/test/run-make/nvptx-binary-crate/main.rs b/src/test/run-make/nvptx-binary-crate/main.rs
deleted file mode 100644
index 826bc3a..0000000
--- a/src/test/run-make/nvptx-binary-crate/main.rs
+++ /dev/null
@@ -1,28 +0,0 @@
-#![no_std]
-#![no_main]
-#![deny(warnings)]
-#![feature(abi_ptx, core_intrinsics)]
-
-// Check the overriden CUDA arch.
-// CHECK: .target sm_60
-// CHECK: .address_size 64
-
-// Verify that no extra function declarations are present.
-// CHECK-NOT: .func
-
-// CHECK-LABEL: .visible .entry top_kernel(
-#[no_mangle]
-pub unsafe extern "ptx-kernel" fn top_kernel(a: *const u32, b: *mut u32) {
- // CHECK: add.s32 %{{r[0-9]+}}, %{{r[0-9]+}}, 5;
- *b = *a + 5;
-}
-
-// Verify that no extra function definitions are there.
-// CHECK-NOT: .func
-// CHECK-NOT: .entry
-
-#[panic_handler]
-unsafe fn breakpoint_panic_handler(_: &::core::panic::PanicInfo) -> ! {
- core::intrinsics::breakpoint();
- core::hint::unreachable_unchecked();
-}
diff --git a/src/test/run-make/nvptx-dylib-crate/Makefile b/src/test/run-make/nvptx-dylib-crate/Makefile
deleted file mode 100644
index 7284e9d..0000000
--- a/src/test/run-make/nvptx-dylib-crate/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
--include ../../run-make-fulldeps/tools.mk
-
-ifeq ($(TARGET),nvptx64-nvidia-cuda)
-all:
- $(RUSTC) dep.rs --crate-type="rlib" --target $(TARGET)
- $(RUSTC) kernel.rs --crate-type="cdylib" -O --target $(TARGET)
- FileCheck kernel.rs --input-file $(TMPDIR)/kernel.ptx
-else
-all:
-endif
diff --git a/src/test/run-make/nvptx-dylib-crate/kernel.rs b/src/test/run-make/nvptx-dylib-crate/kernel.rs
deleted file mode 100644
index 63fd6b0..0000000
--- a/src/test/run-make/nvptx-dylib-crate/kernel.rs
+++ /dev/null
@@ -1,59 +0,0 @@
-#![no_std]
-#![deny(warnings)]
-#![feature(abi_ptx, core_intrinsics)]
-
-extern crate dep;
-
-// Verify the default CUDA arch.
-// CHECK: .target sm_30
-// CHECK: .address_size 64
-
-// Make sure declarations are there.
-// CHECK: .func (.param .b32 func_retval0) wrapping_external_fn
-// CHECK: .func (.param .b32 func_retval0) panicking_external_fn
-// CHECK: .func [[PANIC_HANDLER:_ZN4core9panicking5panic[a-zA-Z0-9]+]]
-
-// CHECK-LABEL: .visible .entry top_kernel(
-#[no_mangle]
-pub unsafe extern "ptx-kernel" fn top_kernel(a: *const u32, b: *mut u32) {
- // CHECK: call.uni (retval0),
- // CHECK-NEXT: wrapping_external_fn
- // CHECK: ld.param.b32 %[[LHS:r[0-9]+]], [retval0+0];
- let lhs = dep::wrapping_external_fn(*a);
-
- // CHECK: call.uni (retval0),
- // CHECK-NEXT: panicking_external_fn
- // CHECK: ld.param.b32 %[[RHS:r[0-9]+]], [retval0+0];
- let rhs = dep::panicking_external_fn(*a);
-
- // CHECK: add.s32 %[[RES:r[0-9]+]], %[[RHS]], %[[LHS]];
- // CHECK: st.global.u32 [%{{rd[0-9]+}}], %[[RES]];
- *b = lhs + rhs;
-}
-
-// Verify that external function bodies are available.
-// CHECK-LABEL: .func (.param .b32 func_retval0) wrapping_external_fn
-// CHECK: {
-// CHECK: st.param.b32 [func_retval0+0], %{{r[0-9]+}};
-// CHECK: }
-
-// Also verify panic behavior.
-// CHECK-LABEL: .func (.param .b32 func_retval0) panicking_external_fn
-// CHECK: {
-// CHECK: %{{p[0-9]+}} bra [[PANIC_LABEL:[a-zA-Z0-9_]+]];
-// CHECK: [[PANIC_LABEL]]:
-// CHECK: call.uni
-// CHECK: [[PANIC_HANDLER]]
-// CHECK: }
-
-// Verify whether out dummy panic formatter has a correct body.
-// CHECK: .func [[PANIC_FMT:_ZN4core9panicking9panic_fmt[a-zA-Z0-9]+]]()
-// CHECK: {
-// CHECK: trap;
-// CHECK: }
-
-#[panic_handler]
-unsafe fn breakpoint_panic_handler(_: &::core::panic::PanicInfo) -> ! {
- core::intrinsics::breakpoint();
- core::hint::unreachable_unchecked();
-}
diff --git a/src/test/run-make/nvptx-emit-asm/Makefile b/src/test/run-make/nvptx-emit-asm/Makefile
deleted file mode 100644
index e036018..0000000
--- a/src/test/run-make/nvptx-emit-asm/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
--include ../../run-make-fulldeps/tools.mk
-
-ifeq ($(TARGET),nvptx64-nvidia-cuda)
-all:
- $(RUSTC) kernel.rs --crate-type="rlib" --emit asm,llvm-ir -O --target $(TARGET)
- FileCheck kernel.rs --input-file $(TMPDIR)/kernel.s
-else
-all:
-endif
diff --git a/src/test/run-pass-fulldeps/undef_mask.rs b/src/test/run-pass-fulldeps/undef_mask.rs
new file mode 100644
index 0000000..cf6e6f7
--- /dev/null
+++ b/src/test/run-pass-fulldeps/undef_mask.rs
@@ -0,0 +1,26 @@
+// ignore-cross-compile
+// ignore-stage1
+
+#![feature(rustc_private)]
+
+extern crate rustc;
+
+use rustc::mir::interpret::UndefMask;
+use rustc::ty::layout::Size;
+
+fn main() {
+ let mut mask = UndefMask::new(Size::from_bytes(500), false);
+ assert!(!mask.get(Size::from_bytes(499)));
+ mask.set(Size::from_bytes(499), true);
+ assert!(mask.get(Size::from_bytes(499)));
+ mask.set_range_inbounds(Size::from_bytes(100), Size::from_bytes(256), true);
+ for i in 0..100 {
+ assert!(!mask.get(Size::from_bytes(i)));
+ }
+ for i in 100..256 {
+ assert!(mask.get(Size::from_bytes(i)));
+ }
+ for i in 256..499 {
+ assert!(!mask.get(Size::from_bytes(i)));
+ }
+}
diff --git a/src/test/run-pass/array-slice-vec/estr-slice.rs b/src/test/run-pass/array-slice-vec/estr-slice.rs
index 02b88f6..cd2c172 100644
--- a/src/test/run-pass/array-slice-vec/estr-slice.rs
+++ b/src/test/run-pass/array-slice-vec/estr-slice.rs
@@ -14,7 +14,7 @@
let z : &str = "thing";
assert_eq!(v, x);
- assert!(x != z);
+ assert_ne!(x, z);
let a = "aaaa";
let b = "bbbb";
@@ -26,7 +26,7 @@
assert!(a < b);
assert!(a <= b);
- assert!(a != b);
+ assert_ne!(a, b);
assert!(b >= a);
assert!(b > a);
@@ -34,7 +34,7 @@
assert!(a < c);
assert!(a <= c);
- assert!(a != c);
+ assert_ne!(a, c);
assert!(c >= a);
assert!(c > a);
@@ -42,7 +42,7 @@
assert!(c < cc);
assert!(c <= cc);
- assert!(c != cc);
+ assert_ne!(c, cc);
assert!(cc >= c);
assert!(cc > c);
diff --git a/src/test/run-pass/issue-55809.rs b/src/test/run-pass/issue-55809.rs
new file mode 100644
index 0000000..86b0977
--- /dev/null
+++ b/src/test/run-pass/issue-55809.rs
@@ -0,0 +1,30 @@
+// edition:2018
+// run-pass
+
+#![feature(async_await, await_macro, futures_api)]
+
+trait Foo { }
+
+impl Foo for () { }
+
+impl<'a, T> Foo for &'a mut T where T: Foo { }
+
+async fn foo_async<T>(_v: T) -> u8 where T: Foo {
+ 0
+}
+
+async fn bad<T>(v: T) -> u8 where T: Foo {
+ await!(foo_async(v))
+}
+
+async fn async_main() {
+ let mut v = ();
+
+ let _ = await!(bad(&mut v));
+ let _ = await!(foo_async(&mut v));
+ let _ = await!(bad(v));
+}
+
+fn main() {
+ let _ = async_main();
+}
diff --git a/src/test/run-pass/issues/issue-57924.rs b/src/test/run-pass/issues/issue-57924.rs
new file mode 100644
index 0000000..2325963
--- /dev/null
+++ b/src/test/run-pass/issues/issue-57924.rs
@@ -0,0 +1,9 @@
+pub struct Gcm<E>(E);
+
+impl<E> Gcm<E> {
+ pub fn crash(e: E) -> Self {
+ Self::<E>(e)
+ }
+}
+
+fn main() {}
diff --git a/src/test/run-pass/simd/simd-size-align.rs b/src/test/run-pass/simd/simd-size-align.rs
index 0a53707..5560137 100644
--- a/src/test/run-pass/simd/simd-size-align.rs
+++ b/src/test/run-pass/simd/simd-size-align.rs
@@ -37,6 +37,22 @@
check::<f32x6>();
check::<f32x7>();
check::<f32x8>();
+
+ check::<usizex2>();
+ check::<usizex3>();
+ check::<usizex4>();
+ check::<usizex5>();
+ check::<usizex6>();
+ check::<usizex7>();
+ check::<usizex8>();
+
+ check::<isizex2>();
+ check::<isizex3>();
+ check::<isizex4>();
+ check::<isizex5>();
+ check::<isizex6>();
+ check::<isizex7>();
+ check::<isizex8>();
}
#[repr(simd)] struct u8x2(u8, u8);
@@ -62,3 +78,19 @@
#[repr(simd)] struct f32x6(f32, f32, f32, f32, f32, f32);
#[repr(simd)] struct f32x7(f32, f32, f32, f32, f32, f32, f32);
#[repr(simd)] struct f32x8(f32, f32, f32, f32, f32, f32, f32, f32);
+
+#[repr(simd)] struct usizex2(usize, usize);
+#[repr(simd)] struct usizex3(usize, usize, usize);
+#[repr(simd)] struct usizex4(usize, usize, usize, usize);
+#[repr(simd)] struct usizex5(usize, usize, usize, usize, usize);
+#[repr(simd)] struct usizex6(usize, usize, usize, usize, usize, usize);
+#[repr(simd)] struct usizex7(usize, usize, usize, usize, usize, usize, usize);
+#[repr(simd)] struct usizex8(usize, usize, usize, usize, usize, usize, usize, usize);
+
+#[repr(simd)] struct isizex2(isize, isize);
+#[repr(simd)] struct isizex3(isize, isize, isize);
+#[repr(simd)] struct isizex4(isize, isize, isize, isize);
+#[repr(simd)] struct isizex5(isize, isize, isize, isize, isize);
+#[repr(simd)] struct isizex6(isize, isize, isize, isize, isize, isize);
+#[repr(simd)] struct isizex7(isize, isize, isize, isize, isize, isize, isize);
+#[repr(simd)] struct isizex8(isize, isize, isize, isize, isize, isize, isize, isize);
diff --git a/src/test/rustdoc-ui/intra-links-ambiguity.rs b/src/test/rustdoc-ui/intra-links-ambiguity.rs
new file mode 100644
index 0000000..7316fcd
--- /dev/null
+++ b/src/test/rustdoc-ui/intra-links-ambiguity.rs
@@ -0,0 +1,36 @@
+#![deny(intra_doc_link_resolution_failure)]
+#![allow(non_camel_case_types)]
+#![allow(non_upper_case_globals)]
+
+pub fn ambiguous() {}
+
+pub struct ambiguous {}
+
+#[macro_export]
+macro_rules! multi_conflict { () => {} }
+
+#[allow(non_camel_case_types)]
+pub struct multi_conflict {}
+
+pub fn multi_conflict() {}
+
+pub mod type_and_value {}
+
+pub const type_and_value: i32 = 0;
+
+pub mod foo {
+ pub enum bar {}
+
+ pub fn bar() {}
+}
+
+/// [`ambiguous`] is ambiguous. //~ERROR `ambiguous`
+///
+/// [ambiguous] is ambiguous. //~ERROR ambiguous
+///
+/// [`multi_conflict`] is a three-way conflict. //~ERROR `multi_conflict`
+///
+/// Ambiguous [type_and_value]. //~ERROR type_and_value
+///
+/// Ambiguous non-implied shortcut link [`foo::bar`]. //~ERROR `foo::bar`
+pub struct Docs {}
diff --git a/src/test/rustdoc-ui/intra-links-ambiguity.stderr b/src/test/rustdoc-ui/intra-links-ambiguity.stderr
new file mode 100644
index 0000000..5d66cc1
--- /dev/null
+++ b/src/test/rustdoc-ui/intra-links-ambiguity.stderr
@@ -0,0 +1,82 @@
+error: `ambiguous` is both a struct and a function
+ --> $DIR/intra-links-ambiguity.rs:27:6
+ |
+LL | /// [`ambiguous`] is ambiguous.
+ | ^^^^^^^^^^^ ambiguous link
+ |
+note: lint level defined here
+ --> $DIR/intra-links-ambiguity.rs:1:9
+ |
+LL | #![deny(intra_doc_link_resolution_failure)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: to link to the struct, prefix with the item type
+ |
+LL | /// [`struct@ambiguous`] is ambiguous.
+ | ^^^^^^^^^^^^^^^^^^
+help: to link to the function, add parentheses
+ |
+LL | /// [`ambiguous()`] is ambiguous.
+ | ^^^^^^^^^^^^^
+
+error: `ambiguous` is both a struct and a function
+ --> $DIR/intra-links-ambiguity.rs:29:6
+ |
+LL | /// [ambiguous] is ambiguous.
+ | ^^^^^^^^^ ambiguous link
+help: to link to the struct, prefix with the item type
+ |
+LL | /// [struct@ambiguous] is ambiguous.
+ | ^^^^^^^^^^^^^^^^
+help: to link to the function, add parentheses
+ |
+LL | /// [ambiguous()] is ambiguous.
+ | ^^^^^^^^^^^
+
+error: `multi_conflict` is a struct, a function, and a macro
+ --> $DIR/intra-links-ambiguity.rs:31:6
+ |
+LL | /// [`multi_conflict`] is a three-way conflict.
+ | ^^^^^^^^^^^^^^^^ ambiguous link
+help: to link to the struct, prefix with the item type
+ |
+LL | /// [`struct@multi_conflict`] is a three-way conflict.
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+help: to link to the function, add parentheses
+ |
+LL | /// [`multi_conflict()`] is a three-way conflict.
+ | ^^^^^^^^^^^^^^^^^^
+help: to link to the macro, add an exclamation mark
+ |
+LL | /// [`multi_conflict!`] is a three-way conflict.
+ | ^^^^^^^^^^^^^^^^^
+
+error: `type_and_value` is both a module and a constant
+ --> $DIR/intra-links-ambiguity.rs:33:16
+ |
+LL | /// Ambiguous [type_and_value].
+ | ^^^^^^^^^^^^^^ ambiguous link
+help: to link to the module, prefix with the item type
+ |
+LL | /// Ambiguous [module@type_and_value].
+ | ^^^^^^^^^^^^^^^^^^^^^
+help: to link to the constant, prefix with the item type
+ |
+LL | /// Ambiguous [const@type_and_value].
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: `foo::bar` is both an enum and a function
+ --> $DIR/intra-links-ambiguity.rs:35:42
+ |
+LL | /// Ambiguous non-implied shortcut link [`foo::bar`].
+ | ^^^^^^^^^^ ambiguous link
+help: to link to the enum, prefix with the item type
+ |
+LL | /// Ambiguous non-implied shortcut link [`enum@foo::bar`].
+ | ^^^^^^^^^^^^^^^
+help: to link to the function, add parentheses
+ |
+LL | /// Ambiguous non-implied shortcut link [`foo::bar()`].
+ | ^^^^^^^^^^^^
+
+error: aborting due to 5 previous errors
+
diff --git a/src/test/rustdoc/default_trait_method.rs b/src/test/rustdoc/default_trait_method.rs
new file mode 100644
index 0000000..dfbd8f2
--- /dev/null
+++ b/src/test/rustdoc/default_trait_method.rs
@@ -0,0 +1,15 @@
+#![feature(specialization)]
+
+pub trait Item {
+ fn foo();
+ fn bar();
+}
+
+// @has default_trait_method/trait.Item.html
+// @has - '//*[@id="method.foo"]' 'default fn foo()'
+// @has - '//*[@id="method.bar"]' 'fn bar()'
+// @!has - '//*[@id="method.bar"]' 'default fn bar()'
+impl<T: ?Sized> Item for T {
+ default fn foo() {}
+ fn bar() {}
+}
diff --git a/src/test/rustdoc/intra-links.rs b/src/test/rustdoc/intra-links.rs
index 9139fc5..c356ab3 100644
--- a/src/test/rustdoc/intra-links.rs
+++ b/src/test/rustdoc/intra-links.rs
@@ -22,6 +22,7 @@
//! * [`ThisType::this_method`](ThisType::this_method)
//! * [`ThisEnum`](ThisEnum)
//! * [`ThisEnum::ThisVariant`](ThisEnum::ThisVariant)
+//! * [`ThisEnum::ThisVariantCtor`](ThisEnum::ThisVariantCtor)
//! * [`ThisTrait`](ThisTrait)
//! * [`ThisTrait::this_associated_method`](ThisTrait::this_associated_method)
//! * [`ThisTrait::ThisAssociatedType`](ThisTrait::ThisAssociatedType)
@@ -50,7 +51,7 @@
impl ThisType {
pub fn this_method() {}
}
-pub enum ThisEnum { ThisVariant, }
+pub enum ThisEnum { ThisVariant, ThisVariantCtor(u32), }
pub trait ThisTrait {
type ThisAssociatedType;
const THIS_ASSOCIATED_CONST: u8;
diff --git a/src/test/ui/E0501.ast.nll.stderr b/src/test/ui/E0501.ast.nll.stderr
index 1d0102d..74f14beb 100644
--- a/src/test/ui/E0501.ast.nll.stderr
+++ b/src/test/ui/E0501.ast.nll.stderr
@@ -6,7 +6,7 @@
LL | inside_closure(a)
| - first borrow occurs due to use of `a` in closure
LL | };
-LL | outside_closure_1(a); //[ast]~ ERROR cannot borrow `*a` as mutable because previous closure requires unique access
+LL | outside_closure_1(a);
| ^ second borrow occurs here
...
LL | drop(bar);
@@ -20,7 +20,7 @@
LL | inside_closure(a)
| - first borrow occurs due to use of `a` in closure
...
-LL | outside_closure_2(a); //[ast]~ ERROR cannot borrow `*a` as immutable because previous closure requires unique access
+LL | outside_closure_2(a);
| ^ second borrow occurs here
...
LL | drop(bar);
diff --git a/src/test/ui/E0501.ast.stderr b/src/test/ui/E0501.ast.stderr
index e0bd7a0..e2f54c6 100644
--- a/src/test/ui/E0501.ast.stderr
+++ b/src/test/ui/E0501.ast.stderr
@@ -6,7 +6,7 @@
LL | inside_closure(a)
| - previous borrow occurs due to use of `a` in closure
LL | };
-LL | outside_closure_1(a); //[ast]~ ERROR cannot borrow `*a` as mutable because previous closure requires unique access
+LL | outside_closure_1(a);
| ^ borrow occurs here
...
LL | }
@@ -20,7 +20,7 @@
LL | inside_closure(a)
| - previous borrow occurs due to use of `a` in closure
...
-LL | outside_closure_2(a); //[ast]~ ERROR cannot borrow `*a` as immutable because previous closure requires unique access
+LL | outside_closure_2(a);
| ^ borrow occurs here
...
LL | }
diff --git a/src/test/ui/E0501.mir.stderr b/src/test/ui/E0501.mir.stderr
index 1d0102d..74f14beb 100644
--- a/src/test/ui/E0501.mir.stderr
+++ b/src/test/ui/E0501.mir.stderr
@@ -6,7 +6,7 @@
LL | inside_closure(a)
| - first borrow occurs due to use of `a` in closure
LL | };
-LL | outside_closure_1(a); //[ast]~ ERROR cannot borrow `*a` as mutable because previous closure requires unique access
+LL | outside_closure_1(a);
| ^ second borrow occurs here
...
LL | drop(bar);
@@ -20,7 +20,7 @@
LL | inside_closure(a)
| - first borrow occurs due to use of `a` in closure
...
-LL | outside_closure_2(a); //[ast]~ ERROR cannot borrow `*a` as immutable because previous closure requires unique access
+LL | outside_closure_2(a);
| ^ second borrow occurs here
...
LL | drop(bar);
diff --git a/src/test/ui/E0506.ast.nll.stderr b/src/test/ui/E0506.ast.nll.stderr
index b66c1d1..6e2d634 100644
--- a/src/test/ui/E0506.ast.nll.stderr
+++ b/src/test/ui/E0506.ast.nll.stderr
@@ -3,7 +3,7 @@
|
LL | let fancy_ref = &fancy_num;
| ---------- borrow of `fancy_num` occurs here
-LL | fancy_num = FancyNum { num: 6 }; //[ast]~ ERROR E0506
+LL | fancy_num = FancyNum { num: 6 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `fancy_num` occurs here
...
LL | println!("Num: {}, Ref: {}", fancy_num.num, fancy_ref.num);
diff --git a/src/test/ui/E0506.ast.stderr b/src/test/ui/E0506.ast.stderr
index d459dcd..3e3001f 100644
--- a/src/test/ui/E0506.ast.stderr
+++ b/src/test/ui/E0506.ast.stderr
@@ -3,7 +3,7 @@
|
LL | let fancy_ref = &fancy_num;
| --------- borrow of `fancy_num` occurs here
-LL | fancy_num = FancyNum { num: 6 }; //[ast]~ ERROR E0506
+LL | fancy_num = FancyNum { num: 6 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `fancy_num` occurs here
error: aborting due to previous error
diff --git a/src/test/ui/E0506.mir.stderr b/src/test/ui/E0506.mir.stderr
index b66c1d1..6e2d634 100644
--- a/src/test/ui/E0506.mir.stderr
+++ b/src/test/ui/E0506.mir.stderr
@@ -3,7 +3,7 @@
|
LL | let fancy_ref = &fancy_num;
| ---------- borrow of `fancy_num` occurs here
-LL | fancy_num = FancyNum { num: 6 }; //[ast]~ ERROR E0506
+LL | fancy_num = FancyNum { num: 6 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `fancy_num` occurs here
...
LL | println!("Num: {}, Ref: {}", fancy_num.num, fancy_ref.num);
diff --git a/src/test/ui/E0508-fail.ast.nll.stderr b/src/test/ui/E0508-fail.ast.nll.stderr
index 4cc1cf8..972b84e 100644
--- a/src/test/ui/E0508-fail.ast.nll.stderr
+++ b/src/test/ui/E0508-fail.ast.nll.stderr
@@ -1,7 +1,7 @@
error[E0508]: cannot move out of type `[NonCopy; 1]`, a non-copy array
--> $DIR/E0508-fail.rs:8:18
|
-LL | let _value = array[0]; //[ast]~ ERROR [E0508]
+LL | let _value = array[0];
| ^^^^^^^^
| |
| cannot move out of here
diff --git a/src/test/ui/E0508-fail.ast.stderr b/src/test/ui/E0508-fail.ast.stderr
index 57959c9..8b24983 100644
--- a/src/test/ui/E0508-fail.ast.stderr
+++ b/src/test/ui/E0508-fail.ast.stderr
@@ -1,7 +1,7 @@
error[E0508]: cannot move out of type `[NonCopy; 1]`, a non-copy array
--> $DIR/E0508-fail.rs:8:18
|
-LL | let _value = array[0]; //[ast]~ ERROR [E0508]
+LL | let _value = array[0];
| ^^^^^^^^
| |
| cannot move out of here
diff --git a/src/test/ui/E0508-fail.mir.stderr b/src/test/ui/E0508-fail.mir.stderr
index 4cc1cf8..972b84e 100644
--- a/src/test/ui/E0508-fail.mir.stderr
+++ b/src/test/ui/E0508-fail.mir.stderr
@@ -1,7 +1,7 @@
error[E0508]: cannot move out of type `[NonCopy; 1]`, a non-copy array
--> $DIR/E0508-fail.rs:8:18
|
-LL | let _value = array[0]; //[ast]~ ERROR [E0508]
+LL | let _value = array[0];
| ^^^^^^^^
| |
| cannot move out of here
diff --git a/src/test/ui/E0508.ast.stderr b/src/test/ui/E0508.ast.stderr
deleted file mode 100644
index 5878b79..0000000
--- a/src/test/ui/E0508.ast.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0508]: cannot move out of type `[NonCopy; 1]`, a non-copy array
- --> $DIR/E0508.rs:18:18
- |
-LL | let _value = array[0]; //[ast]~ ERROR [E0508]
- | ^^^^^^^^
- | |
- | cannot move out of here
- | help: consider using a reference instead: `&array[0]`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0508`.
diff --git a/src/test/ui/E0508.mir.stderr b/src/test/ui/E0508.mir.stderr
deleted file mode 100644
index 5878b79..0000000
--- a/src/test/ui/E0508.mir.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0508]: cannot move out of type `[NonCopy; 1]`, a non-copy array
- --> $DIR/E0508.rs:18:18
- |
-LL | let _value = array[0]; //[ast]~ ERROR [E0508]
- | ^^^^^^^^
- | |
- | cannot move out of here
- | help: consider using a reference instead: `&array[0]`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0508`.
diff --git a/src/test/ui/E0594.ast.nll.stderr b/src/test/ui/E0594.ast.nll.stderr
index 54681a2..cc1c968 100644
--- a/src/test/ui/E0594.ast.nll.stderr
+++ b/src/test/ui/E0594.ast.nll.stderr
@@ -1,7 +1,7 @@
error[E0594]: cannot assign to immutable static item `NUM`
--> $DIR/E0594.rs:7:5
|
-LL | NUM = 20; //[ast]~ ERROR E0594
+LL | NUM = 20;
| ^^^^^^^^ cannot assign
error: aborting due to previous error
diff --git a/src/test/ui/E0594.ast.stderr b/src/test/ui/E0594.ast.stderr
index 4eb9ba1..0c5316d 100644
--- a/src/test/ui/E0594.ast.stderr
+++ b/src/test/ui/E0594.ast.stderr
@@ -1,7 +1,7 @@
error[E0594]: cannot assign to immutable static item
--> $DIR/E0594.rs:7:5
|
-LL | NUM = 20; //[ast]~ ERROR E0594
+LL | NUM = 20;
| ^^^^^^^^
error: aborting due to previous error
diff --git a/src/test/ui/E0594.mir.stderr b/src/test/ui/E0594.mir.stderr
index 54681a2..cc1c968 100644
--- a/src/test/ui/E0594.mir.stderr
+++ b/src/test/ui/E0594.mir.stderr
@@ -1,7 +1,7 @@
error[E0594]: cannot assign to immutable static item `NUM`
--> $DIR/E0594.rs:7:5
|
-LL | NUM = 20; //[ast]~ ERROR E0594
+LL | NUM = 20;
| ^^^^^^^^ cannot assign
error: aborting due to previous error
diff --git a/src/test/ui/E0596.ast.nll.stderr b/src/test/ui/E0596.ast.nll.stderr
index e5da664..c89a915 100644
--- a/src/test/ui/E0596.ast.nll.stderr
+++ b/src/test/ui/E0596.ast.nll.stderr
@@ -3,7 +3,7 @@
|
LL | let x = 1;
| - help: consider changing this to be mutable: `mut x`
-LL | let y = &mut x; //[ast]~ ERROR [E0596]
+LL | let y = &mut x;
| ^^^^^^ cannot borrow as mutable
error: aborting due to previous error
diff --git a/src/test/ui/E0596.ast.stderr b/src/test/ui/E0596.ast.stderr
index 6e65cc8..4b66e49 100644
--- a/src/test/ui/E0596.ast.stderr
+++ b/src/test/ui/E0596.ast.stderr
@@ -3,7 +3,7 @@
|
LL | let x = 1;
| - help: make this binding mutable: `mut x`
-LL | let y = &mut x; //[ast]~ ERROR [E0596]
+LL | let y = &mut x;
| ^ cannot borrow mutably
error: aborting due to previous error
diff --git a/src/test/ui/E0596.mir.stderr b/src/test/ui/E0596.mir.stderr
index e5da664..c89a915 100644
--- a/src/test/ui/E0596.mir.stderr
+++ b/src/test/ui/E0596.mir.stderr
@@ -3,7 +3,7 @@
|
LL | let x = 1;
| - help: consider changing this to be mutable: `mut x`
-LL | let y = &mut x; //[ast]~ ERROR [E0596]
+LL | let y = &mut x;
| ^^^^^^ cannot borrow as mutable
error: aborting due to previous error
diff --git a/src/test/ui/assign-imm-local-twice.ast.nll.stderr b/src/test/ui/assign-imm-local-twice.ast.nll.stderr
index 311a83a..2995a13 100644
--- a/src/test/ui/assign-imm-local-twice.ast.nll.stderr
+++ b/src/test/ui/assign-imm-local-twice.ast.nll.stderr
@@ -4,10 +4,10 @@
LL | let v: isize;
| - help: make this binding mutable: `mut v`
...
-LL | v = 1; //[ast]~ NOTE first assignment
+LL | v = 1;
| ----- first assignment to `v`
...
-LL | v = 2; //[ast]~ ERROR cannot assign twice to immutable variable
+LL | v = 2;
| ^^^^^ cannot assign twice to immutable variable
error: aborting due to previous error
diff --git a/src/test/ui/assign-imm-local-twice.ast.stderr b/src/test/ui/assign-imm-local-twice.ast.stderr
index d57acb2..f16b8e2 100644
--- a/src/test/ui/assign-imm-local-twice.ast.stderr
+++ b/src/test/ui/assign-imm-local-twice.ast.stderr
@@ -1,10 +1,10 @@
error[E0384]: cannot assign twice to immutable variable `v`
--> $DIR/assign-imm-local-twice.rs:11:5
|
-LL | v = 1; //[ast]~ NOTE first assignment
+LL | v = 1;
| ----- first assignment to `v`
...
-LL | v = 2; //[ast]~ ERROR cannot assign twice to immutable variable
+LL | v = 2;
| ^^^^^ cannot assign twice to immutable variable
error: aborting due to previous error
diff --git a/src/test/ui/assign-imm-local-twice.mir.stderr b/src/test/ui/assign-imm-local-twice.mir.stderr
index 311a83a..2995a13 100644
--- a/src/test/ui/assign-imm-local-twice.mir.stderr
+++ b/src/test/ui/assign-imm-local-twice.mir.stderr
@@ -4,10 +4,10 @@
LL | let v: isize;
| - help: make this binding mutable: `mut v`
...
-LL | v = 1; //[ast]~ NOTE first assignment
+LL | v = 1;
| ----- first assignment to `v`
...
-LL | v = 2; //[ast]~ ERROR cannot assign twice to immutable variable
+LL | v = 2;
| ^^^^^ cannot assign twice to immutable variable
error: aborting due to previous error
diff --git a/src/test/ui/associated-types/bound-lifetime-in-binding-only.ok.stderr b/src/test/ui/associated-types/bound-lifetime-in-binding-only.ok.stderr
index 3a5ff9d..fcdb371 100644
--- a/src/test/ui/associated-types/bound-lifetime-in-binding-only.ok.stderr
+++ b/src/test/ui/associated-types/bound-lifetime-in-binding-only.ok.stderr
@@ -1,7 +1,7 @@
error: compilation successful
--> $DIR/bound-lifetime-in-binding-only.rs:71:1
|
-LL | fn main() { } //[ok]~ ERROR compilation successful
+LL | fn main() { }
| ^^^^^^^^^^^^^
error: aborting due to previous error
diff --git a/src/test/ui/associated-types/bound-lifetime-in-return-only.ok.stderr b/src/test/ui/associated-types/bound-lifetime-in-return-only.ok.stderr
index 650383b..504d68e 100644
--- a/src/test/ui/associated-types/bound-lifetime-in-return-only.ok.stderr
+++ b/src/test/ui/associated-types/bound-lifetime-in-return-only.ok.stderr
@@ -1,7 +1,7 @@
error: compilation successful
--> $DIR/bound-lifetime-in-return-only.rs:49:1
|
-LL | fn main() { } //[ok]~ ERROR compilation successful
+LL | fn main() { }
| ^^^^^^^^^^^^^
error: aborting due to previous error
diff --git a/src/test/ui/associated-types/cache/project-fn-ret-contravariant.krisskross.stderr b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.krisskross.stderr
index 0fed413..fa4c6ad 100644
--- a/src/test/ui/associated-types/cache/project-fn-ret-contravariant.krisskross.stderr
+++ b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.krisskross.stderr
@@ -6,7 +6,7 @@
| |
| this parameter and the return type are declared with different lifetimes...
...
-LL | (a, b) //[krisskross]~ ERROR lifetime mismatch [E0623]
+LL | (a, b)
| ^ ...but data from `y` is returned here
error[E0623]: lifetime mismatch
@@ -17,7 +17,7 @@
| |
| this parameter and the return type are declared with different lifetimes...
...
-LL | (a, b) //[krisskross]~ ERROR lifetime mismatch [E0623]
+LL | (a, b)
| ^ ...but data from `x` is returned here
error: aborting due to 2 previous errors
diff --git a/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.stderr b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.stderr
index ab14836..4309373 100644
--- a/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.stderr
+++ b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.stderr
@@ -1,7 +1,7 @@
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> $DIR/project-fn-ret-contravariant.rs:38:8
|
-LL | bar(foo, x) //[transmute]~ ERROR E0495
+LL | bar(foo, x)
| ^^^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 37:8...
@@ -12,13 +12,13 @@
note: ...so that reference does not outlive borrowed content
--> $DIR/project-fn-ret-contravariant.rs:38:13
|
-LL | bar(foo, x) //[transmute]~ ERROR E0495
+LL | bar(foo, x)
| ^
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that reference does not outlive borrowed content
--> $DIR/project-fn-ret-contravariant.rs:38:4
|
-LL | bar(foo, x) //[transmute]~ ERROR E0495
+LL | bar(foo, x)
| ^^^^^^^^^^^
error: aborting due to previous error
diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.stderr
index fa831ea..5009e08 100644
--- a/src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.stderr
+++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.krisskross.stderr
@@ -5,7 +5,7 @@
| -------- --------------------
| |
| this parameter and the return type are declared with different lifetimes...
-LL | let a = bar(foo, y); //[krisskross]~ ERROR E0623
+LL | let a = bar(foo, y);
| ^ ...but data from `x` is returned here
error[E0623]: lifetime mismatch
@@ -15,8 +15,8 @@
| -------- --------------------
| |
| this parameter and the return type are declared with different lifetimes...
-LL | let a = bar(foo, y); //[krisskross]~ ERROR E0623
-LL | let b = bar(foo, x); //[krisskross]~ ERROR E0623
+LL | let a = bar(foo, y);
+LL | let b = bar(foo, x);
| ^ ...but data from `y` is returned here
error: aborting due to 2 previous errors
diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.stderr
index 6b78d66..65d16440 100644
--- a/src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.stderr
+++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.oneuse.stderr
@@ -6,7 +6,7 @@
| |
| this parameter and the return type are declared with different lifetimes...
...
-LL | let b = bar(f, y); //[oneuse]~ ERROR lifetime mismatch [E0623]
+LL | let b = bar(f, y);
| ^ ...but data from `x` is returned here
error: aborting due to previous error
diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr
index dd1212e..b8b1a97 100644
--- a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr
+++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr
@@ -1,7 +1,7 @@
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> $DIR/project-fn-ret-invariant.rs:48:8
|
-LL | bar(foo, x) //[transmute]~ ERROR E0495
+LL | bar(foo, x)
| ^^^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 44:8...
diff --git a/src/test/ui/associated-types/higher-ranked-projection.good.stderr b/src/test/ui/associated-types/higher-ranked-projection.good.stderr
index 165e521..16fef05 100644
--- a/src/test/ui/associated-types/higher-ranked-projection.good.stderr
+++ b/src/test/ui/associated-types/higher-ranked-projection.good.stderr
@@ -1,9 +1,9 @@
error: compilation successful
--> $DIR/higher-ranked-projection.rs:24:1
|
-LL | / fn main() { //[good]~ ERROR compilation successful
+LL | / fn main() {
LL | | foo(());
-LL | | //[bad]~^ ERROR type mismatch
+LL | |
LL | | }
| |_^
diff --git a/src/test/ui/auxiliary/extern-prelude-vec.rs b/src/test/ui/auxiliary/extern-prelude-vec.rs
new file mode 100644
index 0000000..a643c88
--- /dev/null
+++ b/src/test/ui/auxiliary/extern-prelude-vec.rs
@@ -0,0 +1,3 @@
+#![crate_name = "Vec"]
+
+pub fn new(arg1: f32, arg2: ()) {}
diff --git a/src/test/run-make-fulldeps/extern-prelude/ep-lib.rs b/src/test/ui/auxiliary/extern-prelude.rs
similarity index 68%
rename from src/test/run-make-fulldeps/extern-prelude/ep-lib.rs
rename to src/test/ui/auxiliary/extern-prelude.rs
index f5e129e..2fdfd85 100644
--- a/src/test/run-make-fulldeps/extern-prelude/ep-lib.rs
+++ b/src/test/ui/auxiliary/extern-prelude.rs
@@ -1,5 +1,3 @@
-#![crate_type = "rlib"]
-
pub struct S;
impl S {
diff --git a/src/test/ui/borrowck/borrowck-access-permissions.ast.nll.stderr b/src/test/ui/borrowck/borrowck-access-permissions.ast.nll.stderr
index 0d771a5..12f9ad8 100644
--- a/src/test/ui/borrowck/borrowck-access-permissions.ast.nll.stderr
+++ b/src/test/ui/borrowck/borrowck-access-permissions.ast.nll.stderr
@@ -4,13 +4,13 @@
LL | let x = 1;
| - help: consider changing this to be mutable: `mut x`
...
-LL | let _y1 = &mut x; //[ast]~ ERROR [E0596]
+LL | let _y1 = &mut x;
| ^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow immutable static item `static_x` as mutable
--> $DIR/borrowck-access-permissions.rs:18:19
|
-LL | let _y1 = &mut static_x; //[ast]~ ERROR [E0596]
+LL | let _y1 = &mut static_x;
| ^^^^^^^^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow `*box_x` as mutable, as `box_x` is not declared as mutable
@@ -19,7 +19,7 @@
LL | let box_x = Box::new(1);
| ----- help: consider changing this to be mutable: `mut box_x`
...
-LL | let _y1 = &mut *box_x; //[ast]~ ERROR [E0596]
+LL | let _y1 = &mut *box_x;
| ^^^^^^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow `*ref_x` as mutable, as it is behind a `&` reference
@@ -28,7 +28,7 @@
LL | let ref_x = &x;
| -- help: consider changing this to be a mutable reference: `&mut x`
...
-LL | let _y1 = &mut *ref_x; //[ast]~ ERROR [E0596]
+LL | let _y1 = &mut *ref_x;
| ^^^^^^^^^^^ `ref_x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
error[E0596]: cannot borrow `*ptr_x` as mutable, as it is behind a `*const` pointer
@@ -37,7 +37,7 @@
LL | let ptr_x : *const _ = &x;
| -- help: consider changing this to be a mutable pointer: `&mut x`
...
-LL | let _y1 = &mut *ptr_x; //[ast]~ ERROR [E0596]
+LL | let _y1 = &mut *ptr_x;
| ^^^^^^^^^^^ `ptr_x` is a `*const` pointer, so the data it refers to cannot be borrowed as mutable
error[E0596]: cannot borrow `*foo_ref.f` as mutable, as it is behind a `&` reference
@@ -45,7 +45,7 @@
|
LL | let foo_ref = &foo;
| ---- help: consider changing this to be a mutable reference: `&mut foo`
-LL | let _y = &mut *foo_ref.f; //[ast]~ ERROR [E0389]
+LL | let _y = &mut *foo_ref.f;
| ^^^^^^^^^^^^^^^ `foo_ref` is a `&` reference, so the data it refers to cannot be borrowed as mutable
error: aborting due to 6 previous errors
diff --git a/src/test/ui/borrowck/borrowck-access-permissions.ast.stderr b/src/test/ui/borrowck/borrowck-access-permissions.ast.stderr
index 4b0e261..a1cc063 100644
--- a/src/test/ui/borrowck/borrowck-access-permissions.ast.stderr
+++ b/src/test/ui/borrowck/borrowck-access-permissions.ast.stderr
@@ -4,13 +4,13 @@
LL | let x = 1;
| - help: make this binding mutable: `mut x`
...
-LL | let _y1 = &mut x; //[ast]~ ERROR [E0596]
+LL | let _y1 = &mut x;
| ^ cannot borrow mutably
error[E0596]: cannot borrow immutable static item as mutable
--> $DIR/borrowck-access-permissions.rs:18:24
|
-LL | let _y1 = &mut static_x; //[ast]~ ERROR [E0596]
+LL | let _y1 = &mut static_x;
| ^^^^^^^^
error[E0596]: cannot borrow immutable `Box` content `*box_x` as mutable
@@ -19,25 +19,25 @@
LL | let box_x = Box::new(1);
| ----- help: make this binding mutable: `mut box_x`
...
-LL | let _y1 = &mut *box_x; //[ast]~ ERROR [E0596]
+LL | let _y1 = &mut *box_x;
| ^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow immutable borrowed content `*ref_x` as mutable
--> $DIR/borrowck-access-permissions.rs:36:24
|
-LL | let _y1 = &mut *ref_x; //[ast]~ ERROR [E0596]
+LL | let _y1 = &mut *ref_x;
| ^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow immutable dereference of raw pointer `*ptr_x` as mutable
--> $DIR/borrowck-access-permissions.rs:46:28
|
-LL | let _y1 = &mut *ptr_x; //[ast]~ ERROR [E0596]
+LL | let _y1 = &mut *ptr_x;
| ^^^^^^ cannot borrow as mutable
error[E0389]: cannot borrow data mutably in a `&` reference
--> $DIR/borrowck-access-permissions.rs:56:23
|
-LL | let _y = &mut *foo_ref.f; //[ast]~ ERROR [E0389]
+LL | let _y = &mut *foo_ref.f;
| ^^^^^^^^^^ assignment into an immutable reference
error: aborting due to 6 previous errors
diff --git a/src/test/ui/borrowck/borrowck-access-permissions.mir.stderr b/src/test/ui/borrowck/borrowck-access-permissions.mir.stderr
index 0d771a5..12f9ad8 100644
--- a/src/test/ui/borrowck/borrowck-access-permissions.mir.stderr
+++ b/src/test/ui/borrowck/borrowck-access-permissions.mir.stderr
@@ -4,13 +4,13 @@
LL | let x = 1;
| - help: consider changing this to be mutable: `mut x`
...
-LL | let _y1 = &mut x; //[ast]~ ERROR [E0596]
+LL | let _y1 = &mut x;
| ^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow immutable static item `static_x` as mutable
--> $DIR/borrowck-access-permissions.rs:18:19
|
-LL | let _y1 = &mut static_x; //[ast]~ ERROR [E0596]
+LL | let _y1 = &mut static_x;
| ^^^^^^^^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow `*box_x` as mutable, as `box_x` is not declared as mutable
@@ -19,7 +19,7 @@
LL | let box_x = Box::new(1);
| ----- help: consider changing this to be mutable: `mut box_x`
...
-LL | let _y1 = &mut *box_x; //[ast]~ ERROR [E0596]
+LL | let _y1 = &mut *box_x;
| ^^^^^^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow `*ref_x` as mutable, as it is behind a `&` reference
@@ -28,7 +28,7 @@
LL | let ref_x = &x;
| -- help: consider changing this to be a mutable reference: `&mut x`
...
-LL | let _y1 = &mut *ref_x; //[ast]~ ERROR [E0596]
+LL | let _y1 = &mut *ref_x;
| ^^^^^^^^^^^ `ref_x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
error[E0596]: cannot borrow `*ptr_x` as mutable, as it is behind a `*const` pointer
@@ -37,7 +37,7 @@
LL | let ptr_x : *const _ = &x;
| -- help: consider changing this to be a mutable pointer: `&mut x`
...
-LL | let _y1 = &mut *ptr_x; //[ast]~ ERROR [E0596]
+LL | let _y1 = &mut *ptr_x;
| ^^^^^^^^^^^ `ptr_x` is a `*const` pointer, so the data it refers to cannot be borrowed as mutable
error[E0596]: cannot borrow `*foo_ref.f` as mutable, as it is behind a `&` reference
@@ -45,7 +45,7 @@
|
LL | let foo_ref = &foo;
| ---- help: consider changing this to be a mutable reference: `&mut foo`
-LL | let _y = &mut *foo_ref.f; //[ast]~ ERROR [E0389]
+LL | let _y = &mut *foo_ref.f;
| ^^^^^^^^^^^^^^^ `foo_ref` is a `&` reference, so the data it refers to cannot be borrowed as mutable
error: aborting due to 6 previous errors
diff --git a/src/test/ui/borrowck/borrowck-asm.ast.nll.stderr b/src/test/ui/borrowck/borrowck-asm.ast.nll.stderr
index 86e4832..dd6e5eb 100644
--- a/src/test/ui/borrowck/borrowck-asm.ast.nll.stderr
+++ b/src/test/ui/borrowck/borrowck-asm.ast.nll.stderr
@@ -7,7 +7,7 @@
LL | asm!("nop" : : "r"(x));
| - value moved here
LL | }
-LL | let z = x; //[ast]~ ERROR use of moved value: `x`
+LL | let z = x;
| ^ value used here after move
error[E0503]: cannot use `x` because it was mutably borrowed
@@ -16,7 +16,7 @@
LL | let y = &mut x;
| ------ borrow of `x` occurs here
LL | unsafe {
-LL | asm!("nop" : : "r"(x)); //[ast]~ ERROR cannot use
+LL | asm!("nop" : : "r"(x));
| ^ use of borrowed `x`
...
LL | let z = y;
@@ -31,7 +31,7 @@
| first assignment to `x`
| help: make this binding mutable: `mut x`
LL | unsafe {
-LL | asm!("nop" : "=r"(x)); //[ast]~ ERROR cannot assign twice
+LL | asm!("nop" : "=r"(x));
| ^ cannot assign twice to immutable variable
error[E0384]: cannot assign twice to immutable variable `x`
@@ -43,13 +43,13 @@
| first assignment to `x`
| help: make this binding mutable: `mut x`
LL | unsafe {
-LL | asm!("nop" : "+r"(x)); //[ast]~ ERROR cannot assign twice
+LL | asm!("nop" : "+r"(x));
| ^ cannot assign twice to immutable variable
error[E0381]: use of possibly uninitialized variable: `x`
--> $DIR/borrowck-asm.rs:68:32
|
-LL | asm!("nop" : "=*r"(x)); //[ast]~ ERROR use of possibly uninitialized variable
+LL | asm!("nop" : "=*r"(x));
| ^ use of possibly uninitialized `x`
error[E0506]: cannot assign to `x` because it is borrowed
@@ -58,7 +58,7 @@
LL | let y = &*x;
| --- borrow of `x` occurs here
LL | unsafe {
-LL | asm!("nop" : "+r"(x)); //[ast]~ ERROR cannot assign to `x` because it is borrowed
+LL | asm!("nop" : "+r"(x));
| ^ assignment to borrowed `x` occurs here
...
LL | let z = y;
@@ -70,7 +70,7 @@
LL | let x = &mut 2;
| - move occurs because `x` has type `&mut i32`, which does not implement the `Copy` trait
LL | unsafe {
-LL | asm!("nop" : : "r"(x), "r"(x) ); //[ast]~ ERROR use of moved value
+LL | asm!("nop" : : "r"(x), "r"(x) );
| - ^ value used here after move
| |
| value moved here
diff --git a/src/test/ui/borrowck/borrowck-asm.ast.stderr b/src/test/ui/borrowck/borrowck-asm.ast.stderr
index 73eb08b..8418bb7 100644
--- a/src/test/ui/borrowck/borrowck-asm.ast.stderr
+++ b/src/test/ui/borrowck/borrowck-asm.ast.stderr
@@ -4,7 +4,7 @@
LL | asm!("nop" : : "r"(x));
| - value moved here
LL | }
-LL | let z = x; //[ast]~ ERROR use of moved value: `x`
+LL | let z = x;
| ^ value used here after move
|
= note: move occurs because `x` has type `&mut isize`, which does not implement the `Copy` trait
@@ -15,7 +15,7 @@
LL | let y = &mut x;
| - borrow of `x` occurs here
LL | unsafe {
-LL | asm!("nop" : : "r"(x)); //[ast]~ ERROR cannot use
+LL | asm!("nop" : : "r"(x));
| ^ use of borrowed `x`
error[E0384]: cannot assign twice to immutable variable `x`
@@ -24,7 +24,7 @@
LL | let x = 3;
| - first assignment to `x`
LL | unsafe {
-LL | asm!("nop" : "=r"(x)); //[ast]~ ERROR cannot assign twice
+LL | asm!("nop" : "=r"(x));
| ^ cannot assign twice to immutable variable
error[E0506]: cannot assign to `a` because it is borrowed
@@ -33,7 +33,7 @@
LL | let b = &*a;
| -- borrow of `a` occurs here
LL | unsafe {
-LL | asm!("nop" : "=r"(a)); //[ast]~ ERROR cannot assign to `a` because it is borrowed
+LL | asm!("nop" : "=r"(a));
| ^ assignment to borrowed `a` occurs here
error[E0384]: cannot assign twice to immutable variable `x`
@@ -42,13 +42,13 @@
LL | let x = 3;
| - first assignment to `x`
LL | unsafe {
-LL | asm!("nop" : "+r"(x)); //[ast]~ ERROR cannot assign twice
+LL | asm!("nop" : "+r"(x));
| ^ cannot assign twice to immutable variable
error[E0381]: use of possibly uninitialized variable: `x`
--> $DIR/borrowck-asm.rs:68:32
|
-LL | asm!("nop" : "=*r"(x)); //[ast]~ ERROR use of possibly uninitialized variable
+LL | asm!("nop" : "=*r"(x));
| ^ use of possibly uninitialized `x`
error[E0506]: cannot assign to `x` because it is borrowed
@@ -57,13 +57,13 @@
LL | let y = &*x;
| -- borrow of `x` occurs here
LL | unsafe {
-LL | asm!("nop" : "+r"(x)); //[ast]~ ERROR cannot assign to `x` because it is borrowed
+LL | asm!("nop" : "+r"(x));
| ^ assignment to borrowed `x` occurs here
error[E0382]: use of moved value: `x`
--> $DIR/borrowck-asm.rs:86:40
|
-LL | asm!("nop" : : "r"(x), "r"(x) ); //[ast]~ ERROR use of moved value
+LL | asm!("nop" : : "r"(x), "r"(x) );
| - ^ value used here after move
| |
| value moved here
diff --git a/src/test/ui/borrowck/borrowck-asm.mir.stderr b/src/test/ui/borrowck/borrowck-asm.mir.stderr
index 86e4832..dd6e5eb 100644
--- a/src/test/ui/borrowck/borrowck-asm.mir.stderr
+++ b/src/test/ui/borrowck/borrowck-asm.mir.stderr
@@ -7,7 +7,7 @@
LL | asm!("nop" : : "r"(x));
| - value moved here
LL | }
-LL | let z = x; //[ast]~ ERROR use of moved value: `x`
+LL | let z = x;
| ^ value used here after move
error[E0503]: cannot use `x` because it was mutably borrowed
@@ -16,7 +16,7 @@
LL | let y = &mut x;
| ------ borrow of `x` occurs here
LL | unsafe {
-LL | asm!("nop" : : "r"(x)); //[ast]~ ERROR cannot use
+LL | asm!("nop" : : "r"(x));
| ^ use of borrowed `x`
...
LL | let z = y;
@@ -31,7 +31,7 @@
| first assignment to `x`
| help: make this binding mutable: `mut x`
LL | unsafe {
-LL | asm!("nop" : "=r"(x)); //[ast]~ ERROR cannot assign twice
+LL | asm!("nop" : "=r"(x));
| ^ cannot assign twice to immutable variable
error[E0384]: cannot assign twice to immutable variable `x`
@@ -43,13 +43,13 @@
| first assignment to `x`
| help: make this binding mutable: `mut x`
LL | unsafe {
-LL | asm!("nop" : "+r"(x)); //[ast]~ ERROR cannot assign twice
+LL | asm!("nop" : "+r"(x));
| ^ cannot assign twice to immutable variable
error[E0381]: use of possibly uninitialized variable: `x`
--> $DIR/borrowck-asm.rs:68:32
|
-LL | asm!("nop" : "=*r"(x)); //[ast]~ ERROR use of possibly uninitialized variable
+LL | asm!("nop" : "=*r"(x));
| ^ use of possibly uninitialized `x`
error[E0506]: cannot assign to `x` because it is borrowed
@@ -58,7 +58,7 @@
LL | let y = &*x;
| --- borrow of `x` occurs here
LL | unsafe {
-LL | asm!("nop" : "+r"(x)); //[ast]~ ERROR cannot assign to `x` because it is borrowed
+LL | asm!("nop" : "+r"(x));
| ^ assignment to borrowed `x` occurs here
...
LL | let z = y;
@@ -70,7 +70,7 @@
LL | let x = &mut 2;
| - move occurs because `x` has type `&mut i32`, which does not implement the `Copy` trait
LL | unsafe {
-LL | asm!("nop" : : "r"(x), "r"(x) ); //[ast]~ ERROR use of moved value
+LL | asm!("nop" : : "r"(x), "r"(x) );
| - ^ value used here after move
| |
| value moved here
diff --git a/src/test/ui/borrowck/borrowck-assign-comp.ast.nll.stderr b/src/test/ui/borrowck/borrowck-assign-comp.ast.nll.stderr
index c204248..53af41c 100644
--- a/src/test/ui/borrowck/borrowck-assign-comp.ast.nll.stderr
+++ b/src/test/ui/borrowck/borrowck-assign-comp.ast.nll.stderr
@@ -4,9 +4,9 @@
LL | let q = &p;
| -- borrow of `p.x` occurs here
...
-LL | p.x = 5; //[ast]~ ERROR cannot assign to `p.x`
+LL | p.x = 5;
| ^^^^^^^ assignment to borrowed `p.x` occurs here
-LL | //[mir]~^ ERROR cannot assign to `p.x` because it is borrowed
+LL |
LL | q.x;
| --- borrow later used here
@@ -15,7 +15,7 @@
|
LL | let q = &p.y;
| ---- borrow of `p` occurs here
-LL | p = Point {x: 5, y: 7};//[ast]~ ERROR cannot assign to `p`
+LL | p = Point {x: 5, y: 7};
| ^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `p` occurs here
...
LL | *q; // stretch loan
@@ -26,9 +26,9 @@
|
LL | let q = &p.y;
| ---- borrow of `p.y` occurs here
-LL | p.y = 5; //[ast]~ ERROR cannot assign to `p.y`
+LL | p.y = 5;
| ^^^^^^^ assignment to borrowed `p.y` occurs here
-LL | //[mir]~^ ERROR cannot assign to `p.y` because it is borrowed
+LL |
LL | *q;
| -- borrow later used here
diff --git a/src/test/ui/borrowck/borrowck-assign-comp.ast.stderr b/src/test/ui/borrowck/borrowck-assign-comp.ast.stderr
index 735c168..4adb19c 100644
--- a/src/test/ui/borrowck/borrowck-assign-comp.ast.stderr
+++ b/src/test/ui/borrowck/borrowck-assign-comp.ast.stderr
@@ -4,7 +4,7 @@
LL | let q = &p;
| - borrow of `p.x` occurs here
...
-LL | p.x = 5; //[ast]~ ERROR cannot assign to `p.x`
+LL | p.x = 5;
| ^^^^^^^ assignment to borrowed `p.x` occurs here
error[E0506]: cannot assign to `p` because it is borrowed
@@ -12,7 +12,7 @@
|
LL | let q = &p.y;
| --- borrow of `p` occurs here
-LL | p = Point {x: 5, y: 7};//[ast]~ ERROR cannot assign to `p`
+LL | p = Point {x: 5, y: 7};
| ^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `p` occurs here
error[E0506]: cannot assign to `p.y` because it is borrowed
@@ -20,7 +20,7 @@
|
LL | let q = &p.y;
| --- borrow of `p.y` occurs here
-LL | p.y = 5; //[ast]~ ERROR cannot assign to `p.y`
+LL | p.y = 5;
| ^^^^^^^ assignment to borrowed `p.y` occurs here
error: aborting due to 3 previous errors
diff --git a/src/test/ui/borrowck/borrowck-assign-comp.mir.stderr b/src/test/ui/borrowck/borrowck-assign-comp.mir.stderr
index c204248..53af41c 100644
--- a/src/test/ui/borrowck/borrowck-assign-comp.mir.stderr
+++ b/src/test/ui/borrowck/borrowck-assign-comp.mir.stderr
@@ -4,9 +4,9 @@
LL | let q = &p;
| -- borrow of `p.x` occurs here
...
-LL | p.x = 5; //[ast]~ ERROR cannot assign to `p.x`
+LL | p.x = 5;
| ^^^^^^^ assignment to borrowed `p.x` occurs here
-LL | //[mir]~^ ERROR cannot assign to `p.x` because it is borrowed
+LL |
LL | q.x;
| --- borrow later used here
@@ -15,7 +15,7 @@
|
LL | let q = &p.y;
| ---- borrow of `p` occurs here
-LL | p = Point {x: 5, y: 7};//[ast]~ ERROR cannot assign to `p`
+LL | p = Point {x: 5, y: 7};
| ^^^^^^^^^^^^^^^^^^^^^^ assignment to borrowed `p` occurs here
...
LL | *q; // stretch loan
@@ -26,9 +26,9 @@
|
LL | let q = &p.y;
| ---- borrow of `p.y` occurs here
-LL | p.y = 5; //[ast]~ ERROR cannot assign to `p.y`
+LL | p.y = 5;
| ^^^^^^^ assignment to borrowed `p.y` occurs here
-LL | //[mir]~^ ERROR cannot assign to `p.y` because it is borrowed
+LL |
LL | *q;
| -- borrow later used here
diff --git a/src/test/ui/borrowck/borrowck-assign-to-constants.ast.nll.stderr b/src/test/ui/borrowck/borrowck-assign-to-constants.ast.nll.stderr
index 0a30a49..626e1ef 100644
--- a/src/test/ui/borrowck/borrowck-assign-to-constants.ast.nll.stderr
+++ b/src/test/ui/borrowck/borrowck-assign-to-constants.ast.nll.stderr
@@ -1,7 +1,7 @@
error[E0594]: cannot assign to immutable static item `foo`
--> $DIR/borrowck-assign-to-constants.rs:8:5
|
-LL | foo = 6; //[ast]~ ERROR cannot assign to immutable static item
+LL | foo = 6;
| ^^^^^^^ cannot assign
error: aborting due to previous error
diff --git a/src/test/ui/borrowck/borrowck-assign-to-constants.ast.stderr b/src/test/ui/borrowck/borrowck-assign-to-constants.ast.stderr
index 4111f55..e755785 100644
--- a/src/test/ui/borrowck/borrowck-assign-to-constants.ast.stderr
+++ b/src/test/ui/borrowck/borrowck-assign-to-constants.ast.stderr
@@ -1,7 +1,7 @@
error[E0594]: cannot assign to immutable static item
--> $DIR/borrowck-assign-to-constants.rs:8:5
|
-LL | foo = 6; //[ast]~ ERROR cannot assign to immutable static item
+LL | foo = 6;
| ^^^^^^^
error: aborting due to previous error
diff --git a/src/test/ui/borrowck/borrowck-assign-to-constants.mir.stderr b/src/test/ui/borrowck/borrowck-assign-to-constants.mir.stderr
index 0a30a49..626e1ef 100644
--- a/src/test/ui/borrowck/borrowck-assign-to-constants.mir.stderr
+++ b/src/test/ui/borrowck/borrowck-assign-to-constants.mir.stderr
@@ -1,7 +1,7 @@
error[E0594]: cannot assign to immutable static item `foo`
--> $DIR/borrowck-assign-to-constants.rs:8:5
|
-LL | foo = 6; //[ast]~ ERROR cannot assign to immutable static item
+LL | foo = 6;
| ^^^^^^^ cannot assign
error: aborting due to previous error
diff --git a/src/test/ui/borrowck/borrowck-box-insensitivity.ast.stderr b/src/test/ui/borrowck/borrowck-box-insensitivity.ast.stderr
index 236064d..60c8b33 100644
--- a/src/test/ui/borrowck/borrowck-box-insensitivity.ast.stderr
+++ b/src/test/ui/borrowck/borrowck-box-insensitivity.ast.stderr
@@ -3,8 +3,8 @@
|
LL | let _x = a.x;
| -- value moved here
-LL | //[ast]~^ value moved here
-LL | let _y = a.y; //[ast]~ ERROR use of moved
+LL |
+LL | let _y = a.y;
| ^^ value used here after move
|
= note: move occurs because `a.x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
@@ -14,8 +14,8 @@
|
LL | let _x = a.x;
| -- value moved here
-LL | //[ast]~^ value moved here
-LL | let _y = a.y; //[ast]~ ERROR use of moved
+LL |
+LL | let _y = a.y;
| ^^ value used here after move
|
= note: move occurs because `a.x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
@@ -25,8 +25,8 @@
|
LL | let _x = a.x;
| -- value moved here
-LL | //[ast]~^ value moved here
-LL | let _y = &a.y; //[ast]~ ERROR use of moved
+LL |
+LL | let _y = &a.y;
| ^^^ value used here after move
|
= note: move occurs because `a.x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
@@ -44,7 +44,7 @@
|
LL | let _x = &mut a.x;
| --- borrow of `a.x` occurs here
-LL | let _y = a.y; //[ast]~ ERROR cannot use
+LL | let _y = a.y;
| ^^ use of borrowed `a.x`
error[E0505]: cannot move out of `a.y` because it is borrowed
@@ -60,7 +60,7 @@
|
LL | let _x = &mut a.x;
| --- mutable borrow occurs here (via `a.x`)
-LL | let _y = &a.y; //[ast]~ ERROR cannot borrow
+LL | let _y = &a.y;
| ^^^ immutable borrow of `a.y` -- which overlaps with `a.x` -- occurs here
...
LL | }
@@ -71,7 +71,7 @@
|
LL | let _x = &a.x;
| --- immutable borrow occurs here (via `a.x`)
-LL | let _y = &mut a.y; //[ast]~ ERROR cannot borrow
+LL | let _y = &mut a.y;
| ^^^ mutable borrow of `a.y` -- which overlaps with `a.x` -- occurs here
...
LL | }
@@ -82,8 +82,8 @@
|
LL | let _x = a.x.x;
| -- value moved here
-LL | //[ast]~^ value moved here
-LL | let _y = a.y; //[ast]~ ERROR use of collaterally moved
+LL |
+LL | let _y = a.y;
| ^^ value used here after move
|
= note: move occurs because `a.x.x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
@@ -93,8 +93,8 @@
|
LL | let _x = a.x.x;
| -- value moved here
-LL | //[ast]~^ value moved here
-LL | let _y = a.y; //[ast]~ ERROR use of collaterally moved
+LL |
+LL | let _y = a.y;
| ^^ value used here after move
|
= note: move occurs because `a.x.x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
@@ -104,8 +104,8 @@
|
LL | let _x = a.x.x;
| -- value moved here
-LL | //[ast]~^ value moved here
-LL | let _y = &a.y; //[ast]~ ERROR use of collaterally moved
+LL |
+LL | let _y = &a.y;
| ^^^ value used here after move
|
= note: move occurs because `a.x.x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
@@ -115,7 +115,7 @@
|
LL | let _x = &a.x.x;
| ----- borrow of `a.x.x` occurs here
-LL | //[ast]~^ borrow of `a.x.x` occurs here
+LL |
LL | let _y = a.y;
| ^^ move out of `a.y` occurs here
@@ -124,7 +124,7 @@
|
LL | let _x = &mut a.x.x;
| ----- borrow of `a.x.x` occurs here
-LL | let _y = a.y; //[ast]~ ERROR cannot use
+LL | let _y = a.y;
| ^^ use of borrowed `a.x.x`
error[E0505]: cannot move out of `a.y` because it is borrowed
@@ -140,8 +140,8 @@
|
LL | let _x = &mut a.x.x;
| ----- mutable borrow occurs here
-LL | //[ast]~^ mutable borrow occurs here
-LL | let _y = &a.y; //[ast]~ ERROR cannot borrow
+LL |
+LL | let _y = &a.y;
| ^^^ immutable borrow occurs here
...
LL | }
@@ -152,8 +152,8 @@
|
LL | let _x = &a.x.x;
| ----- immutable borrow occurs here
-LL | //[ast]~^ immutable borrow occurs here
-LL | let _y = &mut a.y; //[ast]~ ERROR cannot borrow
+LL |
+LL | let _y = &mut a.y;
| ^^^ mutable borrow occurs here
...
LL | }
diff --git a/src/test/ui/borrowck/borrowck-box-insensitivity.mir.stderr b/src/test/ui/borrowck/borrowck-box-insensitivity.mir.stderr
index 171e992..0e380e9 100644
--- a/src/test/ui/borrowck/borrowck-box-insensitivity.mir.stderr
+++ b/src/test/ui/borrowck/borrowck-box-insensitivity.mir.stderr
@@ -1,7 +1,7 @@
error: compilation successful
--> $DIR/borrowck-box-insensitivity.rs:160:1
|
-LL | / fn main() { //[mir]~ ERROR compilation successful
+LL | / fn main() {
LL | | copy_after_move();
LL | | move_after_move();
LL | | borrow_after_move();
diff --git a/src/test/ui/borrowck/borrowck-closures-mut-and-imm.ast.nll.stderr b/src/test/ui/borrowck/borrowck-closures-mut-and-imm.ast.nll.stderr
index ed3d1ff..aac5fdf6 100644
--- a/src/test/ui/borrowck/borrowck-closures-mut-and-imm.ast.nll.stderr
+++ b/src/test/ui/borrowck/borrowck-closures-mut-and-imm.ast.nll.stderr
@@ -5,11 +5,11 @@
| -- - first borrow occurs due to use of `x` in closure
| |
| mutable borrow occurs here
-LL | let c2 = || x * 5; //[ast]~ ERROR cannot borrow `x`
+LL | let c2 = || x * 5;
| ^^ - second borrow occurs due to use of `x` in closure
| |
| immutable borrow occurs here
-LL | //[mir]~^ ERROR cannot borrow `x` as immutable because it is also borrowed as mutable
+LL |
LL | drop(c1);
| -- mutable borrow later used here
@@ -20,11 +20,11 @@
| -- - first borrow occurs due to use of `x` in closure
| |
| mutable borrow occurs here
-LL | let c2 = || get(&x); //[ast]~ ERROR cannot borrow `x`
+LL | let c2 = || get(&x);
| ^^ - second borrow occurs due to use of `x` in closure
| |
| immutable borrow occurs here
-LL | //[mir]~^ ERROR cannot borrow `x` as immutable because it is also borrowed as mutable
+LL |
LL | drop(c1);
| -- mutable borrow later used here
@@ -35,11 +35,11 @@
| -- - first borrow occurs due to use of `x` in closure
| |
| mutable borrow occurs here
-LL | let c2 = || x * 5; //[ast]~ ERROR cannot borrow `x`
+LL | let c2 = || x * 5;
| ^^ - second borrow occurs due to use of `x` in closure
| |
| immutable borrow occurs here
-LL | //[mir]~^ ERROR cannot borrow `x` as immutable because it is also borrowed as mutable
+LL |
LL | drop(c1);
| -- mutable borrow later used here
@@ -50,9 +50,9 @@
| -- - borrow occurs due to use in closure
| |
| borrow of `x` occurs here
-LL | x = 5; //[ast]~ ERROR cannot assign
+LL | x = 5;
| ^^^^^ assignment to borrowed `x` occurs here
-LL | //[mir]~^ ERROR cannot assign to `x` because it is borrowed
+LL |
LL | drop(c2);
| -- borrow later used here
@@ -63,9 +63,9 @@
| -- - borrow occurs due to use in closure
| |
| borrow of `x` occurs here
-LL | x = 5; //[ast]~ ERROR cannot assign
+LL | x = 5;
| ^^^^^ assignment to borrowed `x` occurs here
-LL | //[mir]~^ ERROR cannot assign to `x` because it is borrowed
+LL |
LL | drop(c1);
| -- borrow later used here
@@ -76,9 +76,9 @@
| -- - borrow occurs due to use in closure
| |
| borrow of `*x` occurs here
-LL | *x = 5; //[ast]~ ERROR cannot assign to `*x`
+LL | *x = 5;
| ^^^^^^ assignment to borrowed `*x` occurs here
-LL | //[mir]~^ ERROR cannot assign to `*x` because it is borrowed
+LL |
LL | drop(c1);
| -- borrow later used here
@@ -89,9 +89,9 @@
| -- - borrow occurs due to use in closure
| |
| borrow of `*x.f` occurs here
-LL | *x.f = 5; //[ast]~ ERROR cannot assign to `*x.f`
+LL | *x.f = 5;
| ^^^^^^^^ assignment to borrowed `*x.f` occurs here
-LL | //[mir]~^ ERROR cannot assign to `*x.f` because it is borrowed
+LL |
LL | drop(c1);
| -- borrow later used here
@@ -102,11 +102,11 @@
| -- - first borrow occurs due to use of `x` in closure
| |
| immutable borrow occurs here
-LL | let c2 = || *x.f = 5; //[ast]~ ERROR cannot borrow `x` as mutable
+LL | let c2 = || *x.f = 5;
| ^^ - second borrow occurs due to use of `x` in closure
| |
| mutable borrow occurs here
-LL | //[mir]~^ ERROR cannot borrow `x` as mutable because it is also borrowed as immutable
+LL |
LL | drop(c1);
| -- immutable borrow later used here
diff --git a/src/test/ui/borrowck/borrowck-closures-mut-and-imm.ast.stderr b/src/test/ui/borrowck/borrowck-closures-mut-and-imm.ast.stderr
index 363889c..d672d0c 100644
--- a/src/test/ui/borrowck/borrowck-closures-mut-and-imm.ast.stderr
+++ b/src/test/ui/borrowck/borrowck-closures-mut-and-imm.ast.stderr
@@ -5,7 +5,7 @@
| -- - previous borrow occurs due to use of `x` in closure
| |
| mutable borrow occurs here
-LL | let c2 = || x * 5; //[ast]~ ERROR cannot borrow `x`
+LL | let c2 = || x * 5;
| ^^ - borrow occurs due to use of `x` in closure
| |
| immutable borrow occurs here
@@ -20,7 +20,7 @@
| -- - previous borrow occurs due to use of `x` in closure
| |
| mutable borrow occurs here
-LL | let c2 = || get(&x); //[ast]~ ERROR cannot borrow `x`
+LL | let c2 = || get(&x);
| ^^ - borrow occurs due to use of `x` in closure
| |
| immutable borrow occurs here
@@ -35,7 +35,7 @@
| -- - previous borrow occurs due to use of `x` in closure
| |
| mutable borrow occurs here
-LL | let c2 = || x * 5; //[ast]~ ERROR cannot borrow `x`
+LL | let c2 = || x * 5;
| ^^ - borrow occurs due to use of `x` in closure
| |
| immutable borrow occurs here
@@ -48,7 +48,7 @@
|
LL | let c2 = || x * 5;
| -- borrow of `x` occurs here
-LL | x = 5; //[ast]~ ERROR cannot assign
+LL | x = 5;
| ^^^^^ assignment to borrowed `x` occurs here
error[E0506]: cannot assign to `x` because it is borrowed
@@ -56,7 +56,7 @@
|
LL | let c1 = || get(&x);
| -- borrow of `x` occurs here
-LL | x = 5; //[ast]~ ERROR cannot assign
+LL | x = 5;
| ^^^^^ assignment to borrowed `x` occurs here
error[E0506]: cannot assign to `*x` because it is borrowed
@@ -64,7 +64,7 @@
|
LL | let c1 = || get(&*x);
| -- borrow of `*x` occurs here
-LL | *x = 5; //[ast]~ ERROR cannot assign to `*x`
+LL | *x = 5;
| ^^^^^^ assignment to borrowed `*x` occurs here
error[E0506]: cannot assign to `*x.f` because it is borrowed
@@ -72,7 +72,7 @@
|
LL | let c1 = || get(&*x.f);
| -- borrow of `*x.f` occurs here
-LL | *x.f = 5; //[ast]~ ERROR cannot assign to `*x.f`
+LL | *x.f = 5;
| ^^^^^^^^ assignment to borrowed `*x.f` occurs here
error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable
@@ -82,7 +82,7 @@
| -- - previous borrow occurs due to use of `x` in closure
| |
| immutable borrow occurs here
-LL | let c2 = || *x.f = 5; //[ast]~ ERROR cannot borrow `x` as mutable
+LL | let c2 = || *x.f = 5;
| ^^ - borrow occurs due to use of `x` in closure
| |
| mutable borrow occurs here
diff --git a/src/test/ui/borrowck/borrowck-closures-mut-and-imm.mir.stderr b/src/test/ui/borrowck/borrowck-closures-mut-and-imm.mir.stderr
index ed3d1ff..aac5fdf6 100644
--- a/src/test/ui/borrowck/borrowck-closures-mut-and-imm.mir.stderr
+++ b/src/test/ui/borrowck/borrowck-closures-mut-and-imm.mir.stderr
@@ -5,11 +5,11 @@
| -- - first borrow occurs due to use of `x` in closure
| |
| mutable borrow occurs here
-LL | let c2 = || x * 5; //[ast]~ ERROR cannot borrow `x`
+LL | let c2 = || x * 5;
| ^^ - second borrow occurs due to use of `x` in closure
| |
| immutable borrow occurs here
-LL | //[mir]~^ ERROR cannot borrow `x` as immutable because it is also borrowed as mutable
+LL |
LL | drop(c1);
| -- mutable borrow later used here
@@ -20,11 +20,11 @@
| -- - first borrow occurs due to use of `x` in closure
| |
| mutable borrow occurs here
-LL | let c2 = || get(&x); //[ast]~ ERROR cannot borrow `x`
+LL | let c2 = || get(&x);
| ^^ - second borrow occurs due to use of `x` in closure
| |
| immutable borrow occurs here
-LL | //[mir]~^ ERROR cannot borrow `x` as immutable because it is also borrowed as mutable
+LL |
LL | drop(c1);
| -- mutable borrow later used here
@@ -35,11 +35,11 @@
| -- - first borrow occurs due to use of `x` in closure
| |
| mutable borrow occurs here
-LL | let c2 = || x * 5; //[ast]~ ERROR cannot borrow `x`
+LL | let c2 = || x * 5;
| ^^ - second borrow occurs due to use of `x` in closure
| |
| immutable borrow occurs here
-LL | //[mir]~^ ERROR cannot borrow `x` as immutable because it is also borrowed as mutable
+LL |
LL | drop(c1);
| -- mutable borrow later used here
@@ -50,9 +50,9 @@
| -- - borrow occurs due to use in closure
| |
| borrow of `x` occurs here
-LL | x = 5; //[ast]~ ERROR cannot assign
+LL | x = 5;
| ^^^^^ assignment to borrowed `x` occurs here
-LL | //[mir]~^ ERROR cannot assign to `x` because it is borrowed
+LL |
LL | drop(c2);
| -- borrow later used here
@@ -63,9 +63,9 @@
| -- - borrow occurs due to use in closure
| |
| borrow of `x` occurs here
-LL | x = 5; //[ast]~ ERROR cannot assign
+LL | x = 5;
| ^^^^^ assignment to borrowed `x` occurs here
-LL | //[mir]~^ ERROR cannot assign to `x` because it is borrowed
+LL |
LL | drop(c1);
| -- borrow later used here
@@ -76,9 +76,9 @@
| -- - borrow occurs due to use in closure
| |
| borrow of `*x` occurs here
-LL | *x = 5; //[ast]~ ERROR cannot assign to `*x`
+LL | *x = 5;
| ^^^^^^ assignment to borrowed `*x` occurs here
-LL | //[mir]~^ ERROR cannot assign to `*x` because it is borrowed
+LL |
LL | drop(c1);
| -- borrow later used here
@@ -89,9 +89,9 @@
| -- - borrow occurs due to use in closure
| |
| borrow of `*x.f` occurs here
-LL | *x.f = 5; //[ast]~ ERROR cannot assign to `*x.f`
+LL | *x.f = 5;
| ^^^^^^^^ assignment to borrowed `*x.f` occurs here
-LL | //[mir]~^ ERROR cannot assign to `*x.f` because it is borrowed
+LL |
LL | drop(c1);
| -- borrow later used here
@@ -102,11 +102,11 @@
| -- - first borrow occurs due to use of `x` in closure
| |
| immutable borrow occurs here
-LL | let c2 = || *x.f = 5; //[ast]~ ERROR cannot borrow `x` as mutable
+LL | let c2 = || *x.f = 5;
| ^^ - second borrow occurs due to use of `x` in closure
| |
| mutable borrow occurs here
-LL | //[mir]~^ ERROR cannot borrow `x` as mutable because it is also borrowed as immutable
+LL |
LL | drop(c1);
| -- immutable borrow later used here
diff --git a/src/test/ui/borrowck/borrowck-describe-lvalue.ast.nll.stderr b/src/test/ui/borrowck/borrowck-describe-lvalue.ast.nll.stderr
index 24467fa..c614469 100644
--- a/src/test/ui/borrowck/borrowck-describe-lvalue.ast.nll.stderr
+++ b/src/test/ui/borrowck/borrowck-describe-lvalue.ast.nll.stderr
@@ -3,9 +3,9 @@
|
LL | let y = &mut x;
| ------ first mutable borrow occurs here
-LL | &mut x; //[ast]~ ERROR cannot borrow `**x` as mutable more than once at a time
+LL | &mut x;
| ^^^^^^ second mutable borrow occurs here
-LL | //[mir]~^ ERROR cannot borrow `x` as mutable more than once at a time
+LL |
LL | *y = 1;
| ------ first borrow later used here
@@ -14,9 +14,9 @@
|
LL | let y = &mut x;
| ------ first mutable borrow occurs here
-LL | &mut x; //[ast]~ ERROR cannot borrow `**x` as mutable more than once at a time
+LL | &mut x;
| ^^^^^^ second mutable borrow occurs here
-LL | //[mir]~^ ERROR cannot borrow `x` as mutable more than once at a time
+LL |
LL | *y = 1;
| ------ first borrow later used here
@@ -25,10 +25,10 @@
|
LL | || {
| - inferred to be a `FnMut` closure
-LL | / || { //[mir]~ ERROR captured variable cannot escape `FnMut` closure body
+LL | / || {
LL | | let y = &mut x;
-LL | | &mut x; //[ast]~ ERROR cannot borrow `**x` as mutable more than once at a time
-LL | | //[mir]~^ ERROR cannot borrow `x` as mutable more than once at a time
+LL | | &mut x;
+LL | |
LL | | *y = 1;
LL | | drop(y);
LL | | }
@@ -42,9 +42,9 @@
|
LL | let x = f.x();
| - borrow of `f` occurs here
-LL | f.x; //[ast]~ ERROR cannot use `f.x` because it was mutably borrowed
+LL | f.x;
| ^^^ use of borrowed `f`
-LL | //[mir]~^ ERROR cannot use `f.x` because it was mutably borrowed
+LL |
LL | drop(x);
| - borrow later used here
@@ -53,9 +53,9 @@
|
LL | let x = g.x();
| - borrow of `g` occurs here
-LL | g.0; //[ast]~ ERROR cannot use `g.0` because it was mutably borrowed
+LL | g.0;
| ^^^ use of borrowed `g`
-LL | //[mir]~^ ERROR cannot use `g.0` because it was mutably borrowed
+LL |
LL | drop(x);
| - borrow later used here
@@ -64,9 +64,9 @@
|
LL | let x = &mut h.0;
| -------- borrow of `h.0` occurs here
-LL | h.0; //[ast]~ ERROR cannot use `h.0` because it was mutably borrowed
+LL | h.0;
| ^^^ use of borrowed `h.0`
-LL | //[mir]~^ ERROR cannot use `h.0` because it was mutably borrowed
+LL |
LL | drop(x);
| - borrow later used here
@@ -87,9 +87,9 @@
|
LL | let x = &mut u.a;
| -------- borrow of `u.a` occurs here
-LL | u.a; //[ast]~ ERROR cannot use `u.a` because it was mutably borrowed
+LL | u.a;
| ^^^ use of borrowed `u.a`
-LL | //[mir]~^ ERROR cannot use `u.a` because it was mutably borrowed
+LL |
LL | drop(x);
| - borrow later used here
@@ -98,9 +98,9 @@
|
LL | let x = f.x();
| - borrow of `*f` occurs here
-LL | f.x; //[ast]~ ERROR cannot use `f.x` because it was mutably borrowed
+LL | f.x;
| ^^^ use of borrowed `*f`
-LL | //[mir]~^ ERROR cannot use `f.x` because it was mutably borrowed
+LL |
LL | drop(x);
| - borrow later used here
@@ -109,9 +109,9 @@
|
LL | let x = g.x();
| - borrow of `*g` occurs here
-LL | g.0; //[ast]~ ERROR cannot use `g.0` because it was mutably borrowed
+LL | g.0;
| ^^^ use of borrowed `*g`
-LL | //[mir]~^ ERROR cannot use `g.0` because it was mutably borrowed
+LL |
LL | drop(x);
| - borrow later used here
@@ -120,9 +120,9 @@
|
LL | let x = &mut h.0;
| -------- borrow of `h.0` occurs here
-LL | h.0; //[ast]~ ERROR cannot use `h.0` because it was mutably borrowed
+LL | h.0;
| ^^^ use of borrowed `h.0`
-LL | //[mir]~^ ERROR cannot use `h.0` because it was mutably borrowed
+LL |
LL | drop(x);
| - borrow later used here
@@ -143,9 +143,9 @@
|
LL | let x = &mut u.a;
| -------- borrow of `u.a` occurs here
-LL | u.a; //[ast]~ ERROR cannot use `u.a` because it was mutably borrowed
+LL | u.a;
| ^^^ use of borrowed `u.a`
-LL | //[mir]~^ ERROR cannot use `u.a` because it was mutably borrowed
+LL |
LL | drop(x);
| - borrow later used here
@@ -372,7 +372,7 @@
|
LL | drop(x);
| - value moved here
-LL | drop(x); //[ast]~ ERROR use of moved value: `x`
+LL | drop(x);
| ^ value used here after move
|
= note: move occurs because `x` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
diff --git a/src/test/ui/borrowck/borrowck-describe-lvalue.ast.stderr b/src/test/ui/borrowck/borrowck-describe-lvalue.ast.stderr
index 278929e..d892db8 100644
--- a/src/test/ui/borrowck/borrowck-describe-lvalue.ast.stderr
+++ b/src/test/ui/borrowck/borrowck-describe-lvalue.ast.stderr
@@ -3,7 +3,7 @@
|
LL | let x = f.x();
| - borrow of `f` occurs here
-LL | f.x; //[ast]~ ERROR cannot use `f.x` because it was mutably borrowed
+LL | f.x;
| ^^^ use of borrowed `f`
error[E0503]: cannot use `g.0` because it was mutably borrowed
@@ -11,7 +11,7 @@
|
LL | let x = g.x();
| - borrow of `g` occurs here
-LL | g.0; //[ast]~ ERROR cannot use `g.0` because it was mutably borrowed
+LL | g.0;
| ^^^ use of borrowed `g`
error[E0503]: cannot use `h.0` because it was mutably borrowed
@@ -19,7 +19,7 @@
|
LL | let x = &mut h.0;
| --- borrow of `h.0` occurs here
-LL | h.0; //[ast]~ ERROR cannot use `h.0` because it was mutably borrowed
+LL | h.0;
| ^^^ use of borrowed `h.0`
error[E0503]: cannot use `e.0` because it was mutably borrowed
@@ -36,7 +36,7 @@
|
LL | let x = &mut u.a;
| --- borrow of `u.a` occurs here
-LL | u.a; //[ast]~ ERROR cannot use `u.a` because it was mutably borrowed
+LL | u.a;
| ^^^ use of borrowed `u.a`
error[E0503]: cannot use `f.x` because it was mutably borrowed
@@ -44,7 +44,7 @@
|
LL | let x = f.x();
| - borrow of `*f` occurs here
-LL | f.x; //[ast]~ ERROR cannot use `f.x` because it was mutably borrowed
+LL | f.x;
| ^^^ use of borrowed `*f`
error[E0503]: cannot use `g.0` because it was mutably borrowed
@@ -52,7 +52,7 @@
|
LL | let x = g.x();
| - borrow of `*g` occurs here
-LL | g.0; //[ast]~ ERROR cannot use `g.0` because it was mutably borrowed
+LL | g.0;
| ^^^ use of borrowed `*g`
error[E0503]: cannot use `h.0` because it was mutably borrowed
@@ -60,7 +60,7 @@
|
LL | let x = &mut h.0;
| --- borrow of `h.0` occurs here
-LL | h.0; //[ast]~ ERROR cannot use `h.0` because it was mutably borrowed
+LL | h.0;
| ^^^ use of borrowed `h.0`
error[E0503]: cannot use `e.0` because it was mutably borrowed
@@ -77,7 +77,7 @@
|
LL | let x = &mut u.a;
| --- borrow of `u.a` occurs here
-LL | u.a; //[ast]~ ERROR cannot use `u.a` because it was mutably borrowed
+LL | u.a;
| ^^^ use of borrowed `u.a`
error[E0503]: cannot use `v[..]` because it was mutably borrowed
@@ -213,7 +213,7 @@
|
LL | let y = &mut x;
| - first mutable borrow occurs here
-LL | &mut x; //[ast]~ ERROR cannot borrow `**x` as mutable more than once at a time
+LL | &mut x;
| ^ second mutable borrow occurs here
...
LL | };
@@ -224,7 +224,7 @@
|
LL | let y = &mut x;
| - first mutable borrow occurs here
-LL | &mut x; //[ast]~ ERROR cannot borrow `**x` as mutable more than once at a time
+LL | &mut x;
| ^ second mutable borrow occurs here
...
LL | }
@@ -235,7 +235,7 @@
|
LL | drop(x);
| - value moved here
-LL | drop(x); //[ast]~ ERROR use of moved value: `x`
+LL | drop(x);
| ^ value used here after move
|
= note: move occurs because `x` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
diff --git a/src/test/ui/borrowck/borrowck-describe-lvalue.mir.stderr b/src/test/ui/borrowck/borrowck-describe-lvalue.mir.stderr
index 279548f..af78340 100644
--- a/src/test/ui/borrowck/borrowck-describe-lvalue.mir.stderr
+++ b/src/test/ui/borrowck/borrowck-describe-lvalue.mir.stderr
@@ -3,9 +3,9 @@
|
LL | let y = &mut x;
| ------ first mutable borrow occurs here
-LL | &mut x; //[ast]~ ERROR cannot borrow `**x` as mutable more than once at a time
+LL | &mut x;
| ^^^^^^ second mutable borrow occurs here
-LL | //[mir]~^ ERROR cannot borrow `x` as mutable more than once at a time
+LL |
LL | *y = 1;
| ------ first borrow later used here
@@ -14,9 +14,9 @@
|
LL | let y = &mut x;
| ------ first mutable borrow occurs here
-LL | &mut x; //[ast]~ ERROR cannot borrow `**x` as mutable more than once at a time
+LL | &mut x;
| ^^^^^^ second mutable borrow occurs here
-LL | //[mir]~^ ERROR cannot borrow `x` as mutable more than once at a time
+LL |
LL | *y = 1;
| ------ first borrow later used here
@@ -25,10 +25,10 @@
|
LL | || {
| - inferred to be a `FnMut` closure
-LL | / || { //[mir]~ ERROR captured variable cannot escape `FnMut` closure body
+LL | / || {
LL | | let y = &mut x;
-LL | | &mut x; //[ast]~ ERROR cannot borrow `**x` as mutable more than once at a time
-LL | | //[mir]~^ ERROR cannot borrow `x` as mutable more than once at a time
+LL | | &mut x;
+LL | |
LL | | *y = 1;
LL | | drop(y);
LL | | }
@@ -42,9 +42,9 @@
|
LL | let x = f.x();
| - borrow of `f` occurs here
-LL | f.x; //[ast]~ ERROR cannot use `f.x` because it was mutably borrowed
+LL | f.x;
| ^^^ use of borrowed `f`
-LL | //[mir]~^ ERROR cannot use `f.x` because it was mutably borrowed
+LL |
LL | drop(x);
| - borrow later used here
@@ -53,9 +53,9 @@
|
LL | let x = g.x();
| - borrow of `g` occurs here
-LL | g.0; //[ast]~ ERROR cannot use `g.0` because it was mutably borrowed
+LL | g.0;
| ^^^ use of borrowed `g`
-LL | //[mir]~^ ERROR cannot use `g.0` because it was mutably borrowed
+LL |
LL | drop(x);
| - borrow later used here
@@ -64,9 +64,9 @@
|
LL | let x = &mut h.0;
| -------- borrow of `h.0` occurs here
-LL | h.0; //[ast]~ ERROR cannot use `h.0` because it was mutably borrowed
+LL | h.0;
| ^^^ use of borrowed `h.0`
-LL | //[mir]~^ ERROR cannot use `h.0` because it was mutably borrowed
+LL |
LL | drop(x);
| - borrow later used here
@@ -87,9 +87,9 @@
|
LL | let x = &mut u.a;
| -------- borrow of `u.a` occurs here
-LL | u.a; //[ast]~ ERROR cannot use `u.a` because it was mutably borrowed
+LL | u.a;
| ^^^ use of borrowed `u.a`
-LL | //[mir]~^ ERROR cannot use `u.a` because it was mutably borrowed
+LL |
LL | drop(x);
| - borrow later used here
@@ -98,9 +98,9 @@
|
LL | let x = f.x();
| - borrow of `*f` occurs here
-LL | f.x; //[ast]~ ERROR cannot use `f.x` because it was mutably borrowed
+LL | f.x;
| ^^^ use of borrowed `*f`
-LL | //[mir]~^ ERROR cannot use `f.x` because it was mutably borrowed
+LL |
LL | drop(x);
| - borrow later used here
@@ -109,9 +109,9 @@
|
LL | let x = g.x();
| - borrow of `*g` occurs here
-LL | g.0; //[ast]~ ERROR cannot use `g.0` because it was mutably borrowed
+LL | g.0;
| ^^^ use of borrowed `*g`
-LL | //[mir]~^ ERROR cannot use `g.0` because it was mutably borrowed
+LL |
LL | drop(x);
| - borrow later used here
@@ -120,9 +120,9 @@
|
LL | let x = &mut h.0;
| -------- borrow of `h.0` occurs here
-LL | h.0; //[ast]~ ERROR cannot use `h.0` because it was mutably borrowed
+LL | h.0;
| ^^^ use of borrowed `h.0`
-LL | //[mir]~^ ERROR cannot use `h.0` because it was mutably borrowed
+LL |
LL | drop(x);
| - borrow later used here
@@ -143,9 +143,9 @@
|
LL | let x = &mut u.a;
| -------- borrow of `u.a` occurs here
-LL | u.a; //[ast]~ ERROR cannot use `u.a` because it was mutably borrowed
+LL | u.a;
| ^^^ use of borrowed `u.a`
-LL | //[mir]~^ ERROR cannot use `u.a` because it was mutably borrowed
+LL |
LL | drop(x);
| - borrow later used here
@@ -366,7 +366,7 @@
|
LL | drop(x);
| - value moved here
-LL | drop(x); //[ast]~ ERROR use of moved value: `x`
+LL | drop(x);
| ^ value used here after move
|
= note: move occurs because `x` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
diff --git a/src/test/ui/borrowck/borrowck-fn-in-const-a.ast.stderr b/src/test/ui/borrowck/borrowck-fn-in-const-a.ast.stderr
index 6a5c504..16c62fc 100644
--- a/src/test/ui/borrowck/borrowck-fn-in-const-a.ast.stderr
+++ b/src/test/ui/borrowck/borrowck-fn-in-const-a.ast.stderr
@@ -1,7 +1,7 @@
error[E0507]: cannot move out of borrowed content
--> $DIR/borrowck-fn-in-const-a.rs:9:16
|
-LL | return *x //[ast]~ ERROR cannot move out of borrowed content [E0507]
+LL | return *x
| ^^ cannot move out of borrowed content
error: aborting due to previous error
diff --git a/src/test/ui/borrowck/borrowck-fn-in-const-a.mir.stderr b/src/test/ui/borrowck/borrowck-fn-in-const-a.mir.stderr
index 6a5c504..16c62fc 100644
--- a/src/test/ui/borrowck/borrowck-fn-in-const-a.mir.stderr
+++ b/src/test/ui/borrowck/borrowck-fn-in-const-a.mir.stderr
@@ -1,7 +1,7 @@
error[E0507]: cannot move out of borrowed content
--> $DIR/borrowck-fn-in-const-a.rs:9:16
|
-LL | return *x //[ast]~ ERROR cannot move out of borrowed content [E0507]
+LL | return *x
| ^^ cannot move out of borrowed content
error: aborting due to previous error
diff --git a/src/test/ui/borrowck/borrowck-imm-ref-to-mut-rec-field-issue-3162-c.ast.nll.stderr b/src/test/ui/borrowck/borrowck-imm-ref-to-mut-rec-field-issue-3162-c.ast.nll.stderr
index d3708b5..88b43c1 100644
--- a/src/test/ui/borrowck/borrowck-imm-ref-to-mut-rec-field-issue-3162-c.ast.nll.stderr
+++ b/src/test/ui/borrowck/borrowck-imm-ref-to-mut-rec-field-issue-3162-c.ast.nll.stderr
@@ -4,7 +4,7 @@
LL | let b = &mut _a;
| ------- borrow of `_a` occurs here
...
-LL | _a = 4; //[ast]~ ERROR cannot assign to `_a`
+LL | _a = 4;
| ^^^^^^ assignment to borrowed `_a` occurs here
...
LL | drop(b);
diff --git a/src/test/ui/borrowck/borrowck-imm-ref-to-mut-rec-field-issue-3162-c.ast.stderr b/src/test/ui/borrowck/borrowck-imm-ref-to-mut-rec-field-issue-3162-c.ast.stderr
index 618edf5..43c3c33 100644
--- a/src/test/ui/borrowck/borrowck-imm-ref-to-mut-rec-field-issue-3162-c.ast.stderr
+++ b/src/test/ui/borrowck/borrowck-imm-ref-to-mut-rec-field-issue-3162-c.ast.stderr
@@ -4,7 +4,7 @@
LL | let b = &mut _a;
| -- borrow of `_a` occurs here
...
-LL | _a = 4; //[ast]~ ERROR cannot assign to `_a`
+LL | _a = 4;
| ^^^^^^ assignment to borrowed `_a` occurs here
error: aborting due to previous error
diff --git a/src/test/ui/borrowck/borrowck-imm-ref-to-mut-rec-field-issue-3162-c.mir.stderr b/src/test/ui/borrowck/borrowck-imm-ref-to-mut-rec-field-issue-3162-c.mir.stderr
index d3708b5..88b43c1 100644
--- a/src/test/ui/borrowck/borrowck-imm-ref-to-mut-rec-field-issue-3162-c.mir.stderr
+++ b/src/test/ui/borrowck/borrowck-imm-ref-to-mut-rec-field-issue-3162-c.mir.stderr
@@ -4,7 +4,7 @@
LL | let b = &mut _a;
| ------- borrow of `_a` occurs here
...
-LL | _a = 4; //[ast]~ ERROR cannot assign to `_a`
+LL | _a = 4;
| ^^^^^^ assignment to borrowed `_a` occurs here
...
LL | drop(b);
diff --git a/src/test/ui/borrowck/borrowck-issue-14498.ast.nll.stderr b/src/test/ui/borrowck/borrowck-issue-14498.ast.nll.stderr
index 8161053..b53cfdd 100644
--- a/src/test/ui/borrowck/borrowck-issue-14498.ast.nll.stderr
+++ b/src/test/ui/borrowck/borrowck-issue-14498.ast.nll.stderr
@@ -3,7 +3,7 @@
|
LL | let p = &y;
| -- help: consider changing this to be a mutable reference: `&mut y`
-LL | ***p = 2; //[ast]~ ERROR cannot assign to data in a `&` reference
+LL | ***p = 2;
| ^^^^^^^^ `p` is a `&` reference, so the data it refers to cannot be written
error[E0506]: cannot assign to `**y` because it is borrowed
@@ -12,9 +12,9 @@
LL | let p = &y;
| -- borrow of `**y` occurs here
LL | let q = &***p;
-LL | **y = 2; //[ast]~ ERROR cannot assign to `**y` because it is borrowed
+LL | **y = 2;
| ^^^^^^^ assignment to borrowed `**y` occurs here
-LL | //[mir]~^ ERROR cannot assign to `**y` because it is borrowed
+LL |
LL | drop(p);
| - borrow later used here
@@ -24,9 +24,9 @@
LL | let p = &y;
| -- borrow of `**y` occurs here
LL | let q = &***p;
-LL | **y = 2; //[ast]~ ERROR cannot assign to `**y` because it is borrowed
+LL | **y = 2;
| ^^^^^^^ assignment to borrowed `**y` occurs here
-LL | //[mir]~^ ERROR cannot assign to `**y` because it is borrowed
+LL |
LL | drop(p);
| - borrow later used here
@@ -36,9 +36,9 @@
LL | let p = &y;
| -- borrow of `**y` occurs here
LL | let q = &***p;
-LL | **y = 2; //[ast]~ ERROR cannot assign to `**y` because it is borrowed
+LL | **y = 2;
| ^^^^^^^ assignment to borrowed `**y` occurs here
-LL | //[mir]~^ ERROR cannot assign to `**y` because it is borrowed
+LL |
LL | drop(p);
| - borrow later used here
@@ -48,9 +48,9 @@
LL | let p = &y;
| -- borrow of `**y` occurs here
LL | let q = &***p;
-LL | **y = 2; //[ast]~ ERROR cannot assign to `**y` because it is borrowed
+LL | **y = 2;
| ^^^^^^^ assignment to borrowed `**y` occurs here
-LL | //[mir]~^ ERROR cannot assign to `**y` because it is borrowed
+LL |
LL | drop(p);
| - borrow later used here
@@ -60,9 +60,9 @@
LL | let p = &y.a;
| ---- borrow of `**y.a` occurs here
LL | let q = &***p;
-LL | **y.a = 2; //[ast]~ ERROR cannot assign to `**y.a` because it is borrowed
+LL | **y.a = 2;
| ^^^^^^^^^ assignment to borrowed `**y.a` occurs here
-LL | //[mir]~^ ERROR cannot assign to `**y.a` because it is borrowed
+LL |
LL | drop(p);
| - borrow later used here
@@ -72,9 +72,9 @@
LL | let p = &y.a;
| ---- borrow of `**y.a` occurs here
LL | let q = &***p;
-LL | **y.a = 2; //[ast]~ ERROR cannot assign to `**y.a` because it is borrowed
+LL | **y.a = 2;
| ^^^^^^^^^ assignment to borrowed `**y.a` occurs here
-LL | //[mir]~^ ERROR cannot assign to `**y.a` because it is borrowed
+LL |
LL | drop(p);
| - borrow later used here
@@ -84,9 +84,9 @@
LL | let p = &y.a;
| ---- borrow of `**y.a` occurs here
LL | let q = &***p;
-LL | **y.a = 2; //[ast]~ ERROR cannot assign to `**y.a` because it is borrowed
+LL | **y.a = 2;
| ^^^^^^^^^ assignment to borrowed `**y.a` occurs here
-LL | //[mir]~^ ERROR cannot assign to `**y.a` because it is borrowed
+LL |
LL | drop(p);
| - borrow later used here
@@ -96,9 +96,9 @@
LL | let p = &y.a;
| ---- borrow of `**y.a` occurs here
LL | let q = &***p;
-LL | **y.a = 2; //[ast]~ ERROR cannot assign to `**y.a` because it is borrowed
+LL | **y.a = 2;
| ^^^^^^^^^ assignment to borrowed `**y.a` occurs here
-LL | //[mir]~^ ERROR cannot assign to `**y.a` because it is borrowed
+LL |
LL | drop(p);
| - borrow later used here
diff --git a/src/test/ui/borrowck/borrowck-issue-14498.ast.stderr b/src/test/ui/borrowck/borrowck-issue-14498.ast.stderr
index 59249da..b002ee7 100644
--- a/src/test/ui/borrowck/borrowck-issue-14498.ast.stderr
+++ b/src/test/ui/borrowck/borrowck-issue-14498.ast.stderr
@@ -1,7 +1,7 @@
error[E0389]: cannot assign to data in a `&` reference
--> $DIR/borrowck-issue-14498.rs:19:5
|
-LL | ***p = 2; //[ast]~ ERROR cannot assign to data in a `&` reference
+LL | ***p = 2;
| ^^^^^^^^ assignment into an immutable reference
error[E0506]: cannot assign to `**y` because it is borrowed
@@ -10,7 +10,7 @@
LL | let p = &y;
| - borrow of `**y` occurs here
LL | let q = &***p;
-LL | **y = 2; //[ast]~ ERROR cannot assign to `**y` because it is borrowed
+LL | **y = 2;
| ^^^^^^^ assignment to borrowed `**y` occurs here
error[E0506]: cannot assign to `**y` because it is borrowed
@@ -19,7 +19,7 @@
LL | let p = &y;
| - borrow of `**y` occurs here
LL | let q = &***p;
-LL | **y = 2; //[ast]~ ERROR cannot assign to `**y` because it is borrowed
+LL | **y = 2;
| ^^^^^^^ assignment to borrowed `**y` occurs here
error[E0506]: cannot assign to `**y` because it is borrowed
@@ -28,7 +28,7 @@
LL | let p = &y;
| - borrow of `**y` occurs here
LL | let q = &***p;
-LL | **y = 2; //[ast]~ ERROR cannot assign to `**y` because it is borrowed
+LL | **y = 2;
| ^^^^^^^ assignment to borrowed `**y` occurs here
error[E0506]: cannot assign to `**y` because it is borrowed
@@ -37,7 +37,7 @@
LL | let p = &y;
| - borrow of `**y` occurs here
LL | let q = &***p;
-LL | **y = 2; //[ast]~ ERROR cannot assign to `**y` because it is borrowed
+LL | **y = 2;
| ^^^^^^^ assignment to borrowed `**y` occurs here
error[E0506]: cannot assign to `**y.a` because it is borrowed
@@ -46,7 +46,7 @@
LL | let p = &y.a;
| --- borrow of `**y.a` occurs here
LL | let q = &***p;
-LL | **y.a = 2; //[ast]~ ERROR cannot assign to `**y.a` because it is borrowed
+LL | **y.a = 2;
| ^^^^^^^^^ assignment to borrowed `**y.a` occurs here
error[E0506]: cannot assign to `**y.a` because it is borrowed
@@ -55,7 +55,7 @@
LL | let p = &y.a;
| --- borrow of `**y.a` occurs here
LL | let q = &***p;
-LL | **y.a = 2; //[ast]~ ERROR cannot assign to `**y.a` because it is borrowed
+LL | **y.a = 2;
| ^^^^^^^^^ assignment to borrowed `**y.a` occurs here
error[E0506]: cannot assign to `**y.a` because it is borrowed
@@ -64,7 +64,7 @@
LL | let p = &y.a;
| --- borrow of `**y.a` occurs here
LL | let q = &***p;
-LL | **y.a = 2; //[ast]~ ERROR cannot assign to `**y.a` because it is borrowed
+LL | **y.a = 2;
| ^^^^^^^^^ assignment to borrowed `**y.a` occurs here
error[E0506]: cannot assign to `**y.a` because it is borrowed
@@ -73,7 +73,7 @@
LL | let p = &y.a;
| --- borrow of `**y.a` occurs here
LL | let q = &***p;
-LL | **y.a = 2; //[ast]~ ERROR cannot assign to `**y.a` because it is borrowed
+LL | **y.a = 2;
| ^^^^^^^^^ assignment to borrowed `**y.a` occurs here
error: aborting due to 9 previous errors
diff --git a/src/test/ui/borrowck/borrowck-issue-14498.mir.stderr b/src/test/ui/borrowck/borrowck-issue-14498.mir.stderr
index 8161053..b53cfdd 100644
--- a/src/test/ui/borrowck/borrowck-issue-14498.mir.stderr
+++ b/src/test/ui/borrowck/borrowck-issue-14498.mir.stderr
@@ -3,7 +3,7 @@
|
LL | let p = &y;
| -- help: consider changing this to be a mutable reference: `&mut y`
-LL | ***p = 2; //[ast]~ ERROR cannot assign to data in a `&` reference
+LL | ***p = 2;
| ^^^^^^^^ `p` is a `&` reference, so the data it refers to cannot be written
error[E0506]: cannot assign to `**y` because it is borrowed
@@ -12,9 +12,9 @@
LL | let p = &y;
| -- borrow of `**y` occurs here
LL | let q = &***p;
-LL | **y = 2; //[ast]~ ERROR cannot assign to `**y` because it is borrowed
+LL | **y = 2;
| ^^^^^^^ assignment to borrowed `**y` occurs here
-LL | //[mir]~^ ERROR cannot assign to `**y` because it is borrowed
+LL |
LL | drop(p);
| - borrow later used here
@@ -24,9 +24,9 @@
LL | let p = &y;
| -- borrow of `**y` occurs here
LL | let q = &***p;
-LL | **y = 2; //[ast]~ ERROR cannot assign to `**y` because it is borrowed
+LL | **y = 2;
| ^^^^^^^ assignment to borrowed `**y` occurs here
-LL | //[mir]~^ ERROR cannot assign to `**y` because it is borrowed
+LL |
LL | drop(p);
| - borrow later used here
@@ -36,9 +36,9 @@
LL | let p = &y;
| -- borrow of `**y` occurs here
LL | let q = &***p;
-LL | **y = 2; //[ast]~ ERROR cannot assign to `**y` because it is borrowed
+LL | **y = 2;
| ^^^^^^^ assignment to borrowed `**y` occurs here
-LL | //[mir]~^ ERROR cannot assign to `**y` because it is borrowed
+LL |
LL | drop(p);
| - borrow later used here
@@ -48,9 +48,9 @@
LL | let p = &y;
| -- borrow of `**y` occurs here
LL | let q = &***p;
-LL | **y = 2; //[ast]~ ERROR cannot assign to `**y` because it is borrowed
+LL | **y = 2;
| ^^^^^^^ assignment to borrowed `**y` occurs here
-LL | //[mir]~^ ERROR cannot assign to `**y` because it is borrowed
+LL |
LL | drop(p);
| - borrow later used here
@@ -60,9 +60,9 @@
LL | let p = &y.a;
| ---- borrow of `**y.a` occurs here
LL | let q = &***p;
-LL | **y.a = 2; //[ast]~ ERROR cannot assign to `**y.a` because it is borrowed
+LL | **y.a = 2;
| ^^^^^^^^^ assignment to borrowed `**y.a` occurs here
-LL | //[mir]~^ ERROR cannot assign to `**y.a` because it is borrowed
+LL |
LL | drop(p);
| - borrow later used here
@@ -72,9 +72,9 @@
LL | let p = &y.a;
| ---- borrow of `**y.a` occurs here
LL | let q = &***p;
-LL | **y.a = 2; //[ast]~ ERROR cannot assign to `**y.a` because it is borrowed
+LL | **y.a = 2;
| ^^^^^^^^^ assignment to borrowed `**y.a` occurs here
-LL | //[mir]~^ ERROR cannot assign to `**y.a` because it is borrowed
+LL |
LL | drop(p);
| - borrow later used here
@@ -84,9 +84,9 @@
LL | let p = &y.a;
| ---- borrow of `**y.a` occurs here
LL | let q = &***p;
-LL | **y.a = 2; //[ast]~ ERROR cannot assign to `**y.a` because it is borrowed
+LL | **y.a = 2;
| ^^^^^^^^^ assignment to borrowed `**y.a` occurs here
-LL | //[mir]~^ ERROR cannot assign to `**y.a` because it is borrowed
+LL |
LL | drop(p);
| - borrow later used here
@@ -96,9 +96,9 @@
LL | let p = &y.a;
| ---- borrow of `**y.a` occurs here
LL | let q = &***p;
-LL | **y.a = 2; //[ast]~ ERROR cannot assign to `**y.a` because it is borrowed
+LL | **y.a = 2;
| ^^^^^^^^^ assignment to borrowed `**y.a` occurs here
-LL | //[mir]~^ ERROR cannot assign to `**y.a` because it is borrowed
+LL |
LL | drop(p);
| - borrow later used here
diff --git a/src/test/ui/borrowck/borrowck-lend-flow-loop.ast.stderr b/src/test/ui/borrowck/borrowck-lend-flow-loop.ast.stderr
index 1844d82..ab10caa 100644
--- a/src/test/ui/borrowck/borrowck-lend-flow-loop.ast.stderr
+++ b/src/test/ui/borrowck/borrowck-lend-flow-loop.ast.stderr
@@ -4,7 +4,7 @@
LL | let mut x = &mut v;
| - mutable borrow occurs here
...
-LL | borrow(&*v); //[ast]~ ERROR cannot borrow
+LL | borrow(&*v);
| ^^ immutable borrow occurs here
LL | }
LL | }
@@ -16,7 +16,7 @@
LL | let mut x = &mut v;
| - mutable borrow occurs here
LL | for _ in 0..3 {
-LL | borrow(&*v); //[ast]~ ERROR cannot borrow
+LL | borrow(&*v);
| ^^ immutable borrow occurs here
...
LL | }
@@ -25,7 +25,7 @@
error[E0502]: cannot borrow `*v` as mutable because `v` is also borrowed as immutable
--> $DIR/borrowck-lend-flow-loop.rs:57:25
|
-LL | borrow_mut(&mut *v); //[ast]~ ERROR cannot borrow
+LL | borrow_mut(&mut *v);
| ^^ mutable borrow occurs here
LL | _x = &v;
| - immutable borrow occurs here
@@ -36,7 +36,7 @@
error[E0502]: cannot borrow `*v` as mutable because `v` is also borrowed as immutable
--> $DIR/borrowck-lend-flow-loop.rs:69:25
|
-LL | borrow_mut(&mut *v); //[ast]~ ERROR cannot borrow
+LL | borrow_mut(&mut *v);
| ^^ mutable borrow occurs here
LL | _x = &v;
| - immutable borrow occurs here
@@ -50,7 +50,7 @@
LL | _x = &v;
| - immutable borrow occurs here
...
-LL | borrow_mut(&mut *v); //[ast]~ ERROR cannot borrow
+LL | borrow_mut(&mut *v);
| ^^ mutable borrow occurs here
LL | }
| - immutable borrow ends here
@@ -61,7 +61,7 @@
LL | _x = &v;
| - immutable borrow occurs here
...
-LL | borrow_mut(&mut *v); //[ast]~ ERROR cannot borrow
+LL | borrow_mut(&mut *v);
| ^^ mutable borrow occurs here
LL | }
| - immutable borrow ends here
@@ -69,10 +69,10 @@
error[E0502]: cannot borrow `*v` as immutable because `v` is also borrowed as mutable
--> $DIR/borrowck-lend-flow-loop.rs:109:17
|
-LL | borrow(&*v); //[ast]~ ERROR cannot borrow
+LL | borrow(&*v);
| ^^ immutable borrow occurs here
...
-LL | x = &mut v; //[ast]~ ERROR cannot borrow
+LL | x = &mut v;
| - mutable borrow occurs here
...
LL | }
@@ -81,7 +81,7 @@
error[E0499]: cannot borrow `v` as mutable more than once at a time
--> $DIR/borrowck-lend-flow-loop.rs:112:22
|
-LL | x = &mut v; //[ast]~ ERROR cannot borrow
+LL | x = &mut v;
| ^ mutable borrow starts here in previous iteration of loop
...
LL | }
diff --git a/src/test/ui/borrowck/borrowck-lend-flow-loop.nll.stderr b/src/test/ui/borrowck/borrowck-lend-flow-loop.nll.stderr
index 396fd6f..6dd6c1f 100644
--- a/src/test/ui/borrowck/borrowck-lend-flow-loop.nll.stderr
+++ b/src/test/ui/borrowck/borrowck-lend-flow-loop.nll.stderr
@@ -4,7 +4,7 @@
LL | let mut x = &mut v;
| ------ mutable borrow occurs here
LL | for _ in 0..3 {
-LL | borrow(&*v); //[ast]~ ERROR cannot borrow
+LL | borrow(&*v);
| ^^^ immutable borrow occurs here
...
LL | *x = box 5;
@@ -15,10 +15,10 @@
|
LL | **x += 1;
| -------- mutable borrow later used here
-LL | borrow(&*v); //[ast]~ ERROR cannot borrow
+LL | borrow(&*v);
| ^^^ immutable borrow occurs here
...
-LL | x = &mut v; //[ast]~ ERROR cannot borrow
+LL | x = &mut v;
| ------ mutable borrow occurs here
error: aborting due to 2 previous errors
diff --git a/src/test/ui/borrowck/borrowck-lend-flow-match.ast.nll.stderr b/src/test/ui/borrowck/borrowck-lend-flow-match.ast.nll.stderr
index 02289e0..734f965 100644
--- a/src/test/ui/borrowck/borrowck-lend-flow-match.ast.nll.stderr
+++ b/src/test/ui/borrowck/borrowck-lend-flow-match.ast.nll.stderr
@@ -3,9 +3,9 @@
|
LL | Some(ref r) => {
| ----- borrow of `x` occurs here
-LL | x = Some(1); //[ast]~ ERROR cannot assign
+LL | x = Some(1);
| ^^^^^^^^^^^ assignment to borrowed `x` occurs here
-LL | //[mir]~^ ERROR cannot assign to `x` because it is borrowed
+LL |
LL | drop(r);
| - borrow later used here
diff --git a/src/test/ui/borrowck/borrowck-lend-flow-match.ast.stderr b/src/test/ui/borrowck/borrowck-lend-flow-match.ast.stderr
index 23eb814..236bc11 100644
--- a/src/test/ui/borrowck/borrowck-lend-flow-match.ast.stderr
+++ b/src/test/ui/borrowck/borrowck-lend-flow-match.ast.stderr
@@ -3,7 +3,7 @@
|
LL | Some(ref r) => {
| ----- borrow of `x` occurs here
-LL | x = Some(1); //[ast]~ ERROR cannot assign
+LL | x = Some(1);
| ^^^^^^^^^^^ assignment to borrowed `x` occurs here
error: aborting due to previous error
diff --git a/src/test/ui/borrowck/borrowck-lend-flow-match.mir.stderr b/src/test/ui/borrowck/borrowck-lend-flow-match.mir.stderr
index 02289e0..734f965 100644
--- a/src/test/ui/borrowck/borrowck-lend-flow-match.mir.stderr
+++ b/src/test/ui/borrowck/borrowck-lend-flow-match.mir.stderr
@@ -3,9 +3,9 @@
|
LL | Some(ref r) => {
| ----- borrow of `x` occurs here
-LL | x = Some(1); //[ast]~ ERROR cannot assign
+LL | x = Some(1);
| ^^^^^^^^^^^ assignment to borrowed `x` occurs here
-LL | //[mir]~^ ERROR cannot assign to `x` because it is borrowed
+LL |
LL | drop(r);
| - borrow later used here
diff --git a/src/test/ui/borrowck/borrowck-match-already-borrowed.ast.nll.stderr b/src/test/ui/borrowck/borrowck-match-already-borrowed.ast.nll.stderr
index b2b82fb..ecbfeec 100644
--- a/src/test/ui/borrowck/borrowck-match-already-borrowed.ast.nll.stderr
+++ b/src/test/ui/borrowck/borrowck-match-already-borrowed.ast.nll.stderr
@@ -4,7 +4,7 @@
LL | let p = &mut foo;
| -------- borrow of `foo` occurs here
LL | let _ = match foo {
-LL | Foo::B => 1, //[mir]~ ERROR [E0503]
+LL | Foo::B => 1,
| ^^^^^^ use of borrowed `foo`
...
LL | drop(p);
@@ -16,7 +16,7 @@
LL | let p = &mut foo;
| -------- borrow of `foo` occurs here
...
-LL | Foo::A(x) => x //[ast]~ ERROR [E0503]
+LL | Foo::A(x) => x
| ^ use of borrowed `foo`
...
LL | drop(p);
@@ -28,7 +28,7 @@
LL | let r = &mut x;
| ------ borrow of `x` occurs here
LL | let _ = match x {
-LL | x => x + 1, //[ast]~ ERROR [E0503]
+LL | x => x + 1,
| ^ use of borrowed `x`
...
LL | drop(r);
@@ -40,7 +40,7 @@
LL | let r = &mut x;
| ------ borrow of `x` occurs here
...
-LL | y => y + 2, //[ast]~ ERROR [E0503]
+LL | y => y + 2,
| ^ use of borrowed `x`
...
LL | drop(r);
diff --git a/src/test/ui/borrowck/borrowck-match-already-borrowed.ast.stderr b/src/test/ui/borrowck/borrowck-match-already-borrowed.ast.stderr
index cfbbef9..a5da1fc 100644
--- a/src/test/ui/borrowck/borrowck-match-already-borrowed.ast.stderr
+++ b/src/test/ui/borrowck/borrowck-match-already-borrowed.ast.stderr
@@ -4,7 +4,7 @@
LL | let p = &mut foo;
| --- borrow of `foo` occurs here
...
-LL | Foo::A(x) => x //[ast]~ ERROR [E0503]
+LL | Foo::A(x) => x
| ^ use of borrowed `foo`
error[E0503]: cannot use `x` because it was mutably borrowed
@@ -13,7 +13,7 @@
LL | let r = &mut x;
| - borrow of `x` occurs here
LL | let _ = match x {
-LL | x => x + 1, //[ast]~ ERROR [E0503]
+LL | x => x + 1,
| ^ use of borrowed `x`
error[E0503]: cannot use `x` because it was mutably borrowed
@@ -22,7 +22,7 @@
LL | let r = &mut x;
| - borrow of `x` occurs here
...
-LL | y => y + 2, //[ast]~ ERROR [E0503]
+LL | y => y + 2,
| ^ use of borrowed `x`
error: aborting due to 3 previous errors
diff --git a/src/test/ui/borrowck/borrowck-match-already-borrowed.mir.stderr b/src/test/ui/borrowck/borrowck-match-already-borrowed.mir.stderr
index b2b82fb..ecbfeec 100644
--- a/src/test/ui/borrowck/borrowck-match-already-borrowed.mir.stderr
+++ b/src/test/ui/borrowck/borrowck-match-already-borrowed.mir.stderr
@@ -4,7 +4,7 @@
LL | let p = &mut foo;
| -------- borrow of `foo` occurs here
LL | let _ = match foo {
-LL | Foo::B => 1, //[mir]~ ERROR [E0503]
+LL | Foo::B => 1,
| ^^^^^^ use of borrowed `foo`
...
LL | drop(p);
@@ -16,7 +16,7 @@
LL | let p = &mut foo;
| -------- borrow of `foo` occurs here
...
-LL | Foo::A(x) => x //[ast]~ ERROR [E0503]
+LL | Foo::A(x) => x
| ^ use of borrowed `foo`
...
LL | drop(p);
@@ -28,7 +28,7 @@
LL | let r = &mut x;
| ------ borrow of `x` occurs here
LL | let _ = match x {
-LL | x => x + 1, //[ast]~ ERROR [E0503]
+LL | x => x + 1,
| ^ use of borrowed `x`
...
LL | drop(r);
@@ -40,7 +40,7 @@
LL | let r = &mut x;
| ------ borrow of `x` occurs here
...
-LL | y => y + 2, //[ast]~ ERROR [E0503]
+LL | y => y + 2,
| ^ use of borrowed `x`
...
LL | drop(r);
diff --git a/src/test/ui/borrowck/borrowck-match-binding-is-assignment.ast.nll.stderr b/src/test/ui/borrowck/borrowck-match-binding-is-assignment.ast.nll.stderr
index cd88d69..2ac0539 100644
--- a/src/test/ui/borrowck/borrowck-match-binding-is-assignment.ast.nll.stderr
+++ b/src/test/ui/borrowck/borrowck-match-binding-is-assignment.ast.nll.stderr
@@ -6,7 +6,7 @@
| |
| first assignment to `x`
| help: make this binding mutable: `mut x`
-LL | x += 1; //[ast]~ ERROR cannot assign twice to immutable variable `x`
+LL | x += 1;
| ^^^^^^ cannot assign twice to immutable variable
error[E0384]: cannot assign twice to immutable variable `x`
@@ -17,7 +17,7 @@
| |
| first assignment to `x`
| help: make this binding mutable: `mut x`
-LL | x += 1; //[ast]~ ERROR cannot assign twice to immutable variable `x`
+LL | x += 1;
| ^^^^^^ cannot assign twice to immutable variable
error[E0384]: cannot assign twice to immutable variable `x`
@@ -28,7 +28,7 @@
| |
| first assignment to `x`
| help: make this binding mutable: `mut x`
-LL | x += 1; //[ast]~ ERROR cannot assign twice to immutable variable `x`
+LL | x += 1;
| ^^^^^^ cannot assign twice to immutable variable
error[E0384]: cannot assign twice to immutable variable `x`
@@ -39,7 +39,7 @@
| |
| first assignment to `x`
| help: make this binding mutable: `mut x`
-LL | x += 1; //[ast]~ ERROR cannot assign twice to immutable variable `x`
+LL | x += 1;
| ^^^^^^ cannot assign twice to immutable variable
error[E0384]: cannot assign twice to immutable variable `x`
@@ -50,7 +50,7 @@
| |
| first assignment to `x`
| help: make this binding mutable: `mut x`
-LL | x += 1; //[ast]~ ERROR cannot assign twice to immutable variable `x`
+LL | x += 1;
| ^^^^^^ cannot assign twice to immutable variable
error: aborting due to 5 previous errors
diff --git a/src/test/ui/borrowck/borrowck-match-binding-is-assignment.ast.stderr b/src/test/ui/borrowck/borrowck-match-binding-is-assignment.ast.stderr
index e7bd9df..5f43302 100644
--- a/src/test/ui/borrowck/borrowck-match-binding-is-assignment.ast.stderr
+++ b/src/test/ui/borrowck/borrowck-match-binding-is-assignment.ast.stderr
@@ -3,7 +3,7 @@
|
LL | x => {
| - first assignment to `x`
-LL | x += 1; //[ast]~ ERROR cannot assign twice to immutable variable `x`
+LL | x += 1;
| ^^^^^^ cannot assign twice to immutable variable
error[E0384]: cannot assign twice to immutable variable `x`
@@ -11,7 +11,7 @@
|
LL | E::Foo(x) => {
| - first assignment to `x`
-LL | x += 1; //[ast]~ ERROR cannot assign twice to immutable variable `x`
+LL | x += 1;
| ^^^^^^ cannot assign twice to immutable variable
error[E0384]: cannot assign twice to immutable variable `x`
@@ -19,7 +19,7 @@
|
LL | S { bar: x } => {
| - first assignment to `x`
-LL | x += 1; //[ast]~ ERROR cannot assign twice to immutable variable `x`
+LL | x += 1;
| ^^^^^^ cannot assign twice to immutable variable
error[E0384]: cannot assign twice to immutable variable `x`
@@ -27,7 +27,7 @@
|
LL | (x,) => {
| - first assignment to `x`
-LL | x += 1; //[ast]~ ERROR cannot assign twice to immutable variable `x`
+LL | x += 1;
| ^^^^^^ cannot assign twice to immutable variable
error[E0384]: cannot assign twice to immutable variable `x`
@@ -35,7 +35,7 @@
|
LL | [x,_,_] => {
| - first assignment to `x`
-LL | x += 1; //[ast]~ ERROR cannot assign twice to immutable variable `x`
+LL | x += 1;
| ^^^^^^ cannot assign twice to immutable variable
error: aborting due to 5 previous errors
diff --git a/src/test/ui/borrowck/borrowck-match-binding-is-assignment.mir.stderr b/src/test/ui/borrowck/borrowck-match-binding-is-assignment.mir.stderr
index cd88d69..2ac0539 100644
--- a/src/test/ui/borrowck/borrowck-match-binding-is-assignment.mir.stderr
+++ b/src/test/ui/borrowck/borrowck-match-binding-is-assignment.mir.stderr
@@ -6,7 +6,7 @@
| |
| first assignment to `x`
| help: make this binding mutable: `mut x`
-LL | x += 1; //[ast]~ ERROR cannot assign twice to immutable variable `x`
+LL | x += 1;
| ^^^^^^ cannot assign twice to immutable variable
error[E0384]: cannot assign twice to immutable variable `x`
@@ -17,7 +17,7 @@
| |
| first assignment to `x`
| help: make this binding mutable: `mut x`
-LL | x += 1; //[ast]~ ERROR cannot assign twice to immutable variable `x`
+LL | x += 1;
| ^^^^^^ cannot assign twice to immutable variable
error[E0384]: cannot assign twice to immutable variable `x`
@@ -28,7 +28,7 @@
| |
| first assignment to `x`
| help: make this binding mutable: `mut x`
-LL | x += 1; //[ast]~ ERROR cannot assign twice to immutable variable `x`
+LL | x += 1;
| ^^^^^^ cannot assign twice to immutable variable
error[E0384]: cannot assign twice to immutable variable `x`
@@ -39,7 +39,7 @@
| |
| first assignment to `x`
| help: make this binding mutable: `mut x`
-LL | x += 1; //[ast]~ ERROR cannot assign twice to immutable variable `x`
+LL | x += 1;
| ^^^^^^ cannot assign twice to immutable variable
error[E0384]: cannot assign twice to immutable variable `x`
@@ -50,7 +50,7 @@
| |
| first assignment to `x`
| help: make this binding mutable: `mut x`
-LL | x += 1; //[ast]~ ERROR cannot assign twice to immutable variable `x`
+LL | x += 1;
| ^^^^^^ cannot assign twice to immutable variable
error: aborting due to 5 previous errors
diff --git a/src/test/ui/borrowck/borrowck-move-moved-value-into-closure.ast.nll.stderr b/src/test/ui/borrowck/borrowck-move-moved-value-into-closure.ast.nll.stderr
index 0789926..874c38c 100644
--- a/src/test/ui/borrowck/borrowck-move-moved-value-into-closure.ast.nll.stderr
+++ b/src/test/ui/borrowck/borrowck-move-moved-value-into-closure.ast.nll.stderr
@@ -8,7 +8,7 @@
| ------ - variable moved due to use in closure
| |
| value moved into closure here
-LL | call_f(move|| { *t + 1 }); //[ast]~ ERROR capture of moved value
+LL | call_f(move|| { *t + 1 });
| ^^^^^^ - use occurs due to use in closure
| |
| value used here after move
diff --git a/src/test/ui/borrowck/borrowck-move-moved-value-into-closure.ast.stderr b/src/test/ui/borrowck/borrowck-move-moved-value-into-closure.ast.stderr
index 308dac8..48651ee 100644
--- a/src/test/ui/borrowck/borrowck-move-moved-value-into-closure.ast.stderr
+++ b/src/test/ui/borrowck/borrowck-move-moved-value-into-closure.ast.stderr
@@ -3,7 +3,7 @@
|
LL | call_f(move|| { *t + 1 });
| ------ value moved (into closure) here
-LL | call_f(move|| { *t + 1 }); //[ast]~ ERROR capture of moved value
+LL | call_f(move|| { *t + 1 });
| ^ value captured here after move
|
= note: move occurs because `t` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
diff --git a/src/test/ui/borrowck/borrowck-move-moved-value-into-closure.mir.stderr b/src/test/ui/borrowck/borrowck-move-moved-value-into-closure.mir.stderr
index 0789926..874c38c 100644
--- a/src/test/ui/borrowck/borrowck-move-moved-value-into-closure.mir.stderr
+++ b/src/test/ui/borrowck/borrowck-move-moved-value-into-closure.mir.stderr
@@ -8,7 +8,7 @@
| ------ - variable moved due to use in closure
| |
| value moved into closure here
-LL | call_f(move|| { *t + 1 }); //[ast]~ ERROR capture of moved value
+LL | call_f(move|| { *t + 1 });
| ^^^^^^ - use occurs due to use in closure
| |
| value used here after move
diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array.ast.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array.ast.stderr
index f866ff9..88a1ab2 100644
--- a/src/test/ui/borrowck/borrowck-move-out-from-array.ast.stderr
+++ b/src/test/ui/borrowck/borrowck-move-out-from-array.ast.stderr
@@ -3,7 +3,7 @@
|
LL | let [_, _x] = a;
| -- value moved here
-LL | let [.., _y] = a; //[ast]~ ERROR [E0382]
+LL | let [.., _y] = a;
| ^^ value used here after move
|
= note: move occurs because `a[..]` has type `std::boxed::Box<i32>`, which does not implement the `Copy` trait
@@ -13,7 +13,7 @@
|
LL | let [_x, _] = a;
| -- value moved here
-LL | let [_y..] = a; //[ast]~ ERROR [E0382]
+LL | let [_y..] = a;
| ^^ value used here after move
|
= note: move occurs because `a[..]` has type `std::boxed::Box<i32>`, which does not implement the `Copy` trait
diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array.mir.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array.mir.stderr
index f866ff9..88a1ab2 100644
--- a/src/test/ui/borrowck/borrowck-move-out-from-array.mir.stderr
+++ b/src/test/ui/borrowck/borrowck-move-out-from-array.mir.stderr
@@ -3,7 +3,7 @@
|
LL | let [_, _x] = a;
| -- value moved here
-LL | let [.., _y] = a; //[ast]~ ERROR [E0382]
+LL | let [.., _y] = a;
| ^^ value used here after move
|
= note: move occurs because `a[..]` has type `std::boxed::Box<i32>`, which does not implement the `Copy` trait
@@ -13,7 +13,7 @@
|
LL | let [_x, _] = a;
| -- value moved here
-LL | let [_y..] = a; //[ast]~ ERROR [E0382]
+LL | let [_y..] = a;
| ^^ value used here after move
|
= note: move occurs because `a[..]` has type `std::boxed::Box<i32>`, which does not implement the `Copy` trait
diff --git a/src/test/ui/borrowck/borrowck-move-out-of-static-item.ast.stderr b/src/test/ui/borrowck/borrowck-move-out-of-static-item.ast.stderr
index 752d533..26d06c0 100644
--- a/src/test/ui/borrowck/borrowck-move-out-of-static-item.ast.stderr
+++ b/src/test/ui/borrowck/borrowck-move-out-of-static-item.ast.stderr
@@ -1,7 +1,7 @@
error[E0507]: cannot move out of static item
--> $DIR/borrowck-move-out-of-static-item.rs:18:10
|
-LL | test(BAR); //[ast]~ ERROR cannot move out of static item [E0507]
+LL | test(BAR);
| ^^^ cannot move out of static item
error: aborting due to previous error
diff --git a/src/test/ui/borrowck/borrowck-move-out-of-static-item.mir.stderr b/src/test/ui/borrowck/borrowck-move-out-of-static-item.mir.stderr
index 752d533..26d06c0 100644
--- a/src/test/ui/borrowck/borrowck-move-out-of-static-item.mir.stderr
+++ b/src/test/ui/borrowck/borrowck-move-out-of-static-item.mir.stderr
@@ -1,7 +1,7 @@
error[E0507]: cannot move out of static item
--> $DIR/borrowck-move-out-of-static-item.rs:18:10
|
-LL | test(BAR); //[ast]~ ERROR cannot move out of static item [E0507]
+LL | test(BAR);
| ^^^ cannot move out of static item
error: aborting due to previous error
diff --git a/src/test/ui/borrowck/borrowck-move-out-of-struct-with-dtor.ast.nll.stderr b/src/test/ui/borrowck/borrowck-move-out-of-struct-with-dtor.ast.nll.stderr
index 7025ce0..c1c04ca 100644
--- a/src/test/ui/borrowck/borrowck-move-out-of-struct-with-dtor.ast.nll.stderr
+++ b/src/test/ui/borrowck/borrowck-move-out-of-struct-with-dtor.ast.nll.stderr
@@ -3,7 +3,7 @@
|
LL | match (S {f:"foo".to_string()}) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of here
-LL | //[mir]~^ ERROR [E0509]
+LL |
LL | S {f:_s} => {}
| -- data moved here
|
diff --git a/src/test/ui/borrowck/borrowck-move-out-of-struct-with-dtor.mir.stderr b/src/test/ui/borrowck/borrowck-move-out-of-struct-with-dtor.mir.stderr
index 7025ce0..c1c04ca 100644
--- a/src/test/ui/borrowck/borrowck-move-out-of-struct-with-dtor.mir.stderr
+++ b/src/test/ui/borrowck/borrowck-move-out-of-struct-with-dtor.mir.stderr
@@ -3,7 +3,7 @@
|
LL | match (S {f:"foo".to_string()}) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of here
-LL | //[mir]~^ ERROR [E0509]
+LL |
LL | S {f:_s} => {}
| -- data moved here
|
diff --git a/src/test/ui/borrowck/borrowck-mut-borrow-linear-errors.ast.nll.stderr b/src/test/ui/borrowck/borrowck-mut-borrow-linear-errors.ast.nll.stderr
index 0f07776..a6e7d74 100644
--- a/src/test/ui/borrowck/borrowck-mut-borrow-linear-errors.ast.nll.stderr
+++ b/src/test/ui/borrowck/borrowck-mut-borrow-linear-errors.ast.nll.stderr
@@ -1,30 +1,30 @@
error[E0499]: cannot borrow `x` as mutable more than once at a time
--> $DIR/borrowck-mut-borrow-linear-errors.rs:13:30
|
-LL | 1 => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
+LL | 1 => { addr.push(&mut x); }
| ---- ^^^^^^ second mutable borrow occurs here
| |
| first borrow later used here
...
-LL | _ => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
+LL | _ => { addr.push(&mut x); }
| ------ first mutable borrow occurs here
error[E0499]: cannot borrow `x` as mutable more than once at a time
--> $DIR/borrowck-mut-borrow-linear-errors.rs:15:30
|
-LL | 1 => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
+LL | 1 => { addr.push(&mut x); }
| ---- first borrow later used here
-LL | //[mir]~^ ERROR [E0499]
-LL | 2 => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
+LL |
+LL | 2 => { addr.push(&mut x); }
| ^^^^^^ second mutable borrow occurs here
-LL | //[mir]~^ ERROR [E0499]
-LL | _ => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
+LL |
+LL | _ => { addr.push(&mut x); }
| ------ first mutable borrow occurs here
error[E0499]: cannot borrow `x` as mutable more than once at a time
--> $DIR/borrowck-mut-borrow-linear-errors.rs:17:30
|
-LL | _ => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
+LL | _ => { addr.push(&mut x); }
| ^^^^^^ mutable borrow starts here in previous iteration of loop
error: aborting due to 3 previous errors
diff --git a/src/test/ui/borrowck/borrowck-mut-borrow-linear-errors.ast.stderr b/src/test/ui/borrowck/borrowck-mut-borrow-linear-errors.ast.stderr
index dafb60c..cee61db 100644
--- a/src/test/ui/borrowck/borrowck-mut-borrow-linear-errors.ast.stderr
+++ b/src/test/ui/borrowck/borrowck-mut-borrow-linear-errors.ast.stderr
@@ -1,7 +1,7 @@
error[E0499]: cannot borrow `x` as mutable more than once at a time
--> $DIR/borrowck-mut-borrow-linear-errors.rs:13:35
|
-LL | 1 => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
+LL | 1 => { addr.push(&mut x); }
| ^ mutable borrow starts here in previous iteration of loop
...
LL | }
@@ -10,10 +10,10 @@
error[E0499]: cannot borrow `x` as mutable more than once at a time
--> $DIR/borrowck-mut-borrow-linear-errors.rs:15:35
|
-LL | 1 => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
+LL | 1 => { addr.push(&mut x); }
| - first mutable borrow occurs here
-LL | //[mir]~^ ERROR [E0499]
-LL | 2 => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
+LL |
+LL | 2 => { addr.push(&mut x); }
| ^ second mutable borrow occurs here
...
LL | }
@@ -22,10 +22,10 @@
error[E0499]: cannot borrow `x` as mutable more than once at a time
--> $DIR/borrowck-mut-borrow-linear-errors.rs:17:35
|
-LL | 1 => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
+LL | 1 => { addr.push(&mut x); }
| - first mutable borrow occurs here
...
-LL | _ => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
+LL | _ => { addr.push(&mut x); }
| ^ second mutable borrow occurs here
...
LL | }
diff --git a/src/test/ui/borrowck/borrowck-mut-borrow-linear-errors.mir.stderr b/src/test/ui/borrowck/borrowck-mut-borrow-linear-errors.mir.stderr
index 0f07776..a6e7d74 100644
--- a/src/test/ui/borrowck/borrowck-mut-borrow-linear-errors.mir.stderr
+++ b/src/test/ui/borrowck/borrowck-mut-borrow-linear-errors.mir.stderr
@@ -1,30 +1,30 @@
error[E0499]: cannot borrow `x` as mutable more than once at a time
--> $DIR/borrowck-mut-borrow-linear-errors.rs:13:30
|
-LL | 1 => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
+LL | 1 => { addr.push(&mut x); }
| ---- ^^^^^^ second mutable borrow occurs here
| |
| first borrow later used here
...
-LL | _ => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
+LL | _ => { addr.push(&mut x); }
| ------ first mutable borrow occurs here
error[E0499]: cannot borrow `x` as mutable more than once at a time
--> $DIR/borrowck-mut-borrow-linear-errors.rs:15:30
|
-LL | 1 => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
+LL | 1 => { addr.push(&mut x); }
| ---- first borrow later used here
-LL | //[mir]~^ ERROR [E0499]
-LL | 2 => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
+LL |
+LL | 2 => { addr.push(&mut x); }
| ^^^^^^ second mutable borrow occurs here
-LL | //[mir]~^ ERROR [E0499]
-LL | _ => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
+LL |
+LL | _ => { addr.push(&mut x); }
| ------ first mutable borrow occurs here
error[E0499]: cannot borrow `x` as mutable more than once at a time
--> $DIR/borrowck-mut-borrow-linear-errors.rs:17:30
|
-LL | _ => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
+LL | _ => { addr.push(&mut x); }
| ^^^^^^ mutable borrow starts here in previous iteration of loop
error: aborting due to 3 previous errors
diff --git a/src/test/ui/borrowck/borrowck-pat-reassign-binding.ast.nll.stderr b/src/test/ui/borrowck/borrowck-pat-reassign-binding.ast.nll.stderr
index d65ba12..f0e1683 100644
--- a/src/test/ui/borrowck/borrowck-pat-reassign-binding.ast.nll.stderr
+++ b/src/test/ui/borrowck/borrowck-pat-reassign-binding.ast.nll.stderr
@@ -4,9 +4,9 @@
LL | Some(ref i) => {
| ----- borrow of `x` occurs here
LL | // But on this branch, `i` is an outstanding borrow
-LL | x = Some(*i+1); //[ast]~ ERROR cannot assign to `x`
+LL | x = Some(*i+1);
| ^^^^^^^^^^^^^^ assignment to borrowed `x` occurs here
-LL | //[mir]~^ ERROR cannot assign to `x` because it is borrowed
+LL |
LL | drop(i);
| - borrow later used here
diff --git a/src/test/ui/borrowck/borrowck-pat-reassign-binding.ast.stderr b/src/test/ui/borrowck/borrowck-pat-reassign-binding.ast.stderr
index 207f971..d7bce40 100644
--- a/src/test/ui/borrowck/borrowck-pat-reassign-binding.ast.stderr
+++ b/src/test/ui/borrowck/borrowck-pat-reassign-binding.ast.stderr
@@ -4,7 +4,7 @@
LL | Some(ref i) => {
| ----- borrow of `x` occurs here
LL | // But on this branch, `i` is an outstanding borrow
-LL | x = Some(*i+1); //[ast]~ ERROR cannot assign to `x`
+LL | x = Some(*i+1);
| ^^^^^^^^^^^^^^ assignment to borrowed `x` occurs here
error: aborting due to previous error
diff --git a/src/test/ui/borrowck/borrowck-pat-reassign-binding.mir.stderr b/src/test/ui/borrowck/borrowck-pat-reassign-binding.mir.stderr
index d65ba12..f0e1683 100644
--- a/src/test/ui/borrowck/borrowck-pat-reassign-binding.mir.stderr
+++ b/src/test/ui/borrowck/borrowck-pat-reassign-binding.mir.stderr
@@ -4,9 +4,9 @@
LL | Some(ref i) => {
| ----- borrow of `x` occurs here
LL | // But on this branch, `i` is an outstanding borrow
-LL | x = Some(*i+1); //[ast]~ ERROR cannot assign to `x`
+LL | x = Some(*i+1);
| ^^^^^^^^^^^^^^ assignment to borrowed `x` occurs here
-LL | //[mir]~^ ERROR cannot assign to `x` because it is borrowed
+LL |
LL | drop(i);
| - borrow later used here
diff --git a/src/test/ui/borrowck/borrowck-thread-local-static-borrow-outlives-fn.ast.nll.stderr b/src/test/ui/borrowck/borrowck-thread-local-static-borrow-outlives-fn.ast.nll.stderr
index 34d08a0..d2b6e06 100644
--- a/src/test/ui/borrowck/borrowck-thread-local-static-borrow-outlives-fn.ast.nll.stderr
+++ b/src/test/ui/borrowck/borrowck-thread-local-static-borrow-outlives-fn.ast.nll.stderr
@@ -1,9 +1,9 @@
error[E0712]: thread-local variable borrowed past end of function
--> $DIR/borrowck-thread-local-static-borrow-outlives-fn.rs:11:20
|
-LL | assert_static(&FOO); //[ast]~ ERROR [E0597]
+LL | assert_static(&FOO);
| ^^^^ thread-local variables cannot be borrowed beyond the end of the function
-LL | //[mir]~^ ERROR [E0712]
+LL |
LL | }
| - end of enclosing function is here
diff --git a/src/test/ui/borrowck/borrowck-thread-local-static-borrow-outlives-fn.ast.stderr b/src/test/ui/borrowck/borrowck-thread-local-static-borrow-outlives-fn.ast.stderr
index 4724f17..ce7b5e6 100644
--- a/src/test/ui/borrowck/borrowck-thread-local-static-borrow-outlives-fn.ast.stderr
+++ b/src/test/ui/borrowck/borrowck-thread-local-static-borrow-outlives-fn.ast.stderr
@@ -1,7 +1,7 @@
error[E0597]: borrowed value does not live long enough
--> $DIR/borrowck-thread-local-static-borrow-outlives-fn.rs:11:21
|
-LL | assert_static(&FOO); //[ast]~ ERROR [E0597]
+LL | assert_static(&FOO);
| ^^^ - borrowed value only lives until here
| |
| borrowed value does not live long enough
diff --git a/src/test/ui/borrowck/borrowck-thread-local-static-borrow-outlives-fn.mir.stderr b/src/test/ui/borrowck/borrowck-thread-local-static-borrow-outlives-fn.mir.stderr
index 34d08a0..d2b6e06 100644
--- a/src/test/ui/borrowck/borrowck-thread-local-static-borrow-outlives-fn.mir.stderr
+++ b/src/test/ui/borrowck/borrowck-thread-local-static-borrow-outlives-fn.mir.stderr
@@ -1,9 +1,9 @@
error[E0712]: thread-local variable borrowed past end of function
--> $DIR/borrowck-thread-local-static-borrow-outlives-fn.rs:11:20
|
-LL | assert_static(&FOO); //[ast]~ ERROR [E0597]
+LL | assert_static(&FOO);
| ^^^^ thread-local variables cannot be borrowed beyond the end of the function
-LL | //[mir]~^ ERROR [E0712]
+LL |
LL | }
| - end of enclosing function is here
diff --git a/src/test/ui/borrowck/borrowck-unary-move.ast.nll.stderr b/src/test/ui/borrowck/borrowck-unary-move.ast.nll.stderr
index 53dc6a7..c29ff53 100644
--- a/src/test/ui/borrowck/borrowck-unary-move.ast.nll.stderr
+++ b/src/test/ui/borrowck/borrowck-unary-move.ast.nll.stderr
@@ -3,9 +3,9 @@
|
LL | let y = &*x;
| --- borrow of `*x` occurs here
-LL | free(x); //[ast]~ ERROR cannot move out of `x` because it is borrowed
+LL | free(x);
| ^ move out of `x` occurs here
-LL | //[mir]~^ ERROR cannot move out of `x` because it is borrowed
+LL |
LL | *y
| -- borrow later used here
diff --git a/src/test/ui/borrowck/borrowck-unary-move.ast.stderr b/src/test/ui/borrowck/borrowck-unary-move.ast.stderr
index 9383298..e05b110 100644
--- a/src/test/ui/borrowck/borrowck-unary-move.ast.stderr
+++ b/src/test/ui/borrowck/borrowck-unary-move.ast.stderr
@@ -3,7 +3,7 @@
|
LL | let y = &*x;
| -- borrow of `*x` occurs here
-LL | free(x); //[ast]~ ERROR cannot move out of `x` because it is borrowed
+LL | free(x);
| ^ move out of `x` occurs here
error: aborting due to previous error
diff --git a/src/test/ui/borrowck/borrowck-unary-move.mir.stderr b/src/test/ui/borrowck/borrowck-unary-move.mir.stderr
index 53dc6a7..c29ff53 100644
--- a/src/test/ui/borrowck/borrowck-unary-move.mir.stderr
+++ b/src/test/ui/borrowck/borrowck-unary-move.mir.stderr
@@ -3,9 +3,9 @@
|
LL | let y = &*x;
| --- borrow of `*x` occurs here
-LL | free(x); //[ast]~ ERROR cannot move out of `x` because it is borrowed
+LL | free(x);
| ^ move out of `x` occurs here
-LL | //[mir]~^ ERROR cannot move out of `x` because it is borrowed
+LL |
LL | *y
| -- borrow later used here
diff --git a/src/test/ui/borrowck/borrowck-uninit-field-access.ast.nll.stderr b/src/test/ui/borrowck/borrowck-uninit-field-access.ast.nll.stderr
index 99cbf64..a6e5f0b 100644
--- a/src/test/ui/borrowck/borrowck-uninit-field-access.ast.nll.stderr
+++ b/src/test/ui/borrowck/borrowck-uninit-field-access.ast.nll.stderr
@@ -1,7 +1,7 @@
error[E0381]: use of possibly uninitialized variable: `a`
--> $DIR/borrowck-uninit-field-access.rs:24:13
|
-LL | let _ = a.x + 1; //[ast]~ ERROR use of possibly uninitialized variable: `a.x`
+LL | let _ = a.x + 1;
| ^^^ use of possibly uninitialized `a.x`
error[E0382]: use of moved value: `line1.origin`
@@ -9,7 +9,7 @@
|
LL | let _moved = line1.origin;
| ------------ value moved here
-LL | let _ = line1.origin.x + 1; //[ast]~ ERROR use of moved value: `line1.origin.x`
+LL | let _ = line1.origin.x + 1;
| ^^^^^^^^^^^^^^ value used here after move
|
= note: move occurs because `line1.origin` has type `Point`, which does not implement the `Copy` trait
@@ -19,7 +19,7 @@
|
LL | let _moved = (line2.origin, line2.middle);
| ------------ value moved here
-LL | line2.consume(); //[ast]~ ERROR use of partially moved value: `line2` [E0382]
+LL | line2.consume();
| ^^^^^ value used here after partial move
|
= note: move occurs because `line2.middle` has type `Point`, which does not implement the `Copy` trait
diff --git a/src/test/ui/borrowck/borrowck-uninit-field-access.ast.stderr b/src/test/ui/borrowck/borrowck-uninit-field-access.ast.stderr
index 8c05272..58fc1d4 100644
--- a/src/test/ui/borrowck/borrowck-uninit-field-access.ast.stderr
+++ b/src/test/ui/borrowck/borrowck-uninit-field-access.ast.stderr
@@ -1,7 +1,7 @@
error[E0381]: use of possibly uninitialized variable: `a.x`
--> $DIR/borrowck-uninit-field-access.rs:24:13
|
-LL | let _ = a.x + 1; //[ast]~ ERROR use of possibly uninitialized variable: `a.x`
+LL | let _ = a.x + 1;
| ^^^ use of possibly uninitialized `a.x`
error[E0382]: use of moved value: `line1.origin.x`
@@ -9,7 +9,7 @@
|
LL | let _moved = line1.origin;
| ------ value moved here
-LL | let _ = line1.origin.x + 1; //[ast]~ ERROR use of moved value: `line1.origin.x`
+LL | let _ = line1.origin.x + 1;
| ^^^^^^^^^^^^^^ value used here after move
|
= note: move occurs because `line1.origin` has type `Point`, which does not implement the `Copy` trait
@@ -19,7 +19,7 @@
|
LL | let _moved = (line2.origin, line2.middle);
| ------------ value moved here
-LL | line2.consume(); //[ast]~ ERROR use of partially moved value: `line2` [E0382]
+LL | line2.consume();
| ^^^^^ value used here after move
|
= note: move occurs because `line2.origin` has type `Point`, which does not implement the `Copy` trait
diff --git a/src/test/ui/borrowck/borrowck-uninit-field-access.mir.stderr b/src/test/ui/borrowck/borrowck-uninit-field-access.mir.stderr
index 99cbf64..a6e5f0b 100644
--- a/src/test/ui/borrowck/borrowck-uninit-field-access.mir.stderr
+++ b/src/test/ui/borrowck/borrowck-uninit-field-access.mir.stderr
@@ -1,7 +1,7 @@
error[E0381]: use of possibly uninitialized variable: `a`
--> $DIR/borrowck-uninit-field-access.rs:24:13
|
-LL | let _ = a.x + 1; //[ast]~ ERROR use of possibly uninitialized variable: `a.x`
+LL | let _ = a.x + 1;
| ^^^ use of possibly uninitialized `a.x`
error[E0382]: use of moved value: `line1.origin`
@@ -9,7 +9,7 @@
|
LL | let _moved = line1.origin;
| ------------ value moved here
-LL | let _ = line1.origin.x + 1; //[ast]~ ERROR use of moved value: `line1.origin.x`
+LL | let _ = line1.origin.x + 1;
| ^^^^^^^^^^^^^^ value used here after move
|
= note: move occurs because `line1.origin` has type `Point`, which does not implement the `Copy` trait
@@ -19,7 +19,7 @@
|
LL | let _moved = (line2.origin, line2.middle);
| ------------ value moved here
-LL | line2.consume(); //[ast]~ ERROR use of partially moved value: `line2` [E0382]
+LL | line2.consume();
| ^^^^^ value used here after partial move
|
= note: move occurs because `line2.middle` has type `Point`, which does not implement the `Copy` trait
diff --git a/src/test/ui/borrowck/borrowck-uninit-ref-chain.ast.nll.stderr b/src/test/ui/borrowck/borrowck-uninit-ref-chain.ast.nll.stderr
index 7687176..a5cf59c 100644
--- a/src/test/ui/borrowck/borrowck-uninit-ref-chain.ast.nll.stderr
+++ b/src/test/ui/borrowck/borrowck-uninit-ref-chain.ast.nll.stderr
@@ -1,43 +1,43 @@
error[E0381]: borrow of possibly uninitialized variable: `x`
--> $DIR/borrowck-uninit-ref-chain.rs:11:14
|
-LL | let _y = &**x; //[ast]~ ERROR use of possibly uninitialized variable: `**x` [E0381]
+LL | let _y = &**x;
| ^^^^ use of possibly uninitialized `**x`
error[E0381]: borrow of possibly uninitialized variable: `x`
--> $DIR/borrowck-uninit-ref-chain.rs:15:14
|
-LL | let _y = &**x; //[ast]~ ERROR use of possibly uninitialized variable: `**x` [E0381]
+LL | let _y = &**x;
| ^^^^ use of possibly uninitialized `**x`
error[E0381]: borrow of possibly uninitialized variable: `x`
--> $DIR/borrowck-uninit-ref-chain.rs:19:14
|
-LL | let _y = &**x; //[ast]~ ERROR use of possibly uninitialized variable: `**x` [E0381]
+LL | let _y = &**x;
| ^^^^ use of possibly uninitialized `**x`
error[E0381]: assign to part of possibly uninitialized variable: `a`
--> $DIR/borrowck-uninit-ref-chain.rs:24:5
|
-LL | a.x = 0; //[mir]~ ERROR assign to part of possibly uninitialized variable: `a` [E0381]
+LL | a.x = 0;
| ^^^^^^^ use of possibly uninitialized `a`
error[E0381]: assign to part of possibly uninitialized variable: `a`
--> $DIR/borrowck-uninit-ref-chain.rs:29:5
|
-LL | a.x = &&0; //[mir]~ ERROR assign to part of possibly uninitialized variable: `a` [E0381]
+LL | a.x = &&0;
| ^^^^^^^^^ use of possibly uninitialized `a`
error[E0381]: assign to part of possibly uninitialized variable: `a`
--> $DIR/borrowck-uninit-ref-chain.rs:35:5
|
-LL | a.x = 0; //[mir]~ ERROR assign to part of possibly uninitialized variable: `a` [E0381]
+LL | a.x = 0;
| ^^^^^^^ use of possibly uninitialized `a`
error[E0381]: assign to part of possibly uninitialized variable: `a`
--> $DIR/borrowck-uninit-ref-chain.rs:40:5
|
-LL | a.x = &&0; //[mir]~ assign to part of possibly uninitialized variable: `a` [E0381]
+LL | a.x = &&0;
| ^^^^^^^^^ use of possibly uninitialized `a`
error: aborting due to 7 previous errors
diff --git a/src/test/ui/borrowck/borrowck-uninit-ref-chain.ast.stderr b/src/test/ui/borrowck/borrowck-uninit-ref-chain.ast.stderr
index e8ebf8c..8cb3f3b 100644
--- a/src/test/ui/borrowck/borrowck-uninit-ref-chain.ast.stderr
+++ b/src/test/ui/borrowck/borrowck-uninit-ref-chain.ast.stderr
@@ -1,43 +1,43 @@
error[E0381]: use of possibly uninitialized variable: `**x`
--> $DIR/borrowck-uninit-ref-chain.rs:11:15
|
-LL | let _y = &**x; //[ast]~ ERROR use of possibly uninitialized variable: `**x` [E0381]
+LL | let _y = &**x;
| ^^^ use of possibly uninitialized `**x`
error[E0381]: use of possibly uninitialized variable: `**x`
--> $DIR/borrowck-uninit-ref-chain.rs:15:15
|
-LL | let _y = &**x; //[ast]~ ERROR use of possibly uninitialized variable: `**x` [E0381]
+LL | let _y = &**x;
| ^^^ use of possibly uninitialized `**x`
error[E0381]: use of possibly uninitialized variable: `**x`
--> $DIR/borrowck-uninit-ref-chain.rs:19:15
|
-LL | let _y = &**x; //[ast]~ ERROR use of possibly uninitialized variable: `**x` [E0381]
+LL | let _y = &**x;
| ^^^ use of possibly uninitialized `**x`
error[E0381]: use of possibly uninitialized variable: `a.x`
--> $DIR/borrowck-uninit-ref-chain.rs:25:15
|
-LL | let _b = &a.x; //[ast]~ ERROR use of possibly uninitialized variable: `a.x` [E0381]
+LL | let _b = &a.x;
| ^^^ use of possibly uninitialized `a.x`
error[E0381]: use of possibly uninitialized variable: `**a.x`
--> $DIR/borrowck-uninit-ref-chain.rs:30:15
|
-LL | let _b = &**a.x; //[ast]~ ERROR use of possibly uninitialized variable: `**a.x` [E0381]
+LL | let _b = &**a.x;
| ^^^^^ use of possibly uninitialized `**a.x`
error[E0381]: use of possibly uninitialized variable: `a.y`
--> $DIR/borrowck-uninit-ref-chain.rs:36:15
|
-LL | let _b = &a.y; //[ast]~ ERROR use of possibly uninitialized variable: `a.y` [E0381]
+LL | let _b = &a.y;
| ^^^ use of possibly uninitialized `a.y`
error[E0381]: use of possibly uninitialized variable: `**a.y`
--> $DIR/borrowck-uninit-ref-chain.rs:41:15
|
-LL | let _b = &**a.y; //[ast]~ ERROR use of possibly uninitialized variable: `**a.y` [E0381]
+LL | let _b = &**a.y;
| ^^^^^ use of possibly uninitialized `**a.y`
error: aborting due to 7 previous errors
diff --git a/src/test/ui/borrowck/borrowck-uninit-ref-chain.mir.stderr b/src/test/ui/borrowck/borrowck-uninit-ref-chain.mir.stderr
index 7687176..a5cf59c 100644
--- a/src/test/ui/borrowck/borrowck-uninit-ref-chain.mir.stderr
+++ b/src/test/ui/borrowck/borrowck-uninit-ref-chain.mir.stderr
@@ -1,43 +1,43 @@
error[E0381]: borrow of possibly uninitialized variable: `x`
--> $DIR/borrowck-uninit-ref-chain.rs:11:14
|
-LL | let _y = &**x; //[ast]~ ERROR use of possibly uninitialized variable: `**x` [E0381]
+LL | let _y = &**x;
| ^^^^ use of possibly uninitialized `**x`
error[E0381]: borrow of possibly uninitialized variable: `x`
--> $DIR/borrowck-uninit-ref-chain.rs:15:14
|
-LL | let _y = &**x; //[ast]~ ERROR use of possibly uninitialized variable: `**x` [E0381]
+LL | let _y = &**x;
| ^^^^ use of possibly uninitialized `**x`
error[E0381]: borrow of possibly uninitialized variable: `x`
--> $DIR/borrowck-uninit-ref-chain.rs:19:14
|
-LL | let _y = &**x; //[ast]~ ERROR use of possibly uninitialized variable: `**x` [E0381]
+LL | let _y = &**x;
| ^^^^ use of possibly uninitialized `**x`
error[E0381]: assign to part of possibly uninitialized variable: `a`
--> $DIR/borrowck-uninit-ref-chain.rs:24:5
|
-LL | a.x = 0; //[mir]~ ERROR assign to part of possibly uninitialized variable: `a` [E0381]
+LL | a.x = 0;
| ^^^^^^^ use of possibly uninitialized `a`
error[E0381]: assign to part of possibly uninitialized variable: `a`
--> $DIR/borrowck-uninit-ref-chain.rs:29:5
|
-LL | a.x = &&0; //[mir]~ ERROR assign to part of possibly uninitialized variable: `a` [E0381]
+LL | a.x = &&0;
| ^^^^^^^^^ use of possibly uninitialized `a`
error[E0381]: assign to part of possibly uninitialized variable: `a`
--> $DIR/borrowck-uninit-ref-chain.rs:35:5
|
-LL | a.x = 0; //[mir]~ ERROR assign to part of possibly uninitialized variable: `a` [E0381]
+LL | a.x = 0;
| ^^^^^^^ use of possibly uninitialized `a`
error[E0381]: assign to part of possibly uninitialized variable: `a`
--> $DIR/borrowck-uninit-ref-chain.rs:40:5
|
-LL | a.x = &&0; //[mir]~ assign to part of possibly uninitialized variable: `a` [E0381]
+LL | a.x = &&0;
| ^^^^^^^^^ use of possibly uninitialized `a`
error: aborting due to 7 previous errors
diff --git a/src/test/ui/borrowck/borrowck-union-borrow.mir.stderr b/src/test/ui/borrowck/borrowck-union-borrow.mir.stderr
deleted file mode 100644
index 1a2433c..0000000
--- a/src/test/ui/borrowck/borrowck-union-borrow.mir.stderr
+++ /dev/null
@@ -1,136 +0,0 @@
-error[E0502]: cannot borrow `u.a` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-union-borrow.rs:27:23
- |
-LL | let ra = &u.a;
- | ---- immutable borrow occurs here
-LL | let rma = &mut u.a; //[ast]~ ERROR cannot borrow `u.a` as mutable because it is also borrowed as immutable
- | ^^^^^^^^ mutable borrow occurs here
-LL | //[mir]~^ ERROR cannot borrow `u.a` as mutable because it is also borrowed as immutable
-LL | drop(ra);
- | -- immutable borrow later used here
-
-error[E0506]: cannot assign to `u.a` because it is borrowed
- --> $DIR/borrowck-union-borrow.rs:33:13
- |
-LL | let ra = &u.a;
- | ---- borrow of `u.a` occurs here
-LL | u.a = 1; //[ast]~ ERROR cannot assign to `u.a` because it is borrowed
- | ^^^^^^^ assignment to borrowed `u.a` occurs here
-LL | //[mir]~^ ERROR cannot assign to `u.a` because it is borrowed
-LL | drop(ra);
- | -- borrow later used here
-
-error[E0502]: cannot borrow `u.b` as mutable because it is also borrowed as immutable
- --> $DIR/borrowck-union-borrow.rs:50:23
- |
-LL | let ra = &u.a;
- | ---- immutable borrow occurs here
-LL | let rmb = &mut u.b; //[ast]~ ERROR cannot borrow `u` (via `u.b`) as mutable because `u` is also borrowed as immutable (via `u.a`)
- | ^^^^^^^^ mutable borrow occurs here
-LL | //[mir]~^ ERROR cannot borrow `u.b` as mutable because it is also borrowed as immutable
-LL | drop(ra);
- | -- immutable borrow later used here
-
-error[E0506]: cannot assign to `u.b` because it is borrowed
- --> $DIR/borrowck-union-borrow.rs:56:13
- |
-LL | let ra = &u.a;
- | ---- borrow of `u.b` occurs here
-LL | u.b = 1; //[ast]~ ERROR cannot assign to `u.b` because it is borrowed
- | ^^^^^^^ assignment to borrowed `u.b` occurs here
-LL | //[mir]~^ ERROR cannot assign to `u.b` because it is borrowed
-LL | drop(ra);
- | -- borrow later used here
-
-error[E0502]: cannot borrow `u.a` as immutable because it is also borrowed as mutable
- --> $DIR/borrowck-union-borrow.rs:63:22
- |
-LL | let rma = &mut u.a;
- | -------- mutable borrow occurs here
-LL | let ra = &u.a; //[ast]~ ERROR cannot borrow `u.a` as immutable because it is also borrowed as mutable
- | ^^^^ immutable borrow occurs here
-LL | //[mir]~^ ERROR cannot borrow `u.a` as immutable because it is also borrowed as mutable
-LL | drop(rma);
- | --- mutable borrow later used here
-
-error[E0503]: cannot use `u.a` because it was mutably borrowed
- --> $DIR/borrowck-union-borrow.rs:69:21
- |
-LL | let ra = &mut u.a;
- | -------- borrow of `u.a` occurs here
-LL | let a = u.a; //[ast]~ ERROR cannot use `u.a` because it was mutably borrowed
- | ^^^ use of borrowed `u.a`
-LL | //[mir]~^ ERROR cannot use `u.a` because it was mutably borrowed
-LL | drop(ra);
- | -- borrow later used here
-
-error[E0499]: cannot borrow `u.a` as mutable more than once at a time
- --> $DIR/borrowck-union-borrow.rs:75:24
- |
-LL | let rma = &mut u.a;
- | -------- first mutable borrow occurs here
-LL | let rma2 = &mut u.a; //[ast]~ ERROR cannot borrow `u.a` as mutable more than once at a time
- | ^^^^^^^^ second mutable borrow occurs here
-LL | //[mir]~^ ERROR cannot borrow `u.a` as mutable more than once at a time
-LL | drop(rma);
- | --- first borrow later used here
-
-error[E0506]: cannot assign to `u.a` because it is borrowed
- --> $DIR/borrowck-union-borrow.rs:81:13
- |
-LL | let rma = &mut u.a;
- | -------- borrow of `u.a` occurs here
-LL | u.a = 1; //[ast]~ ERROR cannot assign to `u.a` because it is borrowed
- | ^^^^^^^ assignment to borrowed `u.a` occurs here
-LL | //[mir]~^ ERROR cannot assign to `u.a` because it is borrowed
-LL | drop(rma);
- | --- borrow later used here
-
-error[E0502]: cannot borrow `u.b` as immutable because it is also borrowed as mutable
- --> $DIR/borrowck-union-borrow.rs:88:22
- |
-LL | let rma = &mut u.a;
- | -------- mutable borrow occurs here
-LL | let rb = &u.b; //[ast]~ ERROR cannot borrow `u` (via `u.b`) as immutable because `u` is also borrowed as mutable (via `u.a`)
- | ^^^^ immutable borrow occurs here
-LL | //[mir]~^ ERROR cannot borrow `u.b` as immutable because it is also borrowed as mutable
-LL | drop(rma);
- | --- mutable borrow later used here
-
-error[E0503]: cannot use `u.b` because it was mutably borrowed
- --> $DIR/borrowck-union-borrow.rs:94:21
- |
-LL | let ra = &mut u.a;
- | -------- borrow of `u.a` occurs here
-LL | let b = u.b; //[ast]~ ERROR cannot use `u.b` because it was mutably borrowed
- | ^^^ use of borrowed `u.a`
-...
-LL | drop(ra);
- | -- borrow later used here
-
-error[E0499]: cannot borrow `u.b` as mutable more than once at a time
- --> $DIR/borrowck-union-borrow.rs:101:24
- |
-LL | let rma = &mut u.a;
- | -------- first mutable borrow occurs here
-LL | let rmb2 = &mut u.b; //[ast]~ ERROR cannot borrow `u` (via `u.b`) as mutable more than once at a time
- | ^^^^^^^^ second mutable borrow occurs here
-LL | //[mir]~^ ERROR cannot borrow `u.b` as mutable more than once at a time
-LL | drop(rma);
- | --- first borrow later used here
-
-error[E0506]: cannot assign to `u.b` because it is borrowed
- --> $DIR/borrowck-union-borrow.rs:107:13
- |
-LL | let rma = &mut u.a;
- | -------- borrow of `u.b` occurs here
-LL | u.b = 1; //[ast]~ ERROR cannot assign to `u.b` because it is borrowed
- | ^^^^^^^ assignment to borrowed `u.b` occurs here
-LL | //[mir]~^ ERROR cannot assign to `u.b` because it is borrowed
-LL | drop(rma);
- | --- borrow later used here
-
-error: aborting due to 12 previous errors
-
-Some errors occurred: E0499, E0502, E0503, E0506.
-For more information about an error, try `rustc --explain E0499`.
diff --git a/src/test/ui/borrowck/borrowck-use-in-index-lvalue.ast.nll.stderr b/src/test/ui/borrowck/borrowck-use-in-index-lvalue.ast.nll.stderr
index 1819123..c5e4f89 100644
--- a/src/test/ui/borrowck/borrowck-use-in-index-lvalue.ast.nll.stderr
+++ b/src/test/ui/borrowck/borrowck-use-in-index-lvalue.ast.nll.stderr
@@ -1,13 +1,13 @@
error[E0381]: use of possibly uninitialized variable: `w`
--> $DIR/borrowck-use-in-index-lvalue.rs:6:5
|
-LL | w[5] = 0; //[ast]~ ERROR use of possibly uninitialized variable: `*w` [E0381]
+LL | w[5] = 0;
| ^^^^ use of possibly uninitialized `*w`
error[E0381]: use of possibly uninitialized variable: `w`
--> $DIR/borrowck-use-in-index-lvalue.rs:10:5
|
-LL | w[5] = 0; //[ast]~ ERROR use of possibly uninitialized variable: `*w` [E0381]
+LL | w[5] = 0;
| ^^^^ use of possibly uninitialized `*w`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/borrowck/borrowck-use-in-index-lvalue.ast.stderr b/src/test/ui/borrowck/borrowck-use-in-index-lvalue.ast.stderr
index abe5157..e235bdf 100644
--- a/src/test/ui/borrowck/borrowck-use-in-index-lvalue.ast.stderr
+++ b/src/test/ui/borrowck/borrowck-use-in-index-lvalue.ast.stderr
@@ -1,13 +1,13 @@
error[E0381]: use of possibly uninitialized variable: `*w`
--> $DIR/borrowck-use-in-index-lvalue.rs:6:5
|
-LL | w[5] = 0; //[ast]~ ERROR use of possibly uninitialized variable: `*w` [E0381]
+LL | w[5] = 0;
| ^^^^^^^^ use of possibly uninitialized `*w`
error[E0381]: use of possibly uninitialized variable: `*w`
--> $DIR/borrowck-use-in-index-lvalue.rs:10:5
|
-LL | w[5] = 0; //[ast]~ ERROR use of possibly uninitialized variable: `*w` [E0381]
+LL | w[5] = 0;
| ^^^^^^^^ use of possibly uninitialized `*w`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/borrowck/borrowck-use-in-index-lvalue.mir.stderr b/src/test/ui/borrowck/borrowck-use-in-index-lvalue.mir.stderr
index 1819123..c5e4f89 100644
--- a/src/test/ui/borrowck/borrowck-use-in-index-lvalue.mir.stderr
+++ b/src/test/ui/borrowck/borrowck-use-in-index-lvalue.mir.stderr
@@ -1,13 +1,13 @@
error[E0381]: use of possibly uninitialized variable: `w`
--> $DIR/borrowck-use-in-index-lvalue.rs:6:5
|
-LL | w[5] = 0; //[ast]~ ERROR use of possibly uninitialized variable: `*w` [E0381]
+LL | w[5] = 0;
| ^^^^ use of possibly uninitialized `*w`
error[E0381]: use of possibly uninitialized variable: `w`
--> $DIR/borrowck-use-in-index-lvalue.rs:10:5
|
-LL | w[5] = 0; //[ast]~ ERROR use of possibly uninitialized variable: `*w` [E0381]
+LL | w[5] = 0;
| ^^^^ use of possibly uninitialized `*w`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.ast.nll.stderr b/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.ast.nll.stderr
index 8f4b02a..a208dc4 100644
--- a/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.ast.nll.stderr
+++ b/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.ast.nll.stderr
@@ -1,7 +1,7 @@
error[E0381]: borrow of possibly uninitialized variable: `x`
--> $DIR/borrowck-use-uninitialized-in-cast-trait.rs:12:13
|
-LL | let y = x as *const Foo; //[ast]~ ERROR use of possibly uninitialized variable: `*x`
+LL | let y = x as *const Foo;
| ^ use of possibly uninitialized `*x`
error: aborting due to previous error
diff --git a/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.ast.stderr b/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.ast.stderr
index ecb8922..49a4300 100644
--- a/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.ast.stderr
+++ b/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.ast.stderr
@@ -1,7 +1,7 @@
error[E0381]: use of possibly uninitialized variable: `*x`
--> $DIR/borrowck-use-uninitialized-in-cast-trait.rs:12:13
|
-LL | let y = x as *const Foo; //[ast]~ ERROR use of possibly uninitialized variable: `*x`
+LL | let y = x as *const Foo;
| ^ use of possibly uninitialized `*x`
error: aborting due to previous error
diff --git a/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.mir.stderr b/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.mir.stderr
index 8f4b02a..a208dc4 100644
--- a/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.mir.stderr
+++ b/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.mir.stderr
@@ -1,7 +1,7 @@
error[E0381]: borrow of possibly uninitialized variable: `x`
--> $DIR/borrowck-use-uninitialized-in-cast-trait.rs:12:13
|
-LL | let y = x as *const Foo; //[ast]~ ERROR use of possibly uninitialized variable: `*x`
+LL | let y = x as *const Foo;
| ^ use of possibly uninitialized `*x`
error: aborting due to previous error
diff --git a/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast.ast.nll.stderr b/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast.ast.nll.stderr
index dd0a750..0f62c3a 100644
--- a/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast.ast.nll.stderr
+++ b/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast.ast.nll.stderr
@@ -1,7 +1,7 @@
error[E0381]: borrow of possibly uninitialized variable: `x`
--> $DIR/borrowck-use-uninitialized-in-cast.rs:10:13
|
-LL | let y = x as *const i32; //[ast]~ ERROR use of possibly uninitialized variable: `*x` [E0381]
+LL | let y = x as *const i32;
| ^ use of possibly uninitialized `*x`
error: aborting due to previous error
diff --git a/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast.ast.stderr b/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast.ast.stderr
index d3ddf24..d813738 100644
--- a/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast.ast.stderr
+++ b/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast.ast.stderr
@@ -1,7 +1,7 @@
error[E0381]: use of possibly uninitialized variable: `*x`
--> $DIR/borrowck-use-uninitialized-in-cast.rs:10:13
|
-LL | let y = x as *const i32; //[ast]~ ERROR use of possibly uninitialized variable: `*x` [E0381]
+LL | let y = x as *const i32;
| ^ use of possibly uninitialized `*x`
error: aborting due to previous error
diff --git a/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast.mir.stderr b/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast.mir.stderr
index dd0a750..0f62c3a 100644
--- a/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast.mir.stderr
+++ b/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast.mir.stderr
@@ -1,7 +1,7 @@
error[E0381]: borrow of possibly uninitialized variable: `x`
--> $DIR/borrowck-use-uninitialized-in-cast.rs:10:13
|
-LL | let y = x as *const i32; //[ast]~ ERROR use of possibly uninitialized variable: `*x` [E0381]
+LL | let y = x as *const i32;
| ^ use of possibly uninitialized `*x`
error: aborting due to previous error
diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.ast.nll.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.ast.nll.stderr
index 6dc2778..7d0d888 100644
--- a/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.ast.nll.stderr
+++ b/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.ast.nll.stderr
@@ -4,7 +4,7 @@
LL | [1, 2, ref tail..] => tail,
| -------- borrow of `a[_]` occurs here
...
-LL | a[2] = 0; //[ast]~ ERROR cannot assign to `a[..]` because it is borrowed
+LL | a[2] = 0;
| ^^^^^^^^ assignment to borrowed `a[_]` occurs here
...
LL | println!("t[0]: {}", t[0]);
diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.ast.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.ast.stderr
index c456dac..1207d4a 100644
--- a/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.ast.stderr
+++ b/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.ast.stderr
@@ -4,7 +4,7 @@
LL | [1, 2, ref tail..] => tail,
| -------- borrow of `a[..]` occurs here
...
-LL | a[2] = 0; //[ast]~ ERROR cannot assign to `a[..]` because it is borrowed
+LL | a[2] = 0;
| ^^^^^^^^ assignment to borrowed `a[..]` occurs here
error: aborting due to previous error
diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.cmp.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.cmp.stderr
index 6eb9eac..f764d5f 100644
--- a/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.cmp.stderr
+++ b/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.cmp.stderr
@@ -4,7 +4,7 @@
LL | [1, 2, ref tail..] => tail,
| -------- borrow of `a[..]` occurs here
...
-LL | a[2] = 0; //[ast]~ ERROR cannot assign to `a[..]` because it is borrowed
+LL | a[2] = 0;
| ^^^^^^^^ assignment to borrowed `a[..]` occurs here
error[E0506]: cannot assign to `a[_]` because it is borrowed (Mir)
@@ -13,7 +13,7 @@
LL | [1, 2, ref tail..] => tail,
| -------- borrow of `a[_]` occurs here
...
-LL | a[2] = 0; //[ast]~ ERROR cannot assign to `a[..]` because it is borrowed
+LL | a[2] = 0;
| ^^^^^^^^ assignment to borrowed `a[_]` occurs here
...
LL | println!("t[0]: {}", t[0]);
diff --git a/src/test/ui/borrowck/move-in-static-initializer-issue-38520.ast.stderr b/src/test/ui/borrowck/move-in-static-initializer-issue-38520.ast.stderr
index 6793e1a..14078b7 100644
--- a/src/test/ui/borrowck/move-in-static-initializer-issue-38520.ast.stderr
+++ b/src/test/ui/borrowck/move-in-static-initializer-issue-38520.ast.stderr
@@ -1,13 +1,13 @@
error[E0507]: cannot move out of borrowed content
--> $DIR/move-in-static-initializer-issue-38520.rs:15:23
|
-LL | static Y: usize = get(*&X); //[ast]~ ERROR E0507
+LL | static Y: usize = get(*&X);
| ^^^ cannot move out of borrowed content
error[E0507]: cannot move out of borrowed content
--> $DIR/move-in-static-initializer-issue-38520.rs:17:22
|
-LL | const Z: usize = get(*&X); //[ast]~ ERROR E0507
+LL | const Z: usize = get(*&X);
| ^^^ cannot move out of borrowed content
error: aborting due to 2 previous errors
diff --git a/src/test/ui/borrowck/move-in-static-initializer-issue-38520.mir.stderr b/src/test/ui/borrowck/move-in-static-initializer-issue-38520.mir.stderr
index 6793e1a..14078b7 100644
--- a/src/test/ui/borrowck/move-in-static-initializer-issue-38520.mir.stderr
+++ b/src/test/ui/borrowck/move-in-static-initializer-issue-38520.mir.stderr
@@ -1,13 +1,13 @@
error[E0507]: cannot move out of borrowed content
--> $DIR/move-in-static-initializer-issue-38520.rs:15:23
|
-LL | static Y: usize = get(*&X); //[ast]~ ERROR E0507
+LL | static Y: usize = get(*&X);
| ^^^ cannot move out of borrowed content
error[E0507]: cannot move out of borrowed content
--> $DIR/move-in-static-initializer-issue-38520.rs:17:22
|
-LL | const Z: usize = get(*&X); //[ast]~ ERROR E0507
+LL | const Z: usize = get(*&X);
| ^^^ cannot move out of borrowed content
error: aborting due to 2 previous errors
diff --git a/src/test/ui/borrowck/two-phase-activation-sharing-interference.nll_target.stderr b/src/test/ui/borrowck/two-phase-activation-sharing-interference.nll_target.stderr
index 7bae1438..8370aad 100644
--- a/src/test/ui/borrowck/two-phase-activation-sharing-interference.nll_target.stderr
+++ b/src/test/ui/borrowck/two-phase-activation-sharing-interference.nll_target.stderr
@@ -5,7 +5,7 @@
| ------ mutable borrow occurs here
LL | { let z = &x; read(z); }
| ^^ immutable borrow occurs here
-LL | //[nll_target]~^ ERROR cannot borrow `x` as immutable because it is also borrowed as mutable
+LL |
LL | *y += 1;
| ------- mutable borrow later used here
@@ -16,7 +16,7 @@
| ------ mutable borrow occurs here
LL | let z = &x;
| ^^ immutable borrow occurs here
-LL | //[nll_target]~^ ERROR cannot borrow `x` as immutable because it is also borrowed as mutable
+LL |
LL | *y += 1;
| ------- mutable borrow later used here
@@ -38,7 +38,7 @@
| ------ mutable borrow occurs here
LL | let _z = &x;
| ^^ immutable borrow occurs here
-LL | //[nll_target]~^ ERROR cannot borrow `x` as immutable because it is also borrowed as mutable
+LL |
LL | *y += 1;
| ------- mutable borrow later used here
diff --git a/src/test/ui/borrowck/two-phase-allow-access-during-reservation.nll_target.stderr b/src/test/ui/borrowck/two-phase-allow-access-during-reservation.nll_target.stderr
index 232876e..9f31c3f 100644
--- a/src/test/ui/borrowck/two-phase-allow-access-during-reservation.nll_target.stderr
+++ b/src/test/ui/borrowck/two-phase-allow-access-during-reservation.nll_target.stderr
@@ -16,7 +16,7 @@
LL | /*1*/ let p = &mut i; // (reservation of `i` starts here)
| ------ borrow of `i` occurs here
...
-LL | /*4*/ let k = i; //[nll_beyond]~ ERROR cannot use `i` because it was mutably borrowed [E0503]
+LL | /*4*/ let k = i;
| ^ use of borrowed `i`
...
LL | /*5*/ *p += 1;
diff --git a/src/test/ui/confuse-field-and-method/issue-18343.stderr b/src/test/ui/confuse-field-and-method/issue-18343.stderr
index 36112cd..03f9d99 100644
--- a/src/test/ui/confuse-field-and-method/issue-18343.stderr
+++ b/src/test/ui/confuse-field-and-method/issue-18343.stderr
@@ -6,8 +6,10 @@
...
LL | o.closure();
| ^^^^^^^ field, not a method
+help: to call the function stored in `closure`, surround the field access with parentheses
|
- = help: use `(o.closure)(...)` if you meant to call the function stored in the `closure` field
+LL | (o.closure)();
+ | ^ ^
error: aborting due to previous error
diff --git a/src/test/ui/confuse-field-and-method/issue-2392.stderr b/src/test/ui/confuse-field-and-method/issue-2392.stderr
index 456a4c1..2107318 100644
--- a/src/test/ui/confuse-field-and-method/issue-2392.stderr
+++ b/src/test/ui/confuse-field-and-method/issue-2392.stderr
@@ -6,8 +6,10 @@
...
LL | o_closure.closure();
| ^^^^^^^ field, not a method
+help: to call the function stored in `closure`, surround the field access with parentheses
|
- = help: use `(o_closure.closure)(...)` if you meant to call the function stored in the `closure` field
+LL | (o_closure.closure)();
+ | ^ ^
error[E0599]: no method named `not_closure` found for type `Obj<[closure@$DIR/issue-2392.rs:39:36: 39:41]>` in the current scope
--> $DIR/issue-2392.rs:42:15
@@ -16,9 +18,9 @@
| -------------------------------------- method `not_closure` not found for this
...
LL | o_closure.not_closure();
- | ^^^^^^^^^^^ field, not a method
- |
- = help: did you mean to write `o_closure.not_closure` instead of `o_closure.not_closure(...)`?
+ | ^^^^^^^^^^^-- help: remove the arguments
+ | |
+ | field, not a method
error[E0599]: no method named `closure` found for type `Obj<fn() -> u32 {func}>` in the current scope
--> $DIR/issue-2392.rs:46:12
@@ -28,8 +30,10 @@
...
LL | o_func.closure();
| ^^^^^^^ field, not a method
+help: to call the function stored in `closure`, surround the field access with parentheses
|
- = help: use `(o_func.closure)(...)` if you meant to call the function stored in the `closure` field
+LL | (o_func.closure)();
+ | ^ ^
error[E0599]: no method named `boxed_closure` found for type `BoxedObj` in the current scope
--> $DIR/issue-2392.rs:49:14
@@ -39,8 +43,10 @@
...
LL | boxed_fn.boxed_closure();
| ^^^^^^^^^^^^^ field, not a method
+help: to call the function stored in `boxed_closure`, surround the field access with parentheses
|
- = help: use `(boxed_fn.boxed_closure)(...)` if you meant to call the function stored in the `boxed_closure` field
+LL | (boxed_fn.boxed_closure)();
+ | ^ ^
error[E0599]: no method named `boxed_closure` found for type `BoxedObj` in the current scope
--> $DIR/issue-2392.rs:52:19
@@ -50,8 +56,10 @@
...
LL | boxed_closure.boxed_closure();
| ^^^^^^^^^^^^^ field, not a method
+help: to call the function stored in `boxed_closure`, surround the field access with parentheses
|
- = help: use `(boxed_closure.boxed_closure)(...)` if you meant to call the function stored in the `boxed_closure` field
+LL | (boxed_closure.boxed_closure)();
+ | ^ ^
error[E0599]: no method named `closure` found for type `Obj<fn() -> u32 {func}>` in the current scope
--> $DIR/issue-2392.rs:57:12
@@ -61,8 +69,10 @@
...
LL | w.wrap.closure();
| ^^^^^^^ field, not a method
+help: to call the function stored in `closure`, surround the field access with parentheses
|
- = help: use `(w.wrap.closure)(...)` if you meant to call the function stored in the `closure` field
+LL | (w.wrap.closure)();
+ | ^ ^
error[E0599]: no method named `not_closure` found for type `Obj<fn() -> u32 {func}>` in the current scope
--> $DIR/issue-2392.rs:59:12
@@ -71,9 +81,9 @@
| -------------------------------------- method `not_closure` not found for this
...
LL | w.wrap.not_closure();
- | ^^^^^^^^^^^ field, not a method
- |
- = help: did you mean to write `w.wrap.not_closure` instead of `w.wrap.not_closure(...)`?
+ | ^^^^^^^^^^^-- help: remove the arguments
+ | |
+ | field, not a method
error[E0599]: no method named `closure` found for type `Obj<std::boxed::Box<(dyn std::boxed::FnBox<(), Output = u32> + 'static)>>` in the current scope
--> $DIR/issue-2392.rs:62:24
@@ -83,8 +93,10 @@
...
LL | check_expression().closure();
| ^^^^^^^ field, not a method
+help: to call the function stored in `closure`, surround the field access with parentheses
|
- = help: use `(check_expression().closure)(...)` if you meant to call the function stored in the `closure` field
+LL | (check_expression().closure)();
+ | ^ ^
error[E0599]: no method named `f1` found for type `FuncContainer` in the current scope
--> $DIR/issue-2392.rs:68:31
@@ -94,8 +106,10 @@
...
LL | (*self.container).f1(1);
| ^^ field, not a method
+help: to call the function stored in `f1`, surround the field access with parentheses
|
- = help: use `((*self.container).f1)(...)` if you meant to call the function stored in the `f1` field
+LL | ((*self.container).f1)(1);
+ | ^ ^
error[E0599]: no method named `f2` found for type `FuncContainer` in the current scope
--> $DIR/issue-2392.rs:69:31
@@ -105,8 +119,10 @@
...
LL | (*self.container).f2(1);
| ^^ field, not a method
+help: to call the function stored in `f2`, surround the field access with parentheses
|
- = help: use `((*self.container).f2)(...)` if you meant to call the function stored in the `f2` field
+LL | ((*self.container).f2)(1);
+ | ^ ^
error[E0599]: no method named `f3` found for type `FuncContainer` in the current scope
--> $DIR/issue-2392.rs:70:31
@@ -116,8 +132,10 @@
...
LL | (*self.container).f3(1);
| ^^ field, not a method
+help: to call the function stored in `f3`, surround the field access with parentheses
|
- = help: use `((*self.container).f3)(...)` if you meant to call the function stored in the `f3` field
+LL | ((*self.container).f3)(1);
+ | ^ ^
error: aborting due to 11 previous errors
diff --git a/src/test/ui/confuse-field-and-method/issue-32128.stderr b/src/test/ui/confuse-field-and-method/issue-32128.stderr
index 902f606..fbabb3a 100644
--- a/src/test/ui/confuse-field-and-method/issue-32128.stderr
+++ b/src/test/ui/confuse-field-and-method/issue-32128.stderr
@@ -6,8 +6,10 @@
...
LL | demo.example(1);
| ^^^^^^^ field, not a method
+help: to call the function stored in `example`, surround the field access with parentheses
|
- = help: use `(demo.example)(...)` if you meant to call the function stored in the `example` field
+LL | (demo.example)(1);
+ | ^ ^
error: aborting due to previous error
diff --git a/src/test/ui/confuse-field-and-method/issue-33784.stderr b/src/test/ui/confuse-field-and-method/issue-33784.stderr
index cce961f..60f1a93 100644
--- a/src/test/ui/confuse-field-and-method/issue-33784.stderr
+++ b/src/test/ui/confuse-field-and-method/issue-33784.stderr
@@ -3,24 +3,30 @@
|
LL | p.closure();
| ^^^^^^^ field, not a method
+help: to call the function stored in `closure`, surround the field access with parentheses
|
- = help: use `(p.closure)(...)` if you meant to call the function stored in the `closure` field
+LL | (p.closure)();
+ | ^ ^
error[E0599]: no method named `fn_ptr` found for type `&&Obj<[closure@$DIR/issue-33784.rs:25:43: 25:48]>` in the current scope
--> $DIR/issue-33784.rs:29:7
|
LL | q.fn_ptr();
| ^^^^^^ field, not a method
+help: to call the function stored in `fn_ptr`, surround the field access with parentheses
|
- = help: use `(q.fn_ptr)(...)` if you meant to call the function stored in the `fn_ptr` field
+LL | (q.fn_ptr)();
+ | ^ ^
error[E0599]: no method named `c_fn_ptr` found for type `&D` in the current scope
--> $DIR/issue-33784.rs:32:7
|
LL | s.c_fn_ptr();
| ^^^^^^^^ field, not a method
+help: to call the function stored in `c_fn_ptr`, surround the field access with parentheses
|
- = help: use `(s.c_fn_ptr)(...)` if you meant to call the function stored in the `c_fn_ptr` field
+LL | (s.c_fn_ptr)();
+ | ^ ^
error: aborting due to 3 previous errors
diff --git a/src/test/ui/consts/union_constant.rs b/src/test/ui/consts/union_constant.rs
new file mode 100644
index 0000000..0740149
--- /dev/null
+++ b/src/test/ui/consts/union_constant.rs
@@ -0,0 +1,11 @@
+// compile-pass
+
+union Uninit {
+ _never_use: *const u8,
+ uninit: (),
+}
+
+const UNINIT: Uninit = Uninit { uninit: () };
+
+fn main() {}
+
diff --git a/src/test/ui/dep-graph/dep-graph-struct-signature.rs b/src/test/ui/dep-graph/dep-graph-struct-signature.rs
index 3d660aa..bd6d3a7 100644
--- a/src/test/ui/dep-graph/dep-graph-struct-signature.rs
+++ b/src/test/ui/dep-graph/dep-graph-struct-signature.rs
@@ -24,7 +24,7 @@
mod signatures {
use WillChange;
- #[rustc_then_this_would_need(TypeOfItem)] //~ ERROR no path
+ #[rustc_then_this_would_need(type_of)] //~ ERROR no path
#[rustc_then_this_would_need(AssociatedItems)] //~ ERROR no path
#[rustc_then_this_would_need(TraitDefOfItem)] //~ ERROR no path
trait Bar {
@@ -42,14 +42,14 @@
WillChange { x: x, y: y }
}
- #[rustc_then_this_would_need(TypeOfItem)] //~ ERROR OK
+ #[rustc_then_this_would_need(type_of)] //~ ERROR OK
impl WillChange {
#[rustc_then_this_would_need(FnSignature)] //~ ERROR OK
#[rustc_then_this_would_need(TypeckTables)] //~ ERROR OK
fn new(x: u32, y: u32) -> WillChange { loop { } }
}
- #[rustc_then_this_would_need(TypeOfItem)] //~ ERROR OK
+ #[rustc_then_this_would_need(type_of)] //~ ERROR OK
impl WillChange {
#[rustc_then_this_would_need(FnSignature)] //~ ERROR OK
#[rustc_then_this_would_need(TypeckTables)] //~ ERROR OK
@@ -57,21 +57,21 @@
}
struct WillChanges {
- #[rustc_then_this_would_need(TypeOfItem)] //~ ERROR OK
+ #[rustc_then_this_would_need(type_of)] //~ ERROR OK
x: WillChange,
- #[rustc_then_this_would_need(TypeOfItem)] //~ ERROR OK
+ #[rustc_then_this_would_need(type_of)] //~ ERROR OK
y: WillChange
}
// The fields change, not the type itself.
- #[rustc_then_this_would_need(TypeOfItem)] //~ ERROR no path
+ #[rustc_then_this_would_need(type_of)] //~ ERROR no path
fn indirect(x: WillChanges) { }
}
mod invalid_signatures {
use WontChange;
- #[rustc_then_this_would_need(TypeOfItem)] //~ ERROR no path
+ #[rustc_then_this_would_need(type_of)] //~ ERROR no path
trait A {
#[rustc_then_this_would_need(FnSignature)] //~ ERROR no path
fn do_something_else_twice(x: WontChange);
diff --git a/src/test/ui/dep-graph/dep-graph-struct-signature.stderr b/src/test/ui/dep-graph/dep-graph-struct-signature.stderr
index 8736d15..7aa4251 100644
--- a/src/test/ui/dep-graph/dep-graph-struct-signature.stderr
+++ b/src/test/ui/dep-graph/dep-graph-struct-signature.stderr
@@ -1,8 +1,8 @@
-error: no path from `WillChange` to `TypeOfItem`
+error: no path from `WillChange` to `type_of`
--> $DIR/dep-graph-struct-signature.rs:27:5
|
-LL | #[rustc_then_this_would_need(TypeOfItem)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[rustc_then_this_would_need(type_of)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: no path from `WillChange` to `AssociatedItems`
--> $DIR/dep-graph-struct-signature.rs:28:5
@@ -43,38 +43,38 @@
error: OK
--> $DIR/dep-graph-struct-signature.rs:45:5
|
-LL | #[rustc_then_this_would_need(TypeOfItem)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[rustc_then_this_would_need(type_of)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: OK
--> $DIR/dep-graph-struct-signature.rs:52:5
|
-LL | #[rustc_then_this_would_need(TypeOfItem)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[rustc_then_this_would_need(type_of)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: OK
--> $DIR/dep-graph-struct-signature.rs:60:9
|
-LL | #[rustc_then_this_would_need(TypeOfItem)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[rustc_then_this_would_need(type_of)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: OK
--> $DIR/dep-graph-struct-signature.rs:62:9
|
-LL | #[rustc_then_this_would_need(TypeOfItem)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[rustc_then_this_would_need(type_of)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: no path from `WillChange` to `TypeOfItem`
+error: no path from `WillChange` to `type_of`
--> $DIR/dep-graph-struct-signature.rs:67:5
|
-LL | #[rustc_then_this_would_need(TypeOfItem)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[rustc_then_this_would_need(type_of)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: no path from `WillChange` to `TypeOfItem`
+error: no path from `WillChange` to `type_of`
--> $DIR/dep-graph-struct-signature.rs:74:5
|
-LL | #[rustc_then_this_would_need(TypeOfItem)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[rustc_then_this_would_need(type_of)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: no path from `WillChange` to `FnSignature`
--> $DIR/dep-graph-struct-signature.rs:80:5
diff --git a/src/test/ui/dep-graph/dep-graph-type-alias.rs b/src/test/ui/dep-graph/dep-graph-type-alias.rs
index 0f703ae..5621284 100644
--- a/src/test/ui/dep-graph/dep-graph-type-alias.rs
+++ b/src/test/ui/dep-graph/dep-graph-type-alias.rs
@@ -14,23 +14,23 @@
// The type alias directly affects the type of the field,
// not the enclosing struct:
-#[rustc_then_this_would_need(TypeOfItem)] //~ ERROR no path
+#[rustc_then_this_would_need(type_of)] //~ ERROR no path
struct Struct {
- #[rustc_then_this_would_need(TypeOfItem)] //~ ERROR OK
+ #[rustc_then_this_would_need(type_of)] //~ ERROR OK
x: TypeAlias,
y: u32
}
-#[rustc_then_this_would_need(TypeOfItem)] //~ ERROR no path
+#[rustc_then_this_would_need(type_of)] //~ ERROR no path
enum Enum {
Variant1 {
- #[rustc_then_this_would_need(TypeOfItem)] //~ ERROR OK
+ #[rustc_then_this_would_need(type_of)] //~ ERROR OK
t: TypeAlias
},
Variant2(i32)
}
-#[rustc_then_this_would_need(TypeOfItem)] //~ ERROR no path
+#[rustc_then_this_would_need(type_of)] //~ ERROR no path
trait Trait {
#[rustc_then_this_would_need(FnSignature)] //~ ERROR OK
fn method(&self, _: TypeAlias);
@@ -38,14 +38,14 @@
struct SomeType;
-#[rustc_then_this_would_need(TypeOfItem)] //~ ERROR no path
+#[rustc_then_this_would_need(type_of)] //~ ERROR no path
impl SomeType {
#[rustc_then_this_would_need(FnSignature)] //~ ERROR OK
#[rustc_then_this_would_need(TypeckTables)] //~ ERROR OK
fn method(&self, _: TypeAlias) {}
}
-#[rustc_then_this_would_need(TypeOfItem)] //~ ERROR OK
+#[rustc_then_this_would_need(type_of)] //~ ERROR OK
type TypeAlias2 = TypeAlias;
#[rustc_then_this_would_need(FnSignature)] //~ ERROR OK
diff --git a/src/test/ui/dep-graph/dep-graph-type-alias.stderr b/src/test/ui/dep-graph/dep-graph-type-alias.stderr
index f54e511..520c2a5 100644
--- a/src/test/ui/dep-graph/dep-graph-type-alias.stderr
+++ b/src/test/ui/dep-graph/dep-graph-type-alias.stderr
@@ -1,44 +1,44 @@
-error: no path from `TypeAlias` to `TypeOfItem`
+error: no path from `TypeAlias` to `type_of`
--> $DIR/dep-graph-type-alias.rs:17:1
|
-LL | #[rustc_then_this_would_need(TypeOfItem)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[rustc_then_this_would_need(type_of)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: OK
--> $DIR/dep-graph-type-alias.rs:19:5
|
-LL | #[rustc_then_this_would_need(TypeOfItem)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[rustc_then_this_would_need(type_of)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: no path from `TypeAlias` to `TypeOfItem`
+error: no path from `TypeAlias` to `type_of`
--> $DIR/dep-graph-type-alias.rs:24:1
|
-LL | #[rustc_then_this_would_need(TypeOfItem)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[rustc_then_this_would_need(type_of)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: OK
--> $DIR/dep-graph-type-alias.rs:27:9
|
-LL | #[rustc_then_this_would_need(TypeOfItem)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[rustc_then_this_would_need(type_of)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: no path from `TypeAlias` to `TypeOfItem`
+error: no path from `TypeAlias` to `type_of`
--> $DIR/dep-graph-type-alias.rs:33:1
|
-LL | #[rustc_then_this_would_need(TypeOfItem)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[rustc_then_this_would_need(type_of)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-error: no path from `TypeAlias` to `TypeOfItem`
+error: no path from `TypeAlias` to `type_of`
--> $DIR/dep-graph-type-alias.rs:41:1
|
-LL | #[rustc_then_this_would_need(TypeOfItem)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[rustc_then_this_would_need(type_of)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: OK
--> $DIR/dep-graph-type-alias.rs:48:1
|
-LL | #[rustc_then_this_would_need(TypeOfItem)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[rustc_then_this_would_need(type_of)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: OK
--> $DIR/dep-graph-type-alias.rs:51:1
diff --git a/src/test/ui/deprecation/derive_on_deprecated.rs b/src/test/ui/deprecation/derive_on_deprecated.rs
new file mode 100644
index 0000000..4980a7f
--- /dev/null
+++ b/src/test/ui/deprecation/derive_on_deprecated.rs
@@ -0,0 +1,9 @@
+// compile-pass
+
+#![deny(deprecated)]
+
+#[deprecated = "oh no"]
+#[derive(Default)]
+struct X;
+
+fn main() {}
diff --git a/src/test/ui/deprecation/derive_on_deprecated_forbidden.rs b/src/test/ui/deprecation/derive_on_deprecated_forbidden.rs
new file mode 100644
index 0000000..235146b
--- /dev/null
+++ b/src/test/ui/deprecation/derive_on_deprecated_forbidden.rs
@@ -0,0 +1,9 @@
+// compile-pass
+
+#![forbid(deprecated)]
+
+#[deprecated = "oh no"]
+#[derive(Default)]
+struct X;
+
+fn main() {}
diff --git a/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.rs b/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.rs
index f5dbab1..7d3aba36 100644
--- a/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.rs
+++ b/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.rs
@@ -1,5 +1,20 @@
enum Example { Ex(String), NotEx }
+enum Void {}
+
+enum ManyVariants {
+ One,
+ Two,
+ Three,
+ Four,
+ Five,
+ Six,
+ Seven,
+ Eight,
+ Nine,
+ Ten,
+}
+
fn result_test() {
let x = Option(1); //~ ERROR expected function, found enum
@@ -12,6 +27,10 @@
if let Example(_) = y { //~ ERROR expected tuple struct/variant, found enum
println!("It is OK.");
}
+
+ let y = Void(); //~ ERROR expected function, found enum
+
+ let z = ManyVariants(); //~ ERROR expected function, found enum
}
fn main() {}
diff --git a/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.stderr b/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.stderr
index 8a0d009..4210b4e 100644
--- a/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.stderr
+++ b/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.stderr
@@ -1,34 +1,63 @@
error[E0423]: expected function, found enum `Option`
- --> $DIR/issue-43871-enum-instead-of-variant.rs:4:13
+ --> $DIR/issue-43871-enum-instead-of-variant.rs:19:13
|
LL | let x = Option(1);
| ^^^^^^
+help: try using one of the enum's variants
|
- = note: did you mean to use one of the following variants?
- - `std::prelude::v1::Option::None`
- - `std::prelude::v1::Option::Some`
+LL | let x = std::prelude::v1::Option::None(1);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | let x = std::prelude::v1::Option::Some(1);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0532]: expected tuple struct/variant, found enum `Option`
- --> $DIR/issue-43871-enum-instead-of-variant.rs:6:12
+ --> $DIR/issue-43871-enum-instead-of-variant.rs:21:12
|
LL | if let Option(_) = x {
| ^^^^^^
+help: try using one of the enum's variants
|
- = note: did you mean to use one of the following variants?
- - `std::prelude::v1::Option::None`
- - `std::prelude::v1::Option::Some`
+LL | if let std::prelude::v1::Option::None(_) = x {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | if let std::prelude::v1::Option::Some(_) = x {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0532]: expected tuple struct/variant, found enum `Example`
- --> $DIR/issue-43871-enum-instead-of-variant.rs:12:12
+ --> $DIR/issue-43871-enum-instead-of-variant.rs:27:12
|
LL | if let Example(_) = y {
| ^^^^^^^
+help: try using one of the enum's variants
|
- = note: did you mean to use one of the following variants?
- - `Example::Ex`
- - `Example::NotEx`
+LL | if let Example::Ex(_) = y {
+ | ^^^^^^^^^^^
+LL | if let Example::NotEx(_) = y {
+ | ^^^^^^^^^^^^^^
-error: aborting due to 3 previous errors
+error[E0423]: expected function, found enum `Void`
+ --> $DIR/issue-43871-enum-instead-of-variant.rs:31:13
+ |
+LL | let y = Void();
+ | ^^^^
+
+error[E0423]: expected function, found enum `ManyVariants`
+ --> $DIR/issue-43871-enum-instead-of-variant.rs:33:13
+ |
+LL | let z = ManyVariants();
+ | ^^^^^^^^^^^^
+help: try using one of the enum's variants
+ |
+LL | let z = ManyVariants::Eight();
+ | ^^^^^^^^^^^^^^^^^^^
+LL | let z = ManyVariants::Five();
+ | ^^^^^^^^^^^^^^^^^^
+LL | let z = ManyVariants::Four();
+ | ^^^^^^^^^^^^^^^^^^
+LL | let z = ManyVariants::Nine();
+ | ^^^^^^^^^^^^^^^^^^
+and 6 other candidates
+
+error: aborting due to 5 previous errors
Some errors occurred: E0423, E0532.
For more information about an error, try `rustc --explain E0423`.
diff --git a/src/test/ui/enum-variant-generic-args.rs b/src/test/ui/enum-variant-generic-args.rs
index 6eddd70..dd1f5f3 100644
--- a/src/test/ui/enum-variant-generic-args.rs
+++ b/src/test/ui/enum-variant-generic-args.rs
@@ -9,27 +9,27 @@
Self::TSVariant(());
//~^ ERROR mismatched types [E0308]
Self::TSVariant::<()>(());
- //~^ ERROR type arguments are not allowed on this entity [E0109]
+ //~^ ERROR type arguments are not allowed for this type [E0109]
Self::<()>::TSVariant(());
- //~^ ERROR type arguments are not allowed on this entity [E0109]
+ //~^ ERROR type arguments are not allowed for this type [E0109]
//~^^ ERROR mismatched types [E0308]
Self::<()>::TSVariant::<()>(());
- //~^ ERROR type arguments are not allowed on this entity [E0109]
- //~^^ ERROR type arguments are not allowed on this entity [E0109]
+ //~^ ERROR type arguments are not allowed for this type [E0109]
+ //~^^ ERROR type arguments are not allowed for this type [E0109]
}
fn s_variant() {
Self::SVariant { v: () };
//~^ ERROR mismatched types [E0308]
Self::SVariant::<()> { v: () };
- //~^ ERROR type arguments are not allowed on this entity [E0109]
+ //~^ ERROR type arguments are not allowed for this type [E0109]
//~^^ ERROR mismatched types [E0308]
Self::<()>::SVariant { v: () };
- //~^ ERROR type arguments are not allowed on this entity [E0109]
+ //~^ ERROR type arguments are not allowed for this type [E0109]
//~^^ ERROR mismatched types [E0308]
Self::<()>::SVariant::<()> { v: () };
- //~^ ERROR type arguments are not allowed on this entity [E0109]
- //~^^ ERROR type arguments are not allowed on this entity [E0109]
+ //~^ ERROR type arguments are not allowed for this type [E0109]
+ //~^^ ERROR type arguments are not allowed for this type [E0109]
//~^^^ ERROR mismatched types [E0308]
}
}
@@ -38,36 +38,36 @@
// Tuple struct variant
Enum::<()>::TSVariant::<()>(());
- //~^ ERROR type arguments are not allowed on this entity [E0109]
+ //~^ ERROR type arguments are not allowed for this type [E0109]
Alias::TSVariant::<()>(());
- //~^ ERROR type arguments are not allowed on this entity [E0109]
+ //~^ ERROR type arguments are not allowed for this type [E0109]
Alias::<()>::TSVariant::<()>(());
- //~^ ERROR type arguments are not allowed on this entity [E0109]
+ //~^ ERROR type arguments are not allowed for this type [E0109]
AliasFixed::TSVariant::<()>(());
- //~^ ERROR type arguments are not allowed on this entity [E0109]
+ //~^ ERROR type arguments are not allowed for this type [E0109]
AliasFixed::<()>::TSVariant(());
//~^ ERROR wrong number of type arguments: expected 0, found 1 [E0107]
AliasFixed::<()>::TSVariant::<()>(());
- //~^ ERROR type arguments are not allowed on this entity [E0109]
+ //~^ ERROR type arguments are not allowed for this type [E0109]
//~^^ ERROR wrong number of type arguments: expected 0, found 1 [E0107]
// Struct variant
Enum::<()>::SVariant::<()> { v: () };
- //~^ ERROR type arguments are not allowed on this entity [E0109]
+ //~^ ERROR type arguments are not allowed for this type [E0109]
Alias::SVariant::<()> { v: () };
- //~^ ERROR type arguments are not allowed on this entity [E0109]
+ //~^ ERROR type arguments are not allowed for this type [E0109]
Alias::<()>::SVariant::<()> { v: () };
- //~^ ERROR type arguments are not allowed on this entity [E0109]
+ //~^ ERROR type arguments are not allowed for this type [E0109]
AliasFixed::SVariant::<()> { v: () };
- //~^ ERROR type arguments are not allowed on this entity [E0109]
+ //~^ ERROR type arguments are not allowed for this type [E0109]
AliasFixed::<()>::SVariant { v: () };
//~^ ERROR wrong number of type arguments: expected 0, found 1 [E0107]
AliasFixed::<()>::SVariant::<()> { v: () };
- //~^ ERROR type arguments are not allowed on this entity [E0109]
+ //~^ ERROR type arguments are not allowed for this type [E0109]
//~^^ ERROR wrong number of type arguments: expected 0, found 1 [E0107]
}
diff --git a/src/test/ui/enum-variant-generic-args.stderr b/src/test/ui/enum-variant-generic-args.stderr
index 4d3b576..09b9a4ee 100644
--- a/src/test/ui/enum-variant-generic-args.stderr
+++ b/src/test/ui/enum-variant-generic-args.stderr
@@ -7,13 +7,13 @@
= note: expected type `T`
found type `()`
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/enum-variant-generic-args.rs:11:27
|
LL | Self::TSVariant::<()>(());
| ^^ type argument not allowed
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/enum-variant-generic-args.rs:13:16
|
LL | Self::<()>::TSVariant(());
@@ -28,13 +28,13 @@
= note: expected type `T`
found type `()`
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/enum-variant-generic-args.rs:16:16
|
LL | Self::<()>::TSVariant::<()>(());
| ^^ type argument not allowed
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/enum-variant-generic-args.rs:16:33
|
LL | Self::<()>::TSVariant::<()>(());
@@ -49,7 +49,7 @@
= note: expected type `T`
found type `()`
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/enum-variant-generic-args.rs:24:26
|
LL | Self::SVariant::<()> { v: () };
@@ -64,7 +64,7 @@
= note: expected type `T`
found type `()`
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/enum-variant-generic-args.rs:27:16
|
LL | Self::<()>::SVariant { v: () };
@@ -79,13 +79,13 @@
= note: expected type `T`
found type `()`
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/enum-variant-generic-args.rs:30:16
|
LL | Self::<()>::SVariant::<()> { v: () };
| ^^ type argument not allowed
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/enum-variant-generic-args.rs:30:32
|
LL | Self::<()>::SVariant::<()> { v: () };
@@ -100,25 +100,25 @@
= note: expected type `T`
found type `()`
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/enum-variant-generic-args.rs:40:29
|
LL | Enum::<()>::TSVariant::<()>(());
| ^^ type argument not allowed
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/enum-variant-generic-args.rs:43:24
|
LL | Alias::TSVariant::<()>(());
| ^^ type argument not allowed
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/enum-variant-generic-args.rs:45:30
|
LL | Alias::<()>::TSVariant::<()>(());
| ^^ type argument not allowed
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/enum-variant-generic-args.rs:48:29
|
LL | AliasFixed::TSVariant::<()>(());
@@ -136,31 +136,31 @@
LL | AliasFixed::<()>::TSVariant::<()>(());
| ^^ unexpected type argument
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/enum-variant-generic-args.rs:52:35
|
LL | AliasFixed::<()>::TSVariant::<()>(());
| ^^ type argument not allowed
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/enum-variant-generic-args.rs:58:28
|
LL | Enum::<()>::SVariant::<()> { v: () };
| ^^ type argument not allowed
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/enum-variant-generic-args.rs:61:23
|
LL | Alias::SVariant::<()> { v: () };
| ^^ type argument not allowed
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/enum-variant-generic-args.rs:63:29
|
LL | Alias::<()>::SVariant::<()> { v: () };
| ^^ type argument not allowed
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/enum-variant-generic-args.rs:66:28
|
LL | AliasFixed::SVariant::<()> { v: () };
@@ -178,7 +178,7 @@
LL | AliasFixed::<()>::SVariant::<()> { v: () };
| ^^ unexpected type argument
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/enum-variant-generic-args.rs:70:34
|
LL | AliasFixed::<()>::SVariant::<()> { v: () };
diff --git a/src/test/ui/error-codes/E0109.stderr b/src/test/ui/error-codes/E0109.stderr
index a807f2d..577e286 100644
--- a/src/test/ui/error-codes/E0109.stderr
+++ b/src/test/ui/error-codes/E0109.stderr
@@ -1,4 +1,4 @@
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/E0109.rs:1:14
|
LL | type X = u32<i32>;
diff --git a/src/test/ui/error-codes/E0110.rs b/src/test/ui/error-codes/E0110.rs
index 764b62b..314c7f5 100644
--- a/src/test/ui/error-codes/E0110.rs
+++ b/src/test/ui/error-codes/E0110.rs
@@ -1,3 +1,3 @@
-type X = u32<'static>; //~ ERROR E0110
+type X = u32<'static>; //~ ERROR E0109
fn main() {}
diff --git a/src/test/ui/error-codes/E0110.stderr b/src/test/ui/error-codes/E0110.stderr
index 3bc4775..b022131 100644
--- a/src/test/ui/error-codes/E0110.stderr
+++ b/src/test/ui/error-codes/E0110.stderr
@@ -1,4 +1,4 @@
-error[E0110]: lifetime arguments are not allowed on this entity
+error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/E0110.rs:1:14
|
LL | type X = u32<'static>;
@@ -6,4 +6,4 @@
error: aborting due to previous error
-For more information about this error, try `rustc --explain E0110`.
+For more information about this error, try `rustc --explain E0109`.
diff --git a/src/test/ui/extern-prelude-fail.rs b/src/test/ui/extern-prelude-fail.rs
new file mode 100644
index 0000000..7d38702
--- /dev/null
+++ b/src/test/ui/extern-prelude-fail.rs
@@ -0,0 +1,9 @@
+// compile-flags:--extern extern_prelude
+// aux-build:extern-prelude.rs
+
+// Extern prelude names are not available by absolute paths
+
+fn main() {
+ use extern_prelude::S; //~ ERROR unresolved import `extern_prelude`
+ let s = ::extern_prelude::S; //~ ERROR failed to resolve
+}
diff --git a/src/test/ui/extern-prelude-fail.stderr b/src/test/ui/extern-prelude-fail.stderr
new file mode 100644
index 0000000..ad148c0
--- /dev/null
+++ b/src/test/ui/extern-prelude-fail.stderr
@@ -0,0 +1,16 @@
+error[E0432]: unresolved import `extern_prelude`
+ --> $DIR/extern-prelude-fail.rs:7:9
+ |
+LL | use extern_prelude::S;
+ | ^^^^^^^^^^^^^^ maybe a missing `extern crate extern_prelude;`?
+
+error[E0433]: failed to resolve: maybe a missing `extern crate extern_prelude;`?
+ --> $DIR/extern-prelude-fail.rs:8:15
+ |
+LL | let s = ::extern_prelude::S;
+ | ^^^^^^^^^^^^^^ maybe a missing `extern crate extern_prelude;`?
+
+error: aborting due to 2 previous errors
+
+Some errors occurred: E0432, E0433.
+For more information about an error, try `rustc --explain E0432`.
diff --git a/src/test/ui/extern-prelude.rs b/src/test/ui/extern-prelude.rs
new file mode 100644
index 0000000..0e52f2c
--- /dev/null
+++ b/src/test/ui/extern-prelude.rs
@@ -0,0 +1,31 @@
+// compile-pass
+// compile-flags:--extern extern_prelude --extern Vec
+// aux-build:extern-prelude.rs
+// aux-build:extern-prelude-vec.rs
+
+fn basic() {
+ // It works
+ let s = extern_prelude::S;
+ s.external();
+}
+
+fn shadow_mod() {
+ // Local module shadows `extern_prelude` from extern prelude
+ mod extern_prelude {
+ pub struct S;
+
+ impl S {
+ pub fn internal(&self) {}
+ }
+ }
+
+ let s = extern_prelude::S;
+ s.internal(); // OK
+}
+
+fn shadow_prelude() {
+ // Extern prelude shadows standard library prelude
+ let x = Vec::new(0f32, ()); // OK
+}
+
+fn main() {}
diff --git a/src/test/ui/feature-gate/allow-features-empty.rs b/src/test/ui/feature-gate/allow-features-empty.rs
new file mode 100644
index 0000000..8325005
--- /dev/null
+++ b/src/test/ui/feature-gate/allow-features-empty.rs
@@ -0,0 +1,10 @@
+// compile-flags: -Z allow_features=
+// Note: This test uses rustc internal flags because they will never stabilize.
+
+#![feature(rustc_diagnostic_macros)] //~ ERROR
+
+#![feature(rustc_const_unstable)] //~ ERROR
+
+#![feature(lang_items)] //~ ERROR
+
+fn main() {}
diff --git a/src/test/ui/feature-gate/allow-features-empty.stderr b/src/test/ui/feature-gate/allow-features-empty.stderr
new file mode 100644
index 0000000..cce2c40
--- /dev/null
+++ b/src/test/ui/feature-gate/allow-features-empty.stderr
@@ -0,0 +1,21 @@
+error[E0725]: the feature `rustc_diagnostic_macros` is not in the list of allowed features
+ --> $DIR/allow-features-empty.rs:4:12
+ |
+LL | #![feature(rustc_diagnostic_macros)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0725]: the feature `rustc_const_unstable` is not in the list of allowed features
+ --> $DIR/allow-features-empty.rs:6:12
+ |
+LL | #![feature(rustc_const_unstable)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error[E0725]: the feature `lang_items` is not in the list of allowed features
+ --> $DIR/allow-features-empty.rs:8:12
+ |
+LL | #![feature(lang_items)]
+ | ^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0725`.
diff --git a/src/test/ui/feature-gate/allow-features.rs b/src/test/ui/feature-gate/allow-features.rs
new file mode 100644
index 0000000..1cebc8f
--- /dev/null
+++ b/src/test/ui/feature-gate/allow-features.rs
@@ -0,0 +1,10 @@
+// compile-flags: -Z allow_features=rustc_diagnostic_macros,lang_items
+// Note: This test uses rustc internal flags because they will never stabilize.
+
+#![feature(rustc_diagnostic_macros)]
+
+#![feature(rustc_const_unstable)] //~ ERROR
+
+#![feature(lang_items)]
+
+fn main() {}
diff --git a/src/test/ui/feature-gate/allow-features.stderr b/src/test/ui/feature-gate/allow-features.stderr
new file mode 100644
index 0000000..b13560f
--- /dev/null
+++ b/src/test/ui/feature-gate/allow-features.stderr
@@ -0,0 +1,9 @@
+error[E0725]: the feature `rustc_const_unstable` is not in the list of allowed features
+ --> $DIR/allow-features.rs:6:12
+ |
+LL | #![feature(rustc_const_unstable)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0725`.
diff --git a/src/test/ui/glob-resolve1.stderr b/src/test/ui/glob-resolve1.stderr
index 01730c4..c252a6e 100644
--- a/src/test/ui/glob-resolve1.stderr
+++ b/src/test/ui/glob-resolve1.stderr
@@ -22,10 +22,7 @@
--> $DIR/glob-resolve1.rs:24:5
|
LL | B;
- | ^
- |
- = note: did you mean to use one of the following variants?
- - `B::B1`
+ | ^ help: try using the enum's variant: `B::B1`
error[E0425]: cannot find value `C` in this scope
--> $DIR/glob-resolve1.rs:25:5
diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_a.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_a.stderr
index 5fcb63e..9ec36f4 100644
--- a/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_a.stderr
+++ b/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_a.stderr
@@ -2,11 +2,11 @@
--> $DIR/hr-subtype.rs:100:1
|
LL | / fn main() {
-LL | | //[bound_a_vs_bound_a]~^ ERROR compilation successful
-LL | | //[bound_a_vs_bound_b]~^^ ERROR compilation successful
-LL | | //[bound_inv_a_vs_bound_inv_b]~^^^ ERROR compilation successful
-LL | | //[bound_co_a_vs_bound_co_b]~^^^^ ERROR compilation successful
-LL | | //[free_x_vs_free_x]~^^^^^ ERROR compilation successful
+LL | |
+LL | |
+LL | |
+LL | |
+LL | |
LL | | }
| |_^
diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_b.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_b.stderr
index 5fcb63e..9ec36f4 100644
--- a/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_b.stderr
+++ b/src/test/ui/hr-subtype/hr-subtype.bound_a_vs_bound_b.stderr
@@ -2,11 +2,11 @@
--> $DIR/hr-subtype.rs:100:1
|
LL | / fn main() {
-LL | | //[bound_a_vs_bound_a]~^ ERROR compilation successful
-LL | | //[bound_a_vs_bound_b]~^^ ERROR compilation successful
-LL | | //[bound_inv_a_vs_bound_inv_b]~^^^ ERROR compilation successful
-LL | | //[bound_co_a_vs_bound_co_b]~^^^^ ERROR compilation successful
-LL | | //[free_x_vs_free_x]~^^^^^ ERROR compilation successful
+LL | |
+LL | |
+LL | |
+LL | |
+LL | |
LL | | }
| |_^
diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_co_a_vs_bound_co_b.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_co_a_vs_bound_co_b.stderr
index 5fcb63e..9ec36f4 100644
--- a/src/test/ui/hr-subtype/hr-subtype.bound_co_a_vs_bound_co_b.stderr
+++ b/src/test/ui/hr-subtype/hr-subtype.bound_co_a_vs_bound_co_b.stderr
@@ -2,11 +2,11 @@
--> $DIR/hr-subtype.rs:100:1
|
LL | / fn main() {
-LL | | //[bound_a_vs_bound_a]~^ ERROR compilation successful
-LL | | //[bound_a_vs_bound_b]~^^ ERROR compilation successful
-LL | | //[bound_inv_a_vs_bound_inv_b]~^^^ ERROR compilation successful
-LL | | //[bound_co_a_vs_bound_co_b]~^^^^ ERROR compilation successful
-LL | | //[free_x_vs_free_x]~^^^^^ ERROR compilation successful
+LL | |
+LL | |
+LL | |
+LL | |
+LL | |
LL | | }
| |_^
diff --git a/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_vs_bound_inv_b.stderr b/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_vs_bound_inv_b.stderr
index 5fcb63e..9ec36f4 100644
--- a/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_vs_bound_inv_b.stderr
+++ b/src/test/ui/hr-subtype/hr-subtype.bound_inv_a_vs_bound_inv_b.stderr
@@ -2,11 +2,11 @@
--> $DIR/hr-subtype.rs:100:1
|
LL | / fn main() {
-LL | | //[bound_a_vs_bound_a]~^ ERROR compilation successful
-LL | | //[bound_a_vs_bound_b]~^^ ERROR compilation successful
-LL | | //[bound_inv_a_vs_bound_inv_b]~^^^ ERROR compilation successful
-LL | | //[bound_co_a_vs_bound_co_b]~^^^^ ERROR compilation successful
-LL | | //[free_x_vs_free_x]~^^^^^ ERROR compilation successful
+LL | |
+LL | |
+LL | |
+LL | |
+LL | |
LL | | }
| |_^
diff --git a/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_x.stderr b/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_x.stderr
index 5fcb63e..9ec36f4 100644
--- a/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_x.stderr
+++ b/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_x.stderr
@@ -2,11 +2,11 @@
--> $DIR/hr-subtype.rs:100:1
|
LL | / fn main() {
-LL | | //[bound_a_vs_bound_a]~^ ERROR compilation successful
-LL | | //[bound_a_vs_bound_b]~^^ ERROR compilation successful
-LL | | //[bound_inv_a_vs_bound_inv_b]~^^^ ERROR compilation successful
-LL | | //[bound_co_a_vs_bound_co_b]~^^^^ ERROR compilation successful
-LL | | //[free_x_vs_free_x]~^^^^^ ERROR compilation successful
+LL | |
+LL | |
+LL | |
+LL | |
+LL | |
LL | | }
| |_^
diff --git a/src/test/ui/hrtb/hrtb-identity-fn-borrows.ast.nll.stderr b/src/test/ui/hrtb/hrtb-identity-fn-borrows.ast.nll.stderr
index bbb95e8..2b69b3f 100644
--- a/src/test/ui/hrtb/hrtb-identity-fn-borrows.ast.nll.stderr
+++ b/src/test/ui/hrtb/hrtb-identity-fn-borrows.ast.nll.stderr
@@ -3,7 +3,7 @@
|
LL | let y = f.call(&x);
| -- borrow of `x` occurs here
-LL | x = 5; //[ast]~ ERROR cannot assign
+LL | x = 5;
| ^^^^^ assignment to borrowed `x` occurs here
...
LL | drop(y);
diff --git a/src/test/ui/hrtb/hrtb-identity-fn-borrows.ast.stderr b/src/test/ui/hrtb/hrtb-identity-fn-borrows.ast.stderr
index f6f9200..6f055aa 100644
--- a/src/test/ui/hrtb/hrtb-identity-fn-borrows.ast.stderr
+++ b/src/test/ui/hrtb/hrtb-identity-fn-borrows.ast.stderr
@@ -3,7 +3,7 @@
|
LL | let y = f.call(&x);
| - borrow of `x` occurs here
-LL | x = 5; //[ast]~ ERROR cannot assign
+LL | x = 5;
| ^^^^^ assignment to borrowed `x` occurs here
error: aborting due to previous error
diff --git a/src/test/ui/hrtb/hrtb-identity-fn-borrows.mir.stderr b/src/test/ui/hrtb/hrtb-identity-fn-borrows.mir.stderr
index bbb95e8..2b69b3f 100644
--- a/src/test/ui/hrtb/hrtb-identity-fn-borrows.mir.stderr
+++ b/src/test/ui/hrtb/hrtb-identity-fn-borrows.mir.stderr
@@ -3,7 +3,7 @@
|
LL | let y = f.call(&x);
| -- borrow of `x` occurs here
-LL | x = 5; //[ast]~ ERROR cannot assign
+LL | x = 5;
| ^^^^^ assignment to borrowed `x` occurs here
...
LL | drop(y);
diff --git a/src/test/ui/if/if-without-else-as-fn-expr.rs b/src/test/ui/if/if-without-else-as-fn-expr.rs
new file mode 100644
index 0000000..67e4445
--- /dev/null
+++ b/src/test/ui/if/if-without-else-as-fn-expr.rs
@@ -0,0 +1,25 @@
+fn foo(bar: usize) -> usize {
+ if bar % 5 == 0 {
+ return 3;
+ }
+ //~^^^ ERROR if may be missing an else clause
+}
+
+fn foo2(bar: usize) -> usize {
+ let x: usize = if bar % 5 == 0 {
+ return 3;
+ };
+ //~^^^ ERROR if may be missing an else clause
+ x
+}
+
+fn foo3(bar: usize) -> usize {
+ if bar % 5 == 0 {
+ 3
+ }
+ //~^^^ ERROR if may be missing an else clause
+}
+
+fn main() {
+ let _ = foo(1);
+}
diff --git a/src/test/ui/if/if-without-else-as-fn-expr.stderr b/src/test/ui/if/if-without-else-as-fn-expr.stderr
new file mode 100644
index 0000000..0ba7272
--- /dev/null
+++ b/src/test/ui/if/if-without-else-as-fn-expr.stderr
@@ -0,0 +1,49 @@
+error[E0317]: if may be missing an else clause
+ --> $DIR/if-without-else-as-fn-expr.rs:2:5
+ |
+LL | fn foo(bar: usize) -> usize {
+ | ----- expected `usize` because of this return type
+LL | / if bar % 5 == 0 {
+LL | | return 3;
+LL | | }
+ | |_____^ expected usize, found ()
+ |
+ = note: expected type `usize`
+ found type `()`
+ = note: `if` expressions without `else` evaluate to `()`
+ = help: consider adding an `else` block that evaluates to the expected type
+
+error[E0317]: if may be missing an else clause
+ --> $DIR/if-without-else-as-fn-expr.rs:9:20
+ |
+LL | let x: usize = if bar % 5 == 0 {
+ | _________-__________^
+ | | |
+ | | expected because of this assignment
+LL | | return 3;
+LL | | };
+ | |_____^ expected usize, found ()
+ |
+ = note: expected type `usize`
+ found type `()`
+ = note: `if` expressions without `else` evaluate to `()`
+ = help: consider adding an `else` block that evaluates to the expected type
+
+error[E0317]: if may be missing an else clause
+ --> $DIR/if-without-else-as-fn-expr.rs:17:5
+ |
+LL | fn foo3(bar: usize) -> usize {
+ | ----- expected `usize` because of this return type
+LL | / if bar % 5 == 0 {
+LL | | 3
+LL | | }
+ | |_____^ expected usize, found ()
+ |
+ = note: expected type `usize`
+ found type `()`
+ = note: `if` expressions without `else` evaluate to `()`
+ = help: consider adding an `else` block that evaluates to the expected type
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0317`.
diff --git a/src/test/ui/if/if-without-else-result.stderr b/src/test/ui/if/if-without-else-result.stderr
index 2134781..ddb013a 100644
--- a/src/test/ui/if/if-without-else-result.stderr
+++ b/src/test/ui/if/if-without-else-result.stderr
@@ -2,10 +2,15 @@
--> $DIR/if-without-else-result.rs:2:13
|
LL | let a = if true { true };
- | ^^^^^^^^^^^^^^^^ expected (), found bool
+ | ^^^^^^^^^^----^^
+ | | |
+ | | found here
+ | expected (), found bool
|
= note: expected type `()`
found type `bool`
+ = note: `if` expressions without `else` evaluate to `()`
+ = help: consider adding an `else` block that evaluates to the expected type
error: aborting due to previous error
diff --git a/src/test/ui/immut-function-arguments.ast.nll.stderr b/src/test/ui/immut-function-arguments.ast.nll.stderr
index f016339..5085f36 100644
--- a/src/test/ui/immut-function-arguments.ast.nll.stderr
+++ b/src/test/ui/immut-function-arguments.ast.nll.stderr
@@ -3,13 +3,13 @@
|
LL | fn f(y: Box<isize>) {
| - help: consider changing this to be mutable: `mut y`
-LL | *y = 5; //[ast]~ ERROR cannot assign
+LL | *y = 5;
| ^^^^^^ cannot assign
error[E0594]: cannot assign to `*q`, as `q` is not declared as mutable
--> $DIR/immut-function-arguments.rs:10:35
|
-LL | let _frob = |q: Box<isize>| { *q = 2; }; //[ast]~ ERROR cannot assign
+LL | let _frob = |q: Box<isize>| { *q = 2; };
| - ^^^^^^ cannot assign
| |
| help: consider changing this to be mutable: `mut q`
diff --git a/src/test/ui/immut-function-arguments.ast.stderr b/src/test/ui/immut-function-arguments.ast.stderr
index 1ffe569..f371a13 100644
--- a/src/test/ui/immut-function-arguments.ast.stderr
+++ b/src/test/ui/immut-function-arguments.ast.stderr
@@ -3,13 +3,13 @@
|
LL | fn f(y: Box<isize>) {
| - help: make this binding mutable: `mut y`
-LL | *y = 5; //[ast]~ ERROR cannot assign
+LL | *y = 5;
| ^^^^^^ cannot borrow as mutable
error[E0594]: cannot assign to immutable `Box` content `*q`
--> $DIR/immut-function-arguments.rs:10:35
|
-LL | let _frob = |q: Box<isize>| { *q = 2; }; //[ast]~ ERROR cannot assign
+LL | let _frob = |q: Box<isize>| { *q = 2; };
| - ^^^^^^ cannot borrow as mutable
| |
| help: make this binding mutable: `mut q`
diff --git a/src/test/ui/immut-function-arguments.mir.stderr b/src/test/ui/immut-function-arguments.mir.stderr
index f016339..5085f36 100644
--- a/src/test/ui/immut-function-arguments.mir.stderr
+++ b/src/test/ui/immut-function-arguments.mir.stderr
@@ -3,13 +3,13 @@
|
LL | fn f(y: Box<isize>) {
| - help: consider changing this to be mutable: `mut y`
-LL | *y = 5; //[ast]~ ERROR cannot assign
+LL | *y = 5;
| ^^^^^^ cannot assign
error[E0594]: cannot assign to `*q`, as `q` is not declared as mutable
--> $DIR/immut-function-arguments.rs:10:35
|
-LL | let _frob = |q: Box<isize>| { *q = 2; }; //[ast]~ ERROR cannot assign
+LL | let _frob = |q: Box<isize>| { *q = 2; };
| - ^^^^^^ cannot assign
| |
| help: consider changing this to be mutable: `mut q`
diff --git a/src/test/ui/issues/issue-10536.rs b/src/test/ui/issues/issue-10536.rs
index 95c8c2b..ceb44ec 100644
--- a/src/test/ui/issues/issue-10536.rs
+++ b/src/test/ui/issues/issue-10536.rs
@@ -12,7 +12,7 @@
foo!();
assert!({one! two()});
- //~^ ERROR macros that expand to items must either be surrounded with braces or followed by a
+ //~^ ERROR macros that expand to items
//~| ERROR cannot find macro `one!` in this scope
//~| ERROR mismatched types
diff --git a/src/test/ui/issues/issue-10536.stderr b/src/test/ui/issues/issue-10536.stderr
index d5caf77..584cdf4 100644
--- a/src/test/ui/issues/issue-10536.stderr
+++ b/src/test/ui/issues/issue-10536.stderr
@@ -1,8 +1,16 @@
-error: macros that expand to items must either be surrounded with braces or followed by a semicolon
+error: macros that expand to items must be delimited with braces or followed by a semicolon
--> $DIR/issue-10536.rs:14:22
|
LL | assert!({one! two()});
| ^^
+help: change the delimiters to curly braces
+ |
+LL | assert!({one! two {}});
+ | ^^
+help: add a semicolon
+ |
+LL | assert!({one! two();});
+ | ^
error: expected `(` or `{`, found `}`
--> $DIR/issue-10536.rs:21:22
diff --git a/src/test/ui/issues/issue-17263.nll.stderr b/src/test/ui/issues/issue-17263.nll.stderr
index cdb574b..5604037 100644
--- a/src/test/ui/issues/issue-17263.nll.stderr
+++ b/src/test/ui/issues/issue-17263.nll.stderr
@@ -1,10 +1,10 @@
error: compilation successful
--> $DIR/issue-17263.rs:15:1
|
-LL | / fn main() { //[nll]~ ERROR compilation successful
+LL | / fn main() {
LL | | let mut x: Box<_> = box Foo { a: 1, b: 2 };
LL | | let (a, b) = (&mut x.a, &mut x.b);
-LL | | //[ast]~^ ERROR cannot borrow `x` (via `x.b`) as mutable more than once at a time
+LL | |
... |
LL | | use_mut(a);
LL | | }
diff --git a/src/test/ui/issues/issue-21950.stderr b/src/test/ui/issues/issue-21950.stderr
index 5f401d1..bda2e3c 100644
--- a/src/test/ui/issues/issue-21950.stderr
+++ b/src/test/ui/issues/issue-21950.stderr
@@ -1,8 +1,8 @@
-error[E0393]: the type parameter `RHS` must be explicitly specified
+error[E0393]: the type parameter `Rhs` must be explicitly specified
--> $DIR/issue-21950.rs:7:14
|
LL | &Add;
- | ^^^ missing reference to `RHS`
+ | ^^^ missing reference to `Rhs`
|
= note: because of the default `Self` reference, type parameters must be specified on object types
diff --git a/src/test/ui/issues/issue-22560.stderr b/src/test/ui/issues/issue-22560.stderr
index be4f3dd..694a4af 100644
--- a/src/test/ui/issues/issue-22560.stderr
+++ b/src/test/ui/issues/issue-22560.stderr
@@ -1,16 +1,16 @@
-error[E0393]: the type parameter `RHS` must be explicitly specified
+error[E0393]: the type parameter `Rhs` must be explicitly specified
--> $DIR/issue-22560.rs:5:13
|
LL | type Test = Add +
- | ^^^ missing reference to `RHS`
+ | ^^^ missing reference to `Rhs`
|
= note: because of the default `Self` reference, type parameters must be specified on object types
-error[E0393]: the type parameter `RHS` must be explicitly specified
+error[E0393]: the type parameter `Rhs` must be explicitly specified
--> $DIR/issue-22560.rs:8:13
|
LL | Sub;
- | ^^^ missing reference to `RHS`
+ | ^^^ missing reference to `Rhs`
|
= note: because of the default `Self` reference, type parameters must be specified on object types
diff --git a/src/test/ui/issues/issue-22706.rs b/src/test/ui/issues/issue-22706.rs
index 413a0d9..28e8a72 100644
--- a/src/test/ui/issues/issue-22706.rs
+++ b/src/test/ui/issues/issue-22706.rs
@@ -1,3 +1,3 @@
fn is_copy<T: ::std::marker<i32>::Copy>() {}
-//~^ ERROR type arguments are not allowed on this entity [E0109]
+//~^ ERROR type arguments are not allowed for this type [E0109]
fn main() {}
diff --git a/src/test/ui/issues/issue-22706.stderr b/src/test/ui/issues/issue-22706.stderr
index a3cf716..c592939 100644
--- a/src/test/ui/issues/issue-22706.stderr
+++ b/src/test/ui/issues/issue-22706.stderr
@@ -1,4 +1,4 @@
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/issue-22706.rs:1:29
|
LL | fn is_copy<T: ::std::marker<i32>::Copy>() {}
diff --git a/src/test/ui/issues/issue-25579.ast.nll.stderr b/src/test/ui/issues/issue-25579.ast.nll.stderr
index b791f60..107f88b 100644
--- a/src/test/ui/issues/issue-25579.ast.nll.stderr
+++ b/src/test/ui/issues/issue-25579.ast.nll.stderr
@@ -1,7 +1,7 @@
error: compilation successful
--> $DIR/issue-25579.rs:21:1
|
-LL | / fn main() { //[mir]~ ERROR compilation successful
+LL | / fn main() {
LL | | }
| |_^
diff --git a/src/test/ui/issues/issue-25579.ast.stderr b/src/test/ui/issues/issue-25579.ast.stderr
index 3de7f56..a44cc95 100644
--- a/src/test/ui/issues/issue-25579.ast.stderr
+++ b/src/test/ui/issues/issue-25579.ast.stderr
@@ -1,7 +1,7 @@
error[E0499]: cannot borrow `l.0` as mutable more than once at a time
--> $DIR/issue-25579.rs:14:32
|
-LL | &mut Sexpression::Cons(ref mut expr) => { //[ast]~ ERROR [E0499]
+LL | &mut Sexpression::Cons(ref mut expr) => {
| ^^^^^^^^^^^^ mutable borrow starts here in previous iteration of loop
...
LL | }
@@ -10,9 +10,9 @@
error[E0506]: cannot assign to `l` because it is borrowed
--> $DIR/issue-25579.rs:15:13
|
-LL | &mut Sexpression::Cons(ref mut expr) => { //[ast]~ ERROR [E0499]
+LL | &mut Sexpression::Cons(ref mut expr) => {
| ------------ borrow of `l` occurs here
-LL | l = &mut **expr; //[ast]~ ERROR [E0506]
+LL | l = &mut **expr;
| ^^^^^^^^^^^^^^^ assignment to borrowed `l` occurs here
error: aborting due to 2 previous errors
diff --git a/src/test/ui/issues/issue-25579.mir.stderr b/src/test/ui/issues/issue-25579.mir.stderr
index b791f60..107f88b 100644
--- a/src/test/ui/issues/issue-25579.mir.stderr
+++ b/src/test/ui/issues/issue-25579.mir.stderr
@@ -1,7 +1,7 @@
error: compilation successful
--> $DIR/issue-25579.rs:21:1
|
-LL | / fn main() { //[mir]~ ERROR compilation successful
+LL | / fn main() {
LL | | }
| |_^
diff --git a/src/test/ui/issues/issue-28433.rs b/src/test/ui/issues/issue-28433.rs
index a87ac63..2bbb32b 100644
--- a/src/test/ui/issues/issue-28433.rs
+++ b/src/test/ui/issues/issue-28433.rs
@@ -1,13 +1,14 @@
// compile-flags: -Z continue-parse-after-error
-enum bird {
- pub duck,
- //~^ ERROR: expected identifier, found keyword `pub`
- //~| ERROR: expected
- goose
+enum Bird {
+ pub Duck,
+ //~^ ERROR unnecessary visibility qualifier
+ Goose,
+ pub(crate) Dove
+ //~^ ERROR unnecessary visibility qualifier
}
fn main() {
- let y = bird::goose;
+ let y = Bird::Goose;
}
diff --git a/src/test/ui/issues/issue-28433.stderr b/src/test/ui/issues/issue-28433.stderr
index d3cba3a..cfdbf6c 100644
--- a/src/test/ui/issues/issue-28433.stderr
+++ b/src/test/ui/issues/issue-28433.stderr
@@ -1,18 +1,14 @@
-error: expected identifier, found keyword `pub`
+error: unnecessary visibility qualifier
--> $DIR/issue-28433.rs:4:5
|
-LL | pub duck,
- | ^^^ expected identifier, found keyword
-help: you can escape reserved keywords to use them as identifiers
- |
-LL | r#pub duck,
- | ^^^^^
+LL | pub Duck,
+ | ^^^ `pub` not permitted here
-error: expected one of `(`, `,`, `=`, `{`, or `}`, found `duck`
- --> $DIR/issue-28433.rs:4:9
+error: unnecessary visibility qualifier
+ --> $DIR/issue-28433.rs:7:5
|
-LL | pub duck,
- | ^^^^ expected one of `(`, `,`, `=`, `{`, or `}` here
+LL | pub(crate) Dove
+ | ^^^^^^^^^^ `pub` not permitted here
error: aborting due to 2 previous errors
diff --git a/src/test/ui/issues/issue-4201.stderr b/src/test/ui/issues/issue-4201.stderr
index d436c92..dd76fae 100644
--- a/src/test/ui/issues/issue-4201.stderr
+++ b/src/test/ui/issues/issue-4201.stderr
@@ -8,11 +8,14 @@
LL | |
LL | |
LL | | 1
+ | | - found here
LL | | };
| |_____^ expected (), found integer
|
= note: expected type `()`
found type `{integer}`
+ = note: `if` expressions without `else` evaluate to `()`
+ = help: consider adding an `else` block that evaluates to the expected type
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-45199.ast.nll.stderr b/src/test/ui/issues/issue-45199.ast.nll.stderr
index 6d6af83..c6ae7c9 100644
--- a/src/test/ui/issues/issue-45199.ast.nll.stderr
+++ b/src/test/ui/issues/issue-45199.ast.nll.stderr
@@ -4,31 +4,31 @@
LL | let b: Box<isize>;
| - help: make this binding mutable: `mut b`
...
-LL | b = Box::new(1); //[ast]~ NOTE first assignment
+LL | b = Box::new(1);
| - first assignment to `b`
-LL | //[mir]~^ NOTE first assignment
-LL | b = Box::new(2); //[ast]~ ERROR cannot assign twice to immutable variable
+LL |
+LL | b = Box::new(2);
| ^ cannot assign twice to immutable variable
error[E0384]: cannot assign twice to immutable variable `b`
--> $DIR/issue-45199.rs:21:5
|
-LL | let b = Box::new(1); //[ast]~ NOTE first assignment
+LL | let b = Box::new(1);
| -
| |
| first assignment to `b`
| help: make this binding mutable: `mut b`
...
-LL | b = Box::new(2); //[ast]~ ERROR cannot assign twice to immutable variable
+LL | b = Box::new(2);
| ^ cannot assign twice to immutable variable
error[E0384]: cannot assign to immutable argument `b`
--> $DIR/issue-45199.rs:30:5
|
-LL | fn test_args(b: Box<i32>) { //[ast]~ NOTE first assignment
+LL | fn test_args(b: Box<i32>) {
| - help: make this binding mutable: `mut b`
...
-LL | b = Box::new(2); //[ast]~ ERROR cannot assign twice to immutable variable
+LL | b = Box::new(2);
| ^ cannot assign to immutable argument
error: aborting due to 3 previous errors
diff --git a/src/test/ui/issues/issue-45199.ast.stderr b/src/test/ui/issues/issue-45199.ast.stderr
index fa9d8e0..9dfd8e8 100644
--- a/src/test/ui/issues/issue-45199.ast.stderr
+++ b/src/test/ui/issues/issue-45199.ast.stderr
@@ -1,28 +1,28 @@
error[E0384]: cannot assign twice to immutable variable `b`
--> $DIR/issue-45199.rs:10:5
|
-LL | b = Box::new(1); //[ast]~ NOTE first assignment
+LL | b = Box::new(1);
| --------------- first assignment to `b`
-LL | //[mir]~^ NOTE first assignment
-LL | b = Box::new(2); //[ast]~ ERROR cannot assign twice to immutable variable
+LL |
+LL | b = Box::new(2);
| ^^^^^^^^^^^^^^^ cannot assign twice to immutable variable
error[E0384]: cannot assign twice to immutable variable `b`
--> $DIR/issue-45199.rs:21:5
|
-LL | let b = Box::new(1); //[ast]~ NOTE first assignment
+LL | let b = Box::new(1);
| - first assignment to `b`
...
-LL | b = Box::new(2); //[ast]~ ERROR cannot assign twice to immutable variable
+LL | b = Box::new(2);
| ^^^^^^^^^^^^^^^ cannot assign twice to immutable variable
error[E0384]: cannot assign twice to immutable variable `b`
--> $DIR/issue-45199.rs:30:5
|
-LL | fn test_args(b: Box<i32>) { //[ast]~ NOTE first assignment
+LL | fn test_args(b: Box<i32>) {
| - first assignment to `b`
...
-LL | b = Box::new(2); //[ast]~ ERROR cannot assign twice to immutable variable
+LL | b = Box::new(2);
| ^^^^^^^^^^^^^^^ cannot assign twice to immutable variable
error: aborting due to 3 previous errors
diff --git a/src/test/ui/issues/issue-45199.mir.stderr b/src/test/ui/issues/issue-45199.mir.stderr
index 6d6af83..c6ae7c9 100644
--- a/src/test/ui/issues/issue-45199.mir.stderr
+++ b/src/test/ui/issues/issue-45199.mir.stderr
@@ -4,31 +4,31 @@
LL | let b: Box<isize>;
| - help: make this binding mutable: `mut b`
...
-LL | b = Box::new(1); //[ast]~ NOTE first assignment
+LL | b = Box::new(1);
| - first assignment to `b`
-LL | //[mir]~^ NOTE first assignment
-LL | b = Box::new(2); //[ast]~ ERROR cannot assign twice to immutable variable
+LL |
+LL | b = Box::new(2);
| ^ cannot assign twice to immutable variable
error[E0384]: cannot assign twice to immutable variable `b`
--> $DIR/issue-45199.rs:21:5
|
-LL | let b = Box::new(1); //[ast]~ NOTE first assignment
+LL | let b = Box::new(1);
| -
| |
| first assignment to `b`
| help: make this binding mutable: `mut b`
...
-LL | b = Box::new(2); //[ast]~ ERROR cannot assign twice to immutable variable
+LL | b = Box::new(2);
| ^ cannot assign twice to immutable variable
error[E0384]: cannot assign to immutable argument `b`
--> $DIR/issue-45199.rs:30:5
|
-LL | fn test_args(b: Box<i32>) { //[ast]~ NOTE first assignment
+LL | fn test_args(b: Box<i32>) {
| - help: make this binding mutable: `mut b`
...
-LL | b = Box::new(2); //[ast]~ ERROR cannot assign twice to immutable variable
+LL | b = Box::new(2);
| ^ cannot assign to immutable argument
error: aborting due to 3 previous errors
diff --git a/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.ast.stderr b/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.ast.stderr
index 1992e32..0aaba52 100644
--- a/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.ast.stderr
+++ b/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.ast.stderr
@@ -1,8 +1,8 @@
error: compilation successful
--> $DIR/issue-45696-scribble-on-boxed-borrow.rs:82:1
|
-LL | / fn main() { //[ast]~ ERROR compilation successful
-LL | | //[migrate]~^ ERROR compilation successful
+LL | / fn main() {
+LL | |
LL | | let mut x = 1;
LL | | {
... |
diff --git a/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.migrate.stderr b/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.migrate.stderr
index 129c629..f8aab23 100644
--- a/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.migrate.stderr
+++ b/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.migrate.stderr
@@ -3,7 +3,7 @@
|
LL | fn scribbled<'a>(s: Scribble<'a>) -> &'a mut u32 {
| -- lifetime `'a` defined here
-LL | &mut *s.0 //[nll]~ ERROR borrow may still be in use when destructor runs [E0713]
+LL | &mut *s.0
| ^^^^^^^^^ returning this value requires that `*s.0` is borrowed for `'a`
...
LL | }
@@ -17,7 +17,7 @@
|
LL | fn boxed_scribbled<'a>(s: Box<Scribble<'a>>) -> &'a mut u32 {
| -- lifetime `'a` defined here
-LL | &mut *(*s).0 //[nll]~ ERROR borrow may still be in use when destructor runs [E0713]
+LL | &mut *(*s).0
| ^^^^^^^^^^^^ returning this value requires that `*s.0` is borrowed for `'a`
...
LL | }
@@ -31,7 +31,7 @@
|
LL | fn boxed_boxed_scribbled<'a>(s: Box<Box<Scribble<'a>>>) -> &'a mut u32 {
| -- lifetime `'a` defined here
-LL | &mut *(**s).0 //[nll]~ ERROR borrow may still be in use when destructor runs [E0713]
+LL | &mut *(**s).0
| ^^^^^^^^^^^^^ returning this value requires that `*s.0` is borrowed for `'a`
...
LL | }
@@ -43,8 +43,8 @@
error: compilation successful
--> $DIR/issue-45696-scribble-on-boxed-borrow.rs:82:1
|
-LL | / fn main() { //[ast]~ ERROR compilation successful
-LL | | //[migrate]~^ ERROR compilation successful
+LL | / fn main() {
+LL | |
LL | | let mut x = 1;
LL | | {
... |
diff --git a/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.nll.stderr b/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.nll.stderr
index 2cb07f0..bfb5832 100644
--- a/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.nll.stderr
+++ b/src/test/ui/issues/issue-45696-scribble-on-boxed-borrow.nll.stderr
@@ -3,7 +3,7 @@
|
LL | fn scribbled<'a>(s: Scribble<'a>) -> &'a mut u32 {
| -- lifetime `'a` defined here
-LL | &mut *s.0 //[nll]~ ERROR borrow may still be in use when destructor runs [E0713]
+LL | &mut *s.0
| ^^^^^^^^^ returning this value requires that `*s.0` is borrowed for `'a`
...
LL | }
@@ -14,7 +14,7 @@
|
LL | fn boxed_scribbled<'a>(s: Box<Scribble<'a>>) -> &'a mut u32 {
| -- lifetime `'a` defined here
-LL | &mut *(*s).0 //[nll]~ ERROR borrow may still be in use when destructor runs [E0713]
+LL | &mut *(*s).0
| ^^^^^^^^^^^^ returning this value requires that `*s.0` is borrowed for `'a`
...
LL | }
@@ -25,7 +25,7 @@
|
LL | fn boxed_boxed_scribbled<'a>(s: Box<Box<Scribble<'a>>>) -> &'a mut u32 {
| -- lifetime `'a` defined here
-LL | &mut *(**s).0 //[nll]~ ERROR borrow may still be in use when destructor runs [E0713]
+LL | &mut *(**s).0
| ^^^^^^^^^^^^^ returning this value requires that `*s.0` is borrowed for `'a`
...
LL | }
diff --git a/src/test/ui/issues/issue-46604.ast.nll.stderr b/src/test/ui/issues/issue-46604.ast.nll.stderr
index 4f73a0f..f43588c 100644
--- a/src/test/ui/issues/issue-46604.ast.nll.stderr
+++ b/src/test/ui/issues/issue-46604.ast.nll.stderr
@@ -1,13 +1,13 @@
error[E0017]: references in statics may only refer to immutable values
--> $DIR/issue-46604.rs:4:25
|
-LL | static buf: &mut [u8] = &mut [1u8,2,3,4,5,7]; //[ast]~ ERROR E0017
+LL | static buf: &mut [u8] = &mut [1u8,2,3,4,5,7];
| ^^^^^^^^^^^^^^^^^^^^ statics require immutable values
error[E0594]: cannot assign to `buf[_]`, as `buf` is an immutable static item
--> $DIR/issue-46604.rs:10:5
|
-LL | buf[0]=2; //[ast]~ ERROR E0389
+LL | buf[0]=2;
| ^^^^^^^^ cannot assign
error: aborting due to 2 previous errors
diff --git a/src/test/ui/issues/issue-46604.ast.stderr b/src/test/ui/issues/issue-46604.ast.stderr
index 14b9242..2ee1ac2 100644
--- a/src/test/ui/issues/issue-46604.ast.stderr
+++ b/src/test/ui/issues/issue-46604.ast.stderr
@@ -1,13 +1,13 @@
error[E0017]: references in statics may only refer to immutable values
--> $DIR/issue-46604.rs:4:25
|
-LL | static buf: &mut [u8] = &mut [1u8,2,3,4,5,7]; //[ast]~ ERROR E0017
+LL | static buf: &mut [u8] = &mut [1u8,2,3,4,5,7];
| ^^^^^^^^^^^^^^^^^^^^ statics require immutable values
error[E0389]: cannot assign to data in a `&` reference
--> $DIR/issue-46604.rs:10:5
|
-LL | buf[0]=2; //[ast]~ ERROR E0389
+LL | buf[0]=2;
| ^^^^^^^^ assignment into an immutable reference
error: aborting due to 2 previous errors
diff --git a/src/test/ui/issues/issue-46604.mir.stderr b/src/test/ui/issues/issue-46604.mir.stderr
index 4f73a0f..f43588c 100644
--- a/src/test/ui/issues/issue-46604.mir.stderr
+++ b/src/test/ui/issues/issue-46604.mir.stderr
@@ -1,13 +1,13 @@
error[E0017]: references in statics may only refer to immutable values
--> $DIR/issue-46604.rs:4:25
|
-LL | static buf: &mut [u8] = &mut [1u8,2,3,4,5,7]; //[ast]~ ERROR E0017
+LL | static buf: &mut [u8] = &mut [1u8,2,3,4,5,7];
| ^^^^^^^^^^^^^^^^^^^^ statics require immutable values
error[E0594]: cannot assign to `buf[_]`, as `buf` is an immutable static item
--> $DIR/issue-46604.rs:10:5
|
-LL | buf[0]=2; //[ast]~ ERROR E0389
+LL | buf[0]=2;
| ^^^^^^^^ cannot assign
error: aborting due to 2 previous errors
diff --git a/src/test/ui/issues/issue-50577.stderr b/src/test/ui/issues/issue-50577.stderr
index f26f5a9..0c3ba2e 100644
--- a/src/test/ui/issues/issue-50577.stderr
+++ b/src/test/ui/issues/issue-50577.stderr
@@ -2,10 +2,15 @@
--> $DIR/issue-50577.rs:3:16
|
LL | Drop = assert_eq!(1, 1)
- | ^^^^^^^^^^^^^^^^ expected (), found isize
+ | ^^^^^^^^^^^^^^^^
+ | |
+ | expected (), found isize
+ | found here
|
= note: expected type `()`
found type `isize`
+ = note: `if` expressions without `else` evaluate to `()`
+ = help: consider adding an `else` block that evaluates to the expected type
= 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: aborting due to previous error
diff --git a/src/test/ui/issues/issue-5500-1.ast.stderr b/src/test/ui/issues/issue-5500-1.ast.stderr
index 681ccbc..558e7b7 100644
--- a/src/test/ui/issues/issue-5500-1.ast.stderr
+++ b/src/test/ui/issues/issue-5500-1.ast.stderr
@@ -3,8 +3,8 @@
|
LL | let _iter = TrieMapIterator{node: &a};
| ----- help: make this binding mutable: `mut _iter`
-LL | / _iter.node = & //[ast]~ ERROR cannot assign to field `_iter.node` of immutable binding
-LL | | //[mir]~^ ERROR cannot assign to field `_iter.node` of immutable binding (Ast)
+LL | / _iter.node = &
+LL | |
LL | | // MIR doesn't generate an error because the code isn't reachable. This is OK
LL | | // because the test is here to check that the compiler doesn't ICE (cf. #5500).
LL | | panic!()
diff --git a/src/test/ui/issues/issue-5500-1.mir.stderr b/src/test/ui/issues/issue-5500-1.mir.stderr
index 67ca23c..92f803e 100644
--- a/src/test/ui/issues/issue-5500-1.mir.stderr
+++ b/src/test/ui/issues/issue-5500-1.mir.stderr
@@ -3,8 +3,8 @@
|
LL | let _iter = TrieMapIterator{node: &a};
| ----- help: make this binding mutable: `mut _iter`
-LL | / _iter.node = & //[ast]~ ERROR cannot assign to field `_iter.node` of immutable binding
-LL | | //[mir]~^ ERROR cannot assign to field `_iter.node` of immutable binding (Ast)
+LL | / _iter.node = &
+LL | |
LL | | // MIR doesn't generate an error because the code isn't reachable. This is OK
LL | | // because the test is here to check that the compiler doesn't ICE (cf. #5500).
LL | | panic!()
diff --git a/src/test/ui/issues/issue-56031.rs b/src/test/ui/issues/issue-56031.rs
new file mode 100644
index 0000000..b68f568
--- /dev/null
+++ b/src/test/ui/issues/issue-56031.rs
@@ -0,0 +1,6 @@
+struct T;
+
+impl for T {}
+//~^ ERROR missing trait in a trait impl
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-56031.stderr b/src/test/ui/issues/issue-56031.stderr
new file mode 100644
index 0000000..3d7acee
--- /dev/null
+++ b/src/test/ui/issues/issue-56031.stderr
@@ -0,0 +1,8 @@
+error: missing trait in a trait impl
+ --> $DIR/issue-56031.rs:3:5
+ |
+LL | impl for T {}
+ | ^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/issues/issue-59029-1.rs b/src/test/ui/issues/issue-59029-1.rs
new file mode 100644
index 0000000..e98a4d0
--- /dev/null
+++ b/src/test/ui/issues/issue-59029-1.rs
@@ -0,0 +1,8 @@
+#![feature(trait_alias)]
+
+trait Svc<Req> { type Res; }
+
+trait MkSvc<Target, Req> = Svc<Target> where Self::Res: Svc<Req>;
+//~^ ERROR associated type `Res` not found for `Self`
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-59029-1.stderr b/src/test/ui/issues/issue-59029-1.stderr
new file mode 100644
index 0000000..ed1d98c
--- /dev/null
+++ b/src/test/ui/issues/issue-59029-1.stderr
@@ -0,0 +1,9 @@
+error[E0220]: associated type `Res` not found for `Self`
+ --> $DIR/issue-59029-1.rs:5:46
+ |
+LL | trait MkSvc<Target, Req> = Svc<Target> where Self::Res: Svc<Req>;
+ | ^^^^^^^^^ associated type `Res` not found
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0220`.
diff --git a/src/test/ui/issues/issue-59029-2.rs b/src/test/ui/issues/issue-59029-2.rs
new file mode 100644
index 0000000..2bdb128
--- /dev/null
+++ b/src/test/ui/issues/issue-59029-2.rs
@@ -0,0 +1,8 @@
+// run-pass
+#![feature(trait_alias)]
+
+trait Svc<Req> { type Res; }
+
+trait MkSvc<Target, Req> = Svc<Target> where <Self as Svc<Target>>::Res: Svc<Req>;
+
+fn main() {}
diff --git a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.ast.nll.stderr b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.ast.nll.stderr
index 9d24570..8376ee8 100644
--- a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.ast.nll.stderr
+++ b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.ast.nll.stderr
@@ -4,7 +4,7 @@
LL | let v: isize;
| - help: make this binding mutable: `mut v`
...
-LL | v = 1; //[ast]~ ERROR cannot assign twice to immutable variable
+LL | v = 1;
| ^^^^^ cannot assign twice to immutable variable
error: aborting due to previous error
diff --git a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.ast.stderr b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.ast.stderr
index 20003b7..db2a482 100644
--- a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.ast.stderr
+++ b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.ast.stderr
@@ -1,7 +1,7 @@
error[E0384]: cannot assign twice to immutable variable `v`
--> $DIR/liveness-assign-imm-local-in-loop.rs:9:9
|
-LL | v = 1; //[ast]~ ERROR cannot assign twice to immutable variable
+LL | v = 1;
| ^^^^^ cannot assign twice to immutable variable
error: aborting due to previous error
diff --git a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.mir.stderr b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.mir.stderr
index 9d24570..8376ee8 100644
--- a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.mir.stderr
+++ b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-loop.mir.stderr
@@ -4,7 +4,7 @@
LL | let v: isize;
| - help: make this binding mutable: `mut v`
...
-LL | v = 1; //[ast]~ ERROR cannot assign twice to immutable variable
+LL | v = 1;
| ^^^^^ cannot assign twice to immutable variable
error: aborting due to previous error
diff --git a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.ast.nll.stderr b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.ast.nll.stderr
index 47b9b02..a6a1c73a 100644
--- a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.ast.nll.stderr
+++ b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.ast.nll.stderr
@@ -4,10 +4,10 @@
LL | let v: isize;
| - help: make this binding mutable: `mut v`
...
-LL | v = 2; //[ast]~ NOTE first assignment
+LL | v = 2;
| ----- first assignment to `v`
-LL | //[mir]~^ NOTE first assignment
-LL | v += 1; //[ast]~ ERROR cannot assign twice to immutable variable
+LL |
+LL | v += 1;
| ^^^^^^ cannot assign twice to immutable variable
error: aborting due to previous error
diff --git a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.ast.stderr b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.ast.stderr
index 4ab254b..b287edf 100644
--- a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.ast.stderr
+++ b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.ast.stderr
@@ -1,10 +1,10 @@
error[E0384]: cannot assign twice to immutable variable `v`
--> $DIR/liveness-assign-imm-local-in-op-eq.rs:10:5
|
-LL | v = 2; //[ast]~ NOTE first assignment
+LL | v = 2;
| ----- first assignment to `v`
-LL | //[mir]~^ NOTE first assignment
-LL | v += 1; //[ast]~ ERROR cannot assign twice to immutable variable
+LL |
+LL | v += 1;
| ^^^^^^ cannot assign twice to immutable variable
error: aborting due to previous error
diff --git a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.mir.stderr b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.mir.stderr
index 47b9b02..a6a1c73a 100644
--- a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.mir.stderr
+++ b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-in-op-eq.mir.stderr
@@ -4,10 +4,10 @@
LL | let v: isize;
| - help: make this binding mutable: `mut v`
...
-LL | v = 2; //[ast]~ NOTE first assignment
+LL | v = 2;
| ----- first assignment to `v`
-LL | //[mir]~^ NOTE first assignment
-LL | v += 1; //[ast]~ ERROR cannot assign twice to immutable variable
+LL |
+LL | v += 1;
| ^^^^^^ cannot assign twice to immutable variable
error: aborting due to previous error
diff --git a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.ast.nll.stderr b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.ast.nll.stderr
index 08a1e9d..8316ffd 100644
--- a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.ast.nll.stderr
+++ b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.ast.nll.stderr
@@ -1,13 +1,13 @@
error[E0384]: cannot assign twice to immutable variable `b`
--> $DIR/liveness-assign-imm-local-with-drop.rs:10:5
|
-LL | let b = Box::new(1); //[ast]~ NOTE first assignment
+LL | let b = Box::new(1);
| -
| |
| first assignment to `b`
| help: make this binding mutable: `mut b`
...
-LL | b = Box::new(2); //[ast]~ ERROR cannot assign twice to immutable variable
+LL | b = Box::new(2);
| ^ cannot assign twice to immutable variable
error: aborting due to previous error
diff --git a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.ast.stderr b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.ast.stderr
index d543fb9..108ca48 100644
--- a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.ast.stderr
+++ b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.ast.stderr
@@ -1,10 +1,10 @@
error[E0384]: cannot assign twice to immutable variable `b`
--> $DIR/liveness-assign-imm-local-with-drop.rs:10:5
|
-LL | let b = Box::new(1); //[ast]~ NOTE first assignment
+LL | let b = Box::new(1);
| - first assignment to `b`
...
-LL | b = Box::new(2); //[ast]~ ERROR cannot assign twice to immutable variable
+LL | b = Box::new(2);
| ^^^^^^^^^^^^^^^ cannot assign twice to immutable variable
error: aborting due to previous error
diff --git a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.mir.stderr b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.mir.stderr
index 08a1e9d..8316ffd 100644
--- a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.mir.stderr
+++ b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.mir.stderr
@@ -1,13 +1,13 @@
error[E0384]: cannot assign twice to immutable variable `b`
--> $DIR/liveness-assign-imm-local-with-drop.rs:10:5
|
-LL | let b = Box::new(1); //[ast]~ NOTE first assignment
+LL | let b = Box::new(1);
| -
| |
| first assignment to `b`
| help: make this binding mutable: `mut b`
...
-LL | b = Box::new(2); //[ast]~ ERROR cannot assign twice to immutable variable
+LL | b = Box::new(2);
| ^ cannot assign twice to immutable variable
error: aborting due to previous error
diff --git a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.ast.nll.stderr b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.ast.nll.stderr
index 3c1a569..5fa06f9 100644
--- a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.ast.nll.stderr
+++ b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.ast.nll.stderr
@@ -1,13 +1,13 @@
error[E0384]: cannot assign twice to immutable variable `v`
--> $DIR/liveness-assign-imm-local-with-init.rs:10:5
|
-LL | let v: isize = 1; //[ast]~ NOTE first assignment
+LL | let v: isize = 1;
| -
| |
| first assignment to `v`
| help: make this binding mutable: `mut v`
...
-LL | v = 2; //[ast]~ ERROR cannot assign twice to immutable variable
+LL | v = 2;
| ^^^^^ cannot assign twice to immutable variable
error: aborting due to previous error
diff --git a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.ast.stderr b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.ast.stderr
index cf293ae..34fb160 100644
--- a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.ast.stderr
+++ b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.ast.stderr
@@ -1,10 +1,10 @@
error[E0384]: cannot assign twice to immutable variable `v`
--> $DIR/liveness-assign-imm-local-with-init.rs:10:5
|
-LL | let v: isize = 1; //[ast]~ NOTE first assignment
+LL | let v: isize = 1;
| - first assignment to `v`
...
-LL | v = 2; //[ast]~ ERROR cannot assign twice to immutable variable
+LL | v = 2;
| ^^^^^ cannot assign twice to immutable variable
error: aborting due to previous error
diff --git a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.mir.stderr b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.mir.stderr
index 3c1a569..5fa06f9 100644
--- a/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.mir.stderr
+++ b/src/test/ui/liveness/liveness-assign/liveness-assign-imm-local-with-init.mir.stderr
@@ -1,13 +1,13 @@
error[E0384]: cannot assign twice to immutable variable `v`
--> $DIR/liveness-assign-imm-local-with-init.rs:10:5
|
-LL | let v: isize = 1; //[ast]~ NOTE first assignment
+LL | let v: isize = 1;
| -
| |
| first assignment to `v`
| help: make this binding mutable: `mut v`
...
-LL | v = 2; //[ast]~ ERROR cannot assign twice to immutable variable
+LL | v = 2;
| ^^^^^ cannot assign twice to immutable variable
error: aborting due to previous error
diff --git a/src/test/ui/macros/missing-comma.rs b/src/test/ui/macros/missing-comma.rs
index 1e14687..2b411ab 100644
--- a/src/test/ui/macros/missing-comma.rs
+++ b/src/test/ui/macros/missing-comma.rs
@@ -6,6 +6,11 @@
($a:ident, $b:ident, $c:ident, $d:ident, $e:ident) => ();
}
+macro_rules! bar {
+ ($lvl:expr, $($arg:tt)+) => {}
+}
+
+
fn main() {
println!("{}" a);
//~^ ERROR expected token: `,`
@@ -17,4 +22,6 @@
//~^ ERROR no rules expected the token `d`
foo!(a, b, c d e);
//~^ ERROR no rules expected the token `d`
+ bar!(Level::Error, );
+ //~^ ERROR unexpected end of macro invocation
}
diff --git a/src/test/ui/macros/missing-comma.stderr b/src/test/ui/macros/missing-comma.stderr
index 5881e0b..424fefd 100644
--- a/src/test/ui/macros/missing-comma.stderr
+++ b/src/test/ui/macros/missing-comma.stderr
@@ -1,11 +1,11 @@
error: expected token: `,`
- --> $DIR/missing-comma.rs:10:19
+ --> $DIR/missing-comma.rs:15:19
|
LL | println!("{}" a);
| ^
error: no rules expected the token `b`
- --> $DIR/missing-comma.rs:12:12
+ --> $DIR/missing-comma.rs:17:12
|
LL | macro_rules! foo {
| ---------------- when calling this macro
@@ -16,7 +16,7 @@
| help: missing comma here
error: no rules expected the token `e`
- --> $DIR/missing-comma.rs:14:21
+ --> $DIR/missing-comma.rs:19:21
|
LL | macro_rules! foo {
| ---------------- when calling this macro
@@ -27,7 +27,7 @@
| help: missing comma here
error: no rules expected the token `d`
- --> $DIR/missing-comma.rs:16:18
+ --> $DIR/missing-comma.rs:21:18
|
LL | macro_rules! foo {
| ---------------- when calling this macro
@@ -38,7 +38,7 @@
| help: missing comma here
error: no rules expected the token `d`
- --> $DIR/missing-comma.rs:18:18
+ --> $DIR/missing-comma.rs:23:18
|
LL | macro_rules! foo {
| ---------------- when calling this macro
@@ -46,5 +46,14 @@
LL | foo!(a, b, c d e);
| ^ no rules expected this token in macro call
-error: aborting due to 5 previous errors
+error: unexpected end of macro invocation
+ --> $DIR/missing-comma.rs:25:23
+ |
+LL | macro_rules! bar {
+ | ---------------- when calling this macro
+...
+LL | bar!(Level::Error, );
+ | ^ missing tokens in macro arguments
+
+error: aborting due to 6 previous errors
diff --git a/src/test/ui/meta-expected-error-correct-rev.a.stderr b/src/test/ui/meta-expected-error-correct-rev.a.stderr
index b561a9e..901bdcd 100644
--- a/src/test/ui/meta-expected-error-correct-rev.a.stderr
+++ b/src/test/ui/meta-expected-error-correct-rev.a.stderr
@@ -1,7 +1,7 @@
error[E0308]: mismatched types
--> $DIR/meta-expected-error-correct-rev.rs:7:18
|
-LL | let x: u32 = 22_usize; //[a]~ ERROR mismatched types
+LL | let x: u32 = 22_usize;
| ^^^^^^^^ expected u32, found usize
error: aborting due to previous error
diff --git a/src/test/ui/mod-subitem-as-enum-variant.rs b/src/test/ui/mod-subitem-as-enum-variant.rs
index ec809d4..cd4459a 100644
--- a/src/test/ui/mod-subitem-as-enum-variant.rs
+++ b/src/test/ui/mod-subitem-as-enum-variant.rs
@@ -6,5 +6,5 @@
fn main() {
Mod::FakeVariant::<i32>(0);
Mod::<i32>::FakeVariant(0);
- //~^ ERROR type arguments are not allowed on this entity [E0109]
+ //~^ ERROR type arguments are not allowed for this type [E0109]
}
diff --git a/src/test/ui/mod-subitem-as-enum-variant.stderr b/src/test/ui/mod-subitem-as-enum-variant.stderr
index d62bad8..72eca58 100644
--- a/src/test/ui/mod-subitem-as-enum-variant.stderr
+++ b/src/test/ui/mod-subitem-as-enum-variant.stderr
@@ -1,4 +1,4 @@
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/mod-subitem-as-enum-variant.rs:8:11
|
LL | Mod::<i32>::FakeVariant(0);
diff --git a/src/test/ui/mut/mut-pattern-internal-mutability.ast.nll.stderr b/src/test/ui/mut/mut-pattern-internal-mutability.ast.nll.stderr
index 82a4628..0db3201 100644
--- a/src/test/ui/mut/mut-pattern-internal-mutability.ast.nll.stderr
+++ b/src/test/ui/mut/mut-pattern-internal-mutability.ast.nll.stderr
@@ -6,7 +6,7 @@
| |
| first assignment to `x`
| help: make this binding mutable: `mut x`
-LL | x += 1; //[ast]~ ERROR cannot assign twice to immutable variable
+LL | x += 1;
| ^^^^^^ cannot assign twice to immutable variable
error[E0506]: cannot assign to `*foo` because it is borrowed
@@ -14,9 +14,9 @@
|
LL | let &mut ref x = foo;
| ----- borrow of `*foo` occurs here
-LL | *foo += 1; //[ast]~ ERROR cannot assign to `*foo` because it is borrowed
+LL | *foo += 1;
| ^^^^^^^^^ assignment to borrowed `*foo` occurs here
-LL | //[mir]~^ ERROR cannot assign to `*foo` because it is borrowed
+LL |
LL | drop(x);
| - borrow later used here
diff --git a/src/test/ui/mut/mut-pattern-internal-mutability.ast.stderr b/src/test/ui/mut/mut-pattern-internal-mutability.ast.stderr
index e3423d5..da33cdf 100644
--- a/src/test/ui/mut/mut-pattern-internal-mutability.ast.stderr
+++ b/src/test/ui/mut/mut-pattern-internal-mutability.ast.stderr
@@ -3,7 +3,7 @@
|
LL | let &mut x = foo;
| - first assignment to `x`
-LL | x += 1; //[ast]~ ERROR cannot assign twice to immutable variable
+LL | x += 1;
| ^^^^^^ cannot assign twice to immutable variable
error[E0506]: cannot assign to `*foo` because it is borrowed
@@ -11,7 +11,7 @@
|
LL | let &mut ref x = foo;
| ----- borrow of `*foo` occurs here
-LL | *foo += 1; //[ast]~ ERROR cannot assign to `*foo` because it is borrowed
+LL | *foo += 1;
| ^^^^^^^^^ assignment to borrowed `*foo` occurs here
error: aborting due to 2 previous errors
diff --git a/src/test/ui/mut/mut-pattern-internal-mutability.mir.stderr b/src/test/ui/mut/mut-pattern-internal-mutability.mir.stderr
index 82a4628..0db3201 100644
--- a/src/test/ui/mut/mut-pattern-internal-mutability.mir.stderr
+++ b/src/test/ui/mut/mut-pattern-internal-mutability.mir.stderr
@@ -6,7 +6,7 @@
| |
| first assignment to `x`
| help: make this binding mutable: `mut x`
-LL | x += 1; //[ast]~ ERROR cannot assign twice to immutable variable
+LL | x += 1;
| ^^^^^^ cannot assign twice to immutable variable
error[E0506]: cannot assign to `*foo` because it is borrowed
@@ -14,9 +14,9 @@
|
LL | let &mut ref x = foo;
| ----- borrow of `*foo` occurs here
-LL | *foo += 1; //[ast]~ ERROR cannot assign to `*foo` because it is borrowed
+LL | *foo += 1;
| ^^^^^^^^^ assignment to borrowed `*foo` occurs here
-LL | //[mir]~^ ERROR cannot assign to `*foo` because it is borrowed
+LL |
LL | drop(x);
| - borrow later used here
diff --git a/src/test/ui/mut/mutable-class-fields.ast.nll.stderr b/src/test/ui/mut/mutable-class-fields.ast.nll.stderr
index 6b36b29..e243fb7 100644
--- a/src/test/ui/mut/mutable-class-fields.ast.nll.stderr
+++ b/src/test/ui/mut/mutable-class-fields.ast.nll.stderr
@@ -3,7 +3,7 @@
|
LL | let nyan : Cat = cat(52, 99);
| ---- help: consider changing this to be mutable: `mut nyan`
-LL | nyan.how_hungry = 0; //[ast]~ ERROR cannot assign
+LL | nyan.how_hungry = 0;
| ^^^^^^^^^^^^^^^^^^^ cannot assign
error: aborting due to previous error
diff --git a/src/test/ui/mut/mutable-class-fields.ast.stderr b/src/test/ui/mut/mutable-class-fields.ast.stderr
index 8018570..95a9284 100644
--- a/src/test/ui/mut/mutable-class-fields.ast.stderr
+++ b/src/test/ui/mut/mutable-class-fields.ast.stderr
@@ -3,7 +3,7 @@
|
LL | let nyan : Cat = cat(52, 99);
| ---- help: make this binding mutable: `mut nyan`
-LL | nyan.how_hungry = 0; //[ast]~ ERROR cannot assign
+LL | nyan.how_hungry = 0;
| ^^^^^^^^^^^^^^^^^^^ cannot mutably borrow field of immutable binding
error: aborting due to previous error
diff --git a/src/test/ui/mut/mutable-class-fields.mir.stderr b/src/test/ui/mut/mutable-class-fields.mir.stderr
index 6b36b29..e243fb7 100644
--- a/src/test/ui/mut/mutable-class-fields.mir.stderr
+++ b/src/test/ui/mut/mutable-class-fields.mir.stderr
@@ -3,7 +3,7 @@
|
LL | let nyan : Cat = cat(52, 99);
| ---- help: consider changing this to be mutable: `mut nyan`
-LL | nyan.how_hungry = 0; //[ast]~ ERROR cannot assign
+LL | nyan.how_hungry = 0;
| ^^^^^^^^^^^^^^^^^^^ cannot assign
error: aborting due to previous error
diff --git a/src/test/ui/nll/match-guards-always-borrow.ast.nll.stderr b/src/test/ui/nll/match-guards-always-borrow.ast.nll.stderr
index 4d64794..82a30db 100644
--- a/src/test/ui/nll/match-guards-always-borrow.ast.nll.stderr
+++ b/src/test/ui/nll/match-guards-always-borrow.ast.nll.stderr
@@ -10,7 +10,7 @@
error: compilation successful
--> $DIR/match-guards-always-borrow.rs:47:1
|
-LL | / fn main() { //[ast]~ ERROR compilation successful
+LL | / fn main() {
LL | | should_reject_destructive_mutate_in_guard();
LL | | allow_mutate_in_arm_body();
LL | | allow_move_into_arm_body();
diff --git a/src/test/ui/nll/match-guards-always-borrow.ast.stderr b/src/test/ui/nll/match-guards-always-borrow.ast.stderr
index 92d76d5..0c08f20 100644
--- a/src/test/ui/nll/match-guards-always-borrow.ast.stderr
+++ b/src/test/ui/nll/match-guards-always-borrow.ast.stderr
@@ -1,7 +1,7 @@
error: compilation successful
--> $DIR/match-guards-always-borrow.rs:47:1
|
-LL | / fn main() { //[ast]~ ERROR compilation successful
+LL | / fn main() {
LL | | should_reject_destructive_mutate_in_guard();
LL | | allow_mutate_in_arm_body();
LL | | allow_move_into_arm_body();
diff --git a/src/test/ui/nll/reference-carried-through-struct-field.ast.nll.stderr b/src/test/ui/nll/reference-carried-through-struct-field.ast.nll.stderr
index f28e552..1f6eb9a 100644
--- a/src/test/ui/nll/reference-carried-through-struct-field.ast.nll.stderr
+++ b/src/test/ui/nll/reference-carried-through-struct-field.ast.nll.stderr
@@ -3,9 +3,9 @@
|
LL | let wrapper = Wrap { w: &mut x };
| ------ borrow of `x` occurs here
-LL | x += 1; //[ast]~ ERROR cannot assign to `x` because it is borrowed [E0506]
+LL | x += 1;
| ^^^^^^ use of borrowed `x`
-LL | //[mir]~^ ERROR cannot use `x` because it was mutably borrowed [E0503]
+LL |
LL | *wrapper.w += 1;
| --------------- borrow later used here
diff --git a/src/test/ui/nll/reference-carried-through-struct-field.ast.stderr b/src/test/ui/nll/reference-carried-through-struct-field.ast.stderr
index b19d0b5..3104944 100644
--- a/src/test/ui/nll/reference-carried-through-struct-field.ast.stderr
+++ b/src/test/ui/nll/reference-carried-through-struct-field.ast.stderr
@@ -3,7 +3,7 @@
|
LL | let wrapper = Wrap { w: &mut x };
| - borrow of `x` occurs here
-LL | x += 1; //[ast]~ ERROR cannot assign to `x` because it is borrowed [E0506]
+LL | x += 1;
| ^^^^^^ assignment to borrowed `x` occurs here
error: aborting due to previous error
diff --git a/src/test/ui/nll/reference-carried-through-struct-field.mir.stderr b/src/test/ui/nll/reference-carried-through-struct-field.mir.stderr
index f28e552..1f6eb9a 100644
--- a/src/test/ui/nll/reference-carried-through-struct-field.mir.stderr
+++ b/src/test/ui/nll/reference-carried-through-struct-field.mir.stderr
@@ -3,9 +3,9 @@
|
LL | let wrapper = Wrap { w: &mut x };
| ------ borrow of `x` occurs here
-LL | x += 1; //[ast]~ ERROR cannot assign to `x` because it is borrowed [E0506]
+LL | x += 1;
| ^^^^^^ use of borrowed `x`
-LL | //[mir]~^ ERROR cannot use `x` because it was mutably borrowed [E0503]
+LL |
LL | *wrapper.w += 1;
| --------------- borrow later used here
diff --git a/src/test/ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.rs b/src/test/ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.rs
new file mode 100644
index 0000000..3d042d4
--- /dev/null
+++ b/src/test/ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.rs
@@ -0,0 +1,70 @@
+// This test is ensuring that type ascriptions on let bindings
+// constrain both:
+//
+// 1. the input expression on the right-hand side (after any potential
+// coercion, and allowing for covariance), *and*
+//
+// 2. the bindings (if any) nested within the pattern on the left-hand
+// side (and here, the type-constraint is *invariant*).
+
+#![feature(nll)]
+
+#![allow(dead_code, unused_mut)]
+type PairUncoupled<'a, 'b, T> = (&'a T, &'b T);
+type PairCoupledRegions<'a, T> = (&'a T, &'a T);
+type PairCoupledTypes<T> = (T, T);
+
+fn uncoupled_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 {
+ let ((mut y, mut _z),): (PairUncoupled<u32>,) = ((s, &_x),); // ok
+ // Above compiling does *not* imply below would compile.
+ // ::std::mem::swap(&mut y, &mut _z);
+ y
+}
+
+fn swap_regions((mut y, mut _z): PairCoupledRegions<u32>) {
+ ::std::mem::swap(&mut y, &mut _z);
+}
+
+fn coupled_regions_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 {
+ let ((y, _z),): (PairCoupledRegions<u32>,) = ((s, &_x),);
+ // If above line compiled, so should line below ...
+
+ // swap_regions((y, _z));
+
+ // ... but the ascribed type also invalidates this use of `y`
+ y //~ ERROR lifetime may not live long enough
+}
+
+fn swap_types((mut y, mut _z): PairCoupledTypes<&u32>) {
+ ::std::mem::swap(&mut y, &mut _z);
+}
+
+fn coupled_types_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 {
+ let ((y, _z),): (PairCoupledTypes<&u32>,) = ((s, &_x),);
+ // If above line compiled, so should line below ...
+
+ // swap_types((y, _z));
+
+ // ... but the ascribed type also invalidates this use of `y`
+ y //~ ERROR lifetime may not live long enough
+}
+
+fn swap_wilds((mut y, mut _z): PairCoupledTypes<&u32>) {
+ ::std::mem::swap(&mut y, &mut _z);
+}
+
+fn coupled_wilds_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 {
+ let ((y, _z),): (PairCoupledTypes<_>,) = ((s, &_x),);
+ // If above line compiled, so should line below
+ // swap_wilds((y, _z));
+
+ // ... but the ascribed type also invalidates this use of `y`
+ y //~ ERROR lifetime may not live long enough
+}
+
+fn main() {
+ uncoupled_lhs(&3, &4);
+ coupled_regions_lhs(&3, &4);
+ coupled_types_lhs(&3, &4);
+ coupled_wilds_lhs(&3, &4);
+}
diff --git a/src/test/ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.stderr b/src/test/ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.stderr
new file mode 100644
index 0000000..5929707
--- /dev/null
+++ b/src/test/ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.stderr
@@ -0,0 +1,29 @@
+error: lifetime may not live long enough
+ --> $DIR/issue-55748-pat-types-constrain-bindings.rs:35:5
+ |
+LL | fn coupled_regions_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 {
+ | -- lifetime `'a` defined here
+...
+LL | y
+ | ^ returning this value requires that `'a` must outlive `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/issue-55748-pat-types-constrain-bindings.rs:49:5
+ |
+LL | fn coupled_types_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 {
+ | -- lifetime `'a` defined here
+...
+LL | y
+ | ^ returning this value requires that `'a` must outlive `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/issue-55748-pat-types-constrain-bindings.rs:62:5
+ |
+LL | fn coupled_wilds_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 {
+ | -- lifetime `'a` defined here
+...
+LL | y
+ | ^ returning this value requires that `'a` must outlive `'static`
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/obsolete-in-place/bad.bad.stderr b/src/test/ui/obsolete-in-place/bad.bad.stderr
index 245ecb4..468577a 100644
--- a/src/test/ui/obsolete-in-place/bad.bad.stderr
+++ b/src/test/ui/obsolete-in-place/bad.bad.stderr
@@ -1,7 +1,7 @@
error: emplacement syntax is obsolete (for now, anyway)
--> $DIR/bad.rs:9:5
|
-LL | x <- y; //[bad]~ ERROR emplacement syntax is obsolete
+LL | x <- y;
| ^^^^^^
|
= note: for more information, see <https://github.com/rust-lang/rust/issues/27779#issuecomment-378416911>
@@ -9,7 +9,7 @@
error: emplacement syntax is obsolete (for now, anyway)
--> $DIR/bad.rs:10:5
|
-LL | in(foo) { bar }; //[bad]~ ERROR emplacement syntax is obsolete
+LL | in(foo) { bar };
| ^^^^^^^^^^^^^^^
|
= note: for more information, see <https://github.com/rust-lang/rust/issues/27779#issuecomment-378416911>
diff --git a/src/test/ui/parser/byte-literals.stderr b/src/test/ui/parser/byte-literals.stderr
index 36cb017..4edeccf 100644
--- a/src/test/ui/parser/byte-literals.stderr
+++ b/src/test/ui/parser/byte-literals.stderr
@@ -2,13 +2,13 @@
--> $DIR/byte-literals.rs:6:21
|
LL | static FOO: u8 = b'/f';
- | ^
+ | ^ unknown byte escape
error: unknown byte escape: f
--> $DIR/byte-literals.rs:9:8
|
LL | b'/f';
- | ^
+ | ^ unknown byte escape
error: invalid character in numeric character escape: Z
--> $DIR/byte-literals.rs:10:10
diff --git a/src/test/ui/parser/byte-string-literals.stderr b/src/test/ui/parser/byte-string-literals.stderr
index 2e9b13b..45c1a94 100644
--- a/src/test/ui/parser/byte-string-literals.stderr
+++ b/src/test/ui/parser/byte-string-literals.stderr
@@ -2,13 +2,13 @@
--> $DIR/byte-string-literals.rs:6:32
|
LL | static FOO: &'static [u8] = b"/f";
- | ^
+ | ^ unknown byte escape
error: unknown byte escape: f
--> $DIR/byte-string-literals.rs:9:8
|
LL | b"/f";
- | ^
+ | ^ unknown byte escape
error: invalid character in numeric character escape: Z
--> $DIR/byte-string-literals.rs:10:10
diff --git a/src/test/ui/parser/issue-23620-invalid-escapes.stderr b/src/test/ui/parser/issue-23620-invalid-escapes.stderr
index f6e476a..669a6d2 100644
--- a/src/test/ui/parser/issue-23620-invalid-escapes.stderr
+++ b/src/test/ui/parser/issue-23620-invalid-escapes.stderr
@@ -14,13 +14,9 @@
--> $DIR/issue-23620-invalid-escapes.rs:10:15
|
LL | let _ = b'/u';
- | ^^
+ | ^^ incorrect unicode escape sequence
|
-help: format of unicode escape sequences is `/u{...}`
- --> $DIR/issue-23620-invalid-escapes.rs:10:15
- |
-LL | let _ = b'/u';
- | ^^
+ = help: format of unicode escape sequences is `/u{...}`
error: unicode escape sequences cannot be used as a byte or in a byte string
--> $DIR/issue-23620-invalid-escapes.rs:10:15
@@ -80,13 +76,9 @@
--> $DIR/issue-23620-invalid-escapes.rs:28:28
|
LL | let _ = b"/u{a4a4} /xf /u";
- | ^^
+ | ^^ incorrect unicode escape sequence
|
-help: format of unicode escape sequences is `/u{...}`
- --> $DIR/issue-23620-invalid-escapes.rs:28:28
- |
-LL | let _ = b"/u{a4a4} /xf /u";
- | ^^
+ = help: format of unicode escape sequences is `/u{...}`
error: unicode escape sequences cannot be used as a byte or in a byte string
--> $DIR/issue-23620-invalid-escapes.rs:28:28
@@ -110,13 +102,9 @@
--> $DIR/issue-23620-invalid-escapes.rs:34:18
|
LL | let _ = "/xf /u";
- | ^^
+ | ^^ incorrect unicode escape sequence
|
-help: format of unicode escape sequences is `/u{...}`
- --> $DIR/issue-23620-invalid-escapes.rs:34:18
- |
-LL | let _ = "/xf /u";
- | ^^
+ = help: format of unicode escape sequences is `/u{...}`
error: incorrect unicode escape sequence
--> $DIR/issue-23620-invalid-escapes.rs:39:14
diff --git a/src/test/ui/parser/lex-bad-char-literals-1.stderr b/src/test/ui/parser/lex-bad-char-literals-1.stderr
index 3c8550e..e6b7110 100644
--- a/src/test/ui/parser/lex-bad-char-literals-1.stderr
+++ b/src/test/ui/parser/lex-bad-char-literals-1.stderr
@@ -14,13 +14,13 @@
--> $DIR/lex-bad-char-literals-1.rs:11:7
|
LL | '/●'
- | ^
+ | ^ unknown character escape
error: unknown character escape: /u{25cf}
--> $DIR/lex-bad-char-literals-1.rs:15:7
|
LL | "/●"
- | ^
+ | ^ unknown character escape
error: aborting due to 4 previous errors
diff --git a/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.stderr b/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.stderr
index 19117bf..b4d538b 100644
--- a/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.stderr
+++ b/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.stderr
Binary files differ
diff --git a/src/test/ui/parser/macros-no-semicolon-items.rs b/src/test/ui/parser/macros-no-semicolon-items.rs
index a727caf..3afc275 100644
--- a/src/test/ui/parser/macros-no-semicolon-items.rs
+++ b/src/test/ui/parser/macros-no-semicolon-items.rs
@@ -1,4 +1,15 @@
macro_rules! foo() //~ ERROR semicolon
+ //~| ERROR unexpected end of macro
+
+macro_rules! bar {
+ ($($tokens:tt)*) => {}
+}
+
+bar!( //~ ERROR semicolon
+ blah
+ blah
+ blah
+)
fn main() {
}
diff --git a/src/test/ui/parser/macros-no-semicolon-items.stderr b/src/test/ui/parser/macros-no-semicolon-items.stderr
index a869a53..5276aa6 100644
--- a/src/test/ui/parser/macros-no-semicolon-items.stderr
+++ b/src/test/ui/parser/macros-no-semicolon-items.stderr
@@ -1,8 +1,45 @@
-error: macros that expand to items must either be surrounded with braces or followed by a semicolon
+error: macros that expand to items must be delimited with braces or followed by a semicolon
--> $DIR/macros-no-semicolon-items.rs:1:17
|
LL | macro_rules! foo()
| ^^
+help: change the delimiters to curly braces
+ |
+LL | macro_rules! foo {}
+ | ^^
+help: add a semicolon
+ |
+LL | macro_rules! foo();
+ | ^
-error: aborting due to previous error
+error: macros that expand to items must be delimited with braces or followed by a semicolon
+ --> $DIR/macros-no-semicolon-items.rs:8:5
+ |
+LL | bar!(
+ | _____^
+LL | | blah
+LL | | blah
+LL | | blah
+LL | | )
+ | |_^
+help: change the delimiters to curly braces
+ |
+LL | bar! {
+LL | blah
+LL | blah
+LL | blah
+LL | }
+ |
+help: add a semicolon
+ |
+LL | );
+ | ^
+
+error: unexpected end of macro invocation
+ --> $DIR/macros-no-semicolon-items.rs:1:1
+ |
+LL | macro_rules! foo()
+ | ^^^^^^^^^^^^^^^^^^ missing tokens in macro arguments
+
+error: aborting due to 3 previous errors
diff --git a/src/test/ui/parser/pat-tuple-3.stderr b/src/test/ui/parser/pat-tuple-3.stderr
index 0ad7d27..c9f14bb 100644
--- a/src/test/ui/parser/pat-tuple-3.stderr
+++ b/src/test/ui/parser/pat-tuple-3.stderr
@@ -2,7 +2,9 @@
--> $DIR/pat-tuple-3.rs:3:19
|
LL | (.., pat, ..) => {}
- | ^^ can only be used once per pattern
+ | -- ^^ can only be used once per pattern
+ | |
+ | previously present here
error: aborting due to previous error
diff --git a/src/test/ui/parser/raw/raw-literal-self.rs b/src/test/ui/parser/raw/raw-literal-self.rs
index d7b9553..123a11b 100644
--- a/src/test/ui/parser/raw/raw-literal-self.rs
+++ b/src/test/ui/parser/raw/raw-literal-self.rs
@@ -1,3 +1,4 @@
-fn self_test(r#self: u32) {
- //~^ ERROR `r#self` is not currently supported.
+fn main() {
+ let r#self;
+ //~^ ERROR `self` cannot be a raw identifier
}
diff --git a/src/test/ui/parser/raw/raw-literal-self.stderr b/src/test/ui/parser/raw/raw-literal-self.stderr
index e643327..9a330fc 100644
--- a/src/test/ui/parser/raw/raw-literal-self.stderr
+++ b/src/test/ui/parser/raw/raw-literal-self.stderr
@@ -1,8 +1,8 @@
-error: `r#self` is not currently supported.
- --> $DIR/raw-literal-self.rs:1:14
+error: `self` cannot be a raw identifier
+ --> $DIR/raw-literal-self.rs:2:9
|
-LL | fn self_test(r#self: u32) {
- | ^^^^^^
+LL | let r#self;
+ | ^^^^^^
error: aborting due to previous error
diff --git a/src/test/ui/parser/raw/raw-literal-underscore.rs b/src/test/ui/parser/raw/raw-literal-underscore.rs
index bbedd39..6d15f1e 100644
--- a/src/test/ui/parser/raw/raw-literal-underscore.rs
+++ b/src/test/ui/parser/raw/raw-literal-underscore.rs
@@ -1,3 +1,4 @@
-fn underscore_test(r#_: u32) {
- //~^ ERROR `r#_` is not currently supported.
+fn main() {
+ let r#_;
+ //~^ ERROR `_` cannot be a raw identifier
}
diff --git a/src/test/ui/parser/raw/raw-literal-underscore.stderr b/src/test/ui/parser/raw/raw-literal-underscore.stderr
index 9427b33..d96b14f 100644
--- a/src/test/ui/parser/raw/raw-literal-underscore.stderr
+++ b/src/test/ui/parser/raw/raw-literal-underscore.stderr
@@ -1,8 +1,8 @@
-error: `r#_` is not currently supported.
- --> $DIR/raw-literal-underscore.rs:1:20
+error: `_` cannot be a raw identifier
+ --> $DIR/raw-literal-underscore.rs:2:9
|
-LL | fn underscore_test(r#_: u32) {
- | ^^^
+LL | let r#_;
+ | ^^^
error: aborting due to previous error
diff --git a/src/test/ui/parser/recover-enum.rs b/src/test/ui/parser/recover-enum.rs
index 204ad85..da42da8 100644
--- a/src/test/ui/parser/recover-enum.rs
+++ b/src/test/ui/parser/recover-enum.rs
@@ -3,7 +3,11 @@
fn main() {
enum Test {
Very
- Bad //~ ERROR found `Bad`
- Stuff
+ //~^ ERROR missing comma
+ Bad(usize)
+ //~^ ERROR missing comma
+ Stuff { a: usize }
+ //~^ ERROR missing comma
+ Here
}
}
diff --git a/src/test/ui/parser/recover-enum.stderr b/src/test/ui/parser/recover-enum.stderr
index 8c3448d..10b4aba 100644
--- a/src/test/ui/parser/recover-enum.stderr
+++ b/src/test/ui/parser/recover-enum.stderr
@@ -1,10 +1,20 @@
-error: expected one of `(`, `,`, `=`, `{`, or `}`, found `Bad`
- --> $DIR/recover-enum.rs:6:9
+error: missing comma
+ --> $DIR/recover-enum.rs:5:13
|
LL | Very
- | - expected one of `(`, `,`, `=`, `{`, or `}` here
-LL | Bad
- | ^^^ unexpected token
+ | ^ help: missing comma
-error: aborting due to previous error
+error: missing comma
+ --> $DIR/recover-enum.rs:7:19
+ |
+LL | Bad(usize)
+ | ^ help: missing comma
+
+error: missing comma
+ --> $DIR/recover-enum.rs:9:27
+ |
+LL | Stuff { a: usize }
+ | ^ help: missing comma
+
+error: aborting due to 3 previous errors
diff --git a/src/test/ui/parser/recovered-struct-variant.rs b/src/test/ui/parser/recovered-struct-variant.rs
new file mode 100644
index 0000000..5b195dc
--- /dev/null
+++ b/src/test/ui/parser/recovered-struct-variant.rs
@@ -0,0 +1,13 @@
+enum Foo {
+ A { a, b: usize }
+ //~^ ERROR expected `:`, found `,`
+}
+
+fn main() {
+ // no complaints about non-existing fields
+ let f = Foo::A { a:3, b: 4};
+ match f {
+ // no complaints about non-existing fields
+ Foo::A {a, b} => {}
+ }
+}
diff --git a/src/test/ui/parser/recovered-struct-variant.stderr b/src/test/ui/parser/recovered-struct-variant.stderr
new file mode 100644
index 0000000..51aaf8b
--- /dev/null
+++ b/src/test/ui/parser/recovered-struct-variant.stderr
@@ -0,0 +1,8 @@
+error: expected `:`, found `,`
+ --> $DIR/recovered-struct-variant.rs:2:10
+ |
+LL | A { a, b: usize }
+ | ^ expected `:`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/trailing-carriage-return-in-string.stderr b/src/test/ui/parser/trailing-carriage-return-in-string.stderr
index 972e429..f70f8ac 100644
--- a/src/test/ui/parser/trailing-carriage-return-in-string.stderr
+++ b/src/test/ui/parser/trailing-carriage-return-in-string.stderr
Binary files differ
diff --git a/src/test/ui/parser/trait-pub-assoc-const.rs b/src/test/ui/parser/trait-pub-assoc-const.rs
index 3ee2dc1..219ffa3 100644
--- a/src/test/ui/parser/trait-pub-assoc-const.rs
+++ b/src/test/ui/parser/trait-pub-assoc-const.rs
@@ -1,6 +1,6 @@
trait Foo {
pub const Foo: u32;
- //~^ ERROR expected one of `async`, `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found
+ //~^ ERROR unnecessary visibility qualifier
}
fn main() {}
diff --git a/src/test/ui/parser/trait-pub-assoc-const.stderr b/src/test/ui/parser/trait-pub-assoc-const.stderr
index 8fc9ae4..817692c 100644
--- a/src/test/ui/parser/trait-pub-assoc-const.stderr
+++ b/src/test/ui/parser/trait-pub-assoc-const.stderr
@@ -1,10 +1,8 @@
-error: expected one of `async`, `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found `pub`
+error: unnecessary visibility qualifier
--> $DIR/trait-pub-assoc-const.rs:2:5
|
-LL | trait Foo {
- | - expected one of 7 possible tokens here
LL | pub const Foo: u32;
- | ^^^ unexpected token
+ | ^^^ `pub` not permitted here
error: aborting due to previous error
diff --git a/src/test/ui/parser/trait-pub-assoc-ty.rs b/src/test/ui/parser/trait-pub-assoc-ty.rs
index 042addf..a78dfbd 100644
--- a/src/test/ui/parser/trait-pub-assoc-ty.rs
+++ b/src/test/ui/parser/trait-pub-assoc-ty.rs
@@ -1,6 +1,6 @@
trait Foo {
pub type Foo;
- //~^ ERROR expected one of `async`, `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found
+ //~^ ERROR unnecessary visibility qualifier
}
fn main() {}
diff --git a/src/test/ui/parser/trait-pub-assoc-ty.stderr b/src/test/ui/parser/trait-pub-assoc-ty.stderr
index b8eab4e..400be6a 100644
--- a/src/test/ui/parser/trait-pub-assoc-ty.stderr
+++ b/src/test/ui/parser/trait-pub-assoc-ty.stderr
@@ -1,10 +1,8 @@
-error: expected one of `async`, `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found `pub`
+error: unnecessary visibility qualifier
--> $DIR/trait-pub-assoc-ty.rs:2:5
|
-LL | trait Foo {
- | - expected one of 7 possible tokens here
LL | pub type Foo;
- | ^^^ unexpected token
+ | ^^^ `pub` not permitted here
error: aborting due to previous error
diff --git a/src/test/ui/parser/trait-pub-method.rs b/src/test/ui/parser/trait-pub-method.rs
index 9675182..1f6ee02 100644
--- a/src/test/ui/parser/trait-pub-method.rs
+++ b/src/test/ui/parser/trait-pub-method.rs
@@ -1,6 +1,6 @@
trait Foo {
pub fn foo();
- //~^ ERROR expected one of `async`, `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found
+ //~^ ERROR unnecessary visibility qualifier
}
fn main() {}
diff --git a/src/test/ui/parser/trait-pub-method.stderr b/src/test/ui/parser/trait-pub-method.stderr
index d4db961..b3617a4 100644
--- a/src/test/ui/parser/trait-pub-method.stderr
+++ b/src/test/ui/parser/trait-pub-method.stderr
@@ -1,10 +1,8 @@
-error: expected one of `async`, `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found `pub`
+error: unnecessary visibility qualifier
--> $DIR/trait-pub-method.rs:2:5
|
-LL | trait Foo {
- | - expected one of 7 possible tokens here
LL | pub fn foo();
- | ^^^ unexpected token
+ | ^^^ `pub` not permitted here
error: aborting due to previous error
diff --git a/src/test/ui/parser/wrong-escape-of-curly-braces.stderr b/src/test/ui/parser/wrong-escape-of-curly-braces.stderr
index 90debfc..346eba0 100644
--- a/src/test/ui/parser/wrong-escape-of-curly-braces.stderr
+++ b/src/test/ui/parser/wrong-escape-of-curly-braces.stderr
@@ -2,25 +2,17 @@
--> $DIR/wrong-escape-of-curly-braces.rs:3:17
|
LL | let bad = "/{it is wrong/}";
- | ^
+ | ^ unknown character escape
|
-help: if used in a formatting string, curly braces are escaped with `{{` and `}}`
- --> $DIR/wrong-escape-of-curly-braces.rs:3:17
- |
-LL | let bad = "/{it is wrong/}";
- | ^
+ = help: if used in a formatting string, curly braces are escaped with `{{` and `}}`
error: unknown character escape: }
--> $DIR/wrong-escape-of-curly-braces.rs:3:30
|
LL | let bad = "/{it is wrong/}";
- | ^
+ | ^ unknown character escape
|
-help: if used in a formatting string, curly braces are escaped with `{{` and `}}`
- --> $DIR/wrong-escape-of-curly-braces.rs:3:30
- |
-LL | let bad = "/{it is wrong/}";
- | ^
+ = help: if used in a formatting string, curly braces are escaped with `{{` and `}}`
error: aborting due to 2 previous errors
diff --git a/src/test/ui/prim-with-args.rs b/src/test/ui/prim-with-args.rs
index b5df0fb..e5beaca 100644
--- a/src/test/ui/prim-with-args.rs
+++ b/src/test/ui/prim-with-args.rs
@@ -1,27 +1,27 @@
fn main() {
-let x: isize<isize>; //~ ERROR type arguments are not allowed on this entity
-let x: i8<isize>; //~ ERROR type arguments are not allowed on this entity
-let x: i16<isize>; //~ ERROR type arguments are not allowed on this entity
-let x: i32<isize>; //~ ERROR type arguments are not allowed on this entity
-let x: i64<isize>; //~ ERROR type arguments are not allowed on this entity
-let x: usize<isize>; //~ ERROR type arguments are not allowed on this entity
-let x: u8<isize>; //~ ERROR type arguments are not allowed on this entity
-let x: u16<isize>; //~ ERROR type arguments are not allowed on this entity
-let x: u32<isize>; //~ ERROR type arguments are not allowed on this entity
-let x: u64<isize>; //~ ERROR type arguments are not allowed on this entity
-let x: char<isize>; //~ ERROR type arguments are not allowed on this entity
+let x: isize<isize>; //~ ERROR type arguments are not allowed for this type
+let x: i8<isize>; //~ ERROR type arguments are not allowed for this type
+let x: i16<isize>; //~ ERROR type arguments are not allowed for this type
+let x: i32<isize>; //~ ERROR type arguments are not allowed for this type
+let x: i64<isize>; //~ ERROR type arguments are not allowed for this type
+let x: usize<isize>; //~ ERROR type arguments are not allowed for this type
+let x: u8<isize>; //~ ERROR type arguments are not allowed for this type
+let x: u16<isize>; //~ ERROR type arguments are not allowed for this type
+let x: u32<isize>; //~ ERROR type arguments are not allowed for this type
+let x: u64<isize>; //~ ERROR type arguments are not allowed for this type
+let x: char<isize>; //~ ERROR type arguments are not allowed for this type
-let x: isize<'static>; //~ ERROR lifetime arguments are not allowed on this entity
-let x: i8<'static>; //~ ERROR lifetime arguments are not allowed on this entity
-let x: i16<'static>; //~ ERROR lifetime arguments are not allowed on this entity
-let x: i32<'static>; //~ ERROR lifetime arguments are not allowed on this entity
-let x: i64<'static>; //~ ERROR lifetime arguments are not allowed on this entity
-let x: usize<'static>; //~ ERROR lifetime arguments are not allowed on this entity
-let x: u8<'static>; //~ ERROR lifetime arguments are not allowed on this entity
-let x: u16<'static>; //~ ERROR lifetime arguments are not allowed on this entity
-let x: u32<'static>; //~ ERROR lifetime arguments are not allowed on this entity
-let x: u64<'static>; //~ ERROR lifetime arguments are not allowed on this entity
-let x: char<'static>; //~ ERROR lifetime arguments are not allowed on this entity
+let x: isize<'static>; //~ ERROR lifetime arguments are not allowed for this type
+let x: i8<'static>; //~ ERROR lifetime arguments are not allowed for this type
+let x: i16<'static>; //~ ERROR lifetime arguments are not allowed for this type
+let x: i32<'static>; //~ ERROR lifetime arguments are not allowed for this type
+let x: i64<'static>; //~ ERROR lifetime arguments are not allowed for this type
+let x: usize<'static>; //~ ERROR lifetime arguments are not allowed for this type
+let x: u8<'static>; //~ ERROR lifetime arguments are not allowed for this type
+let x: u16<'static>; //~ ERROR lifetime arguments are not allowed for this type
+let x: u32<'static>; //~ ERROR lifetime arguments are not allowed for this type
+let x: u64<'static>; //~ ERROR lifetime arguments are not allowed for this type
+let x: char<'static>; //~ ERROR lifetime arguments are not allowed for this type
}
diff --git a/src/test/ui/prim-with-args.stderr b/src/test/ui/prim-with-args.stderr
index 4535633..4bde981 100644
--- a/src/test/ui/prim-with-args.stderr
+++ b/src/test/ui/prim-with-args.stderr
@@ -1,130 +1,130 @@
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/prim-with-args.rs:3:14
|
LL | let x: isize<isize>;
| ^^^^^ type argument not allowed
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/prim-with-args.rs:4:11
|
LL | let x: i8<isize>;
| ^^^^^ type argument not allowed
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/prim-with-args.rs:5:12
|
LL | let x: i16<isize>;
| ^^^^^ type argument not allowed
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/prim-with-args.rs:6:12
|
LL | let x: i32<isize>;
| ^^^^^ type argument not allowed
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/prim-with-args.rs:7:12
|
LL | let x: i64<isize>;
| ^^^^^ type argument not allowed
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/prim-with-args.rs:8:14
|
LL | let x: usize<isize>;
| ^^^^^ type argument not allowed
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/prim-with-args.rs:9:11
|
LL | let x: u8<isize>;
| ^^^^^ type argument not allowed
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/prim-with-args.rs:10:12
|
LL | let x: u16<isize>;
| ^^^^^ type argument not allowed
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/prim-with-args.rs:11:12
|
LL | let x: u32<isize>;
| ^^^^^ type argument not allowed
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/prim-with-args.rs:12:12
|
LL | let x: u64<isize>;
| ^^^^^ type argument not allowed
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/prim-with-args.rs:13:13
|
LL | let x: char<isize>;
| ^^^^^ type argument not allowed
-error[E0110]: lifetime arguments are not allowed on this entity
+error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/prim-with-args.rs:15:14
|
LL | let x: isize<'static>;
| ^^^^^^^ lifetime argument not allowed
-error[E0110]: lifetime arguments are not allowed on this entity
+error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/prim-with-args.rs:16:11
|
LL | let x: i8<'static>;
| ^^^^^^^ lifetime argument not allowed
-error[E0110]: lifetime arguments are not allowed on this entity
+error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/prim-with-args.rs:17:12
|
LL | let x: i16<'static>;
| ^^^^^^^ lifetime argument not allowed
-error[E0110]: lifetime arguments are not allowed on this entity
+error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/prim-with-args.rs:18:12
|
LL | let x: i32<'static>;
| ^^^^^^^ lifetime argument not allowed
-error[E0110]: lifetime arguments are not allowed on this entity
+error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/prim-with-args.rs:19:12
|
LL | let x: i64<'static>;
| ^^^^^^^ lifetime argument not allowed
-error[E0110]: lifetime arguments are not allowed on this entity
+error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/prim-with-args.rs:20:14
|
LL | let x: usize<'static>;
| ^^^^^^^ lifetime argument not allowed
-error[E0110]: lifetime arguments are not allowed on this entity
+error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/prim-with-args.rs:21:11
|
LL | let x: u8<'static>;
| ^^^^^^^ lifetime argument not allowed
-error[E0110]: lifetime arguments are not allowed on this entity
+error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/prim-with-args.rs:22:12
|
LL | let x: u16<'static>;
| ^^^^^^^ lifetime argument not allowed
-error[E0110]: lifetime arguments are not allowed on this entity
+error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/prim-with-args.rs:23:12
|
LL | let x: u32<'static>;
| ^^^^^^^ lifetime argument not allowed
-error[E0110]: lifetime arguments are not allowed on this entity
+error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/prim-with-args.rs:24:12
|
LL | let x: u64<'static>;
| ^^^^^^^ lifetime argument not allowed
-error[E0110]: lifetime arguments are not allowed on this entity
+error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/prim-with-args.rs:25:13
|
LL | let x: char<'static>;
@@ -132,5 +132,4 @@
error: aborting due to 22 previous errors
-Some errors occurred: E0109, E0110.
-For more information about an error, try `rustc --explain E0109`.
+For more information about this error, try `rustc --explain E0109`.
diff --git a/src/test/ui/proc-macro/attribute.rs b/src/test/ui/proc-macro/attribute.rs
index a0b982d..ac7d0b4 100644
--- a/src/test/ui/proc-macro/attribute.rs
+++ b/src/test/ui/proc-macro/attribute.rs
@@ -4,53 +4,73 @@
#![crate_type = "proc-macro"]
extern crate proc_macro;
+use proc_macro::*;
#[proc_macro_derive]
//~^ ERROR: attribute must be of the form
-pub fn foo1(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
- input
-}
+pub fn foo1(input: TokenStream) -> TokenStream { input }
-#[proc_macro_derive = "foo"]
+#[proc_macro_derive = ""]
//~^ ERROR: attribute must be of the form
-pub fn foo2(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
- input
-}
+pub fn foo2(input: TokenStream) -> TokenStream { input }
-#[proc_macro_derive(
- a = "b"
-)]
-//~^^ ERROR: must only be one word
-pub fn foo3(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
- input
-}
-
-#[proc_macro_derive(b, c, d)]
+#[proc_macro_derive(d3, a, b)]
//~^ ERROR: attribute must have either one or two arguments
-pub fn foo4(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
- input
-}
+pub fn foo3(input: TokenStream) -> TokenStream { input }
-#[proc_macro_derive(d(e))]
-//~^ ERROR: must only be one word
-pub fn foo5(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
- input
-}
-
-#[proc_macro_derive(f, attributes(g = "h"))]
-//~^ ERROR: must only be one word
-pub fn foo6(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
- input
-}
-
-#[proc_macro_derive(i, attributes(j(k)))]
-//~^ ERROR: must only be one word
-pub fn foo7(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
- input
-}
-
-#[proc_macro_derive(l, attributes(m), n)]
+#[proc_macro_derive(d4, attributes(a), b)]
//~^ ERROR: attribute must have either one or two arguments
-pub fn foo8(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
- input
-}
+pub fn foo4(input: TokenStream) -> TokenStream { input }
+
+#[proc_macro_derive("a")]
+//~^ ERROR: not a meta item
+pub fn foo5(input: TokenStream) -> TokenStream { input }
+
+#[proc_macro_derive(d6 = "")]
+//~^ ERROR: must only be one word
+pub fn foo6(input: TokenStream) -> TokenStream { input }
+
+#[proc_macro_derive(m::d7)]
+//~^ ERROR: must only be one word
+pub fn foo7(input: TokenStream) -> TokenStream { input }
+
+#[proc_macro_derive(d8(a))]
+//~^ ERROR: must only be one word
+pub fn foo8(input: TokenStream) -> TokenStream { input }
+
+#[proc_macro_derive(self)]
+//~^ ERROR: `self` cannot be a name of derive macro
+pub fn foo9(input: TokenStream) -> TokenStream { input }
+
+#[proc_macro_derive(PartialEq)]
+//~^ ERROR: cannot override a built-in derive macro
+pub fn foo10(input: TokenStream) -> TokenStream { input }
+
+#[proc_macro_derive(d11, a)]
+//~^ ERROR: second argument must be `attributes`
+//~| ERROR: attribute must be of form: `attributes(foo, bar)`
+pub fn foo11(input: TokenStream) -> TokenStream { input }
+
+#[proc_macro_derive(d12, attributes)]
+//~^ ERROR: attribute must be of form: `attributes(foo, bar)`
+pub fn foo12(input: TokenStream) -> TokenStream { input }
+
+#[proc_macro_derive(d13, attributes("a"))]
+//~^ ERROR: not a meta item
+pub fn foo13(input: TokenStream) -> TokenStream { input }
+
+#[proc_macro_derive(d14, attributes(a = ""))]
+//~^ ERROR: must only be one word
+pub fn foo14(input: TokenStream) -> TokenStream { input }
+
+#[proc_macro_derive(d15, attributes(m::a))]
+//~^ ERROR: must only be one word
+pub fn foo15(input: TokenStream) -> TokenStream { input }
+
+#[proc_macro_derive(d16, attributes(a(b)))]
+//~^ ERROR: must only be one word
+pub fn foo16(input: TokenStream) -> TokenStream { input }
+
+#[proc_macro_derive(d17, attributes(self))]
+//~^ ERROR: `self` cannot be a name of derive helper attribute
+pub fn foo17(input: TokenStream) -> TokenStream { input }
diff --git a/src/test/ui/proc-macro/attribute.stderr b/src/test/ui/proc-macro/attribute.stderr
index 231eb1f..cc17d38 100644
--- a/src/test/ui/proc-macro/attribute.stderr
+++ b/src/test/ui/proc-macro/attribute.stderr
@@ -1,50 +1,110 @@
-error: must only be one word
- --> $DIR/attribute.rs:21:5
+error: attribute must have either one or two arguments
+ --> $DIR/attribute.rs:17:1
|
-LL | a = "b"
- | ^^^^^^^
+LL | #[proc_macro_derive(d3, a, b)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: attribute must have either one or two arguments
- --> $DIR/attribute.rs:28:1
+ --> $DIR/attribute.rs:21:1
|
-LL | #[proc_macro_derive(b, c, d)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[proc_macro_derive(d4, attributes(a), b)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: not a meta item
+ --> $DIR/attribute.rs:25:21
+ |
+LL | #[proc_macro_derive("a")]
+ | ^^^
error: must only be one word
- --> $DIR/attribute.rs:34:21
+ --> $DIR/attribute.rs:29:21
|
-LL | #[proc_macro_derive(d(e))]
+LL | #[proc_macro_derive(d6 = "")]
+ | ^^^^^^^
+
+error: must only be one word
+ --> $DIR/attribute.rs:33:21
+ |
+LL | #[proc_macro_derive(m::d7)]
+ | ^^^^^
+
+error: must only be one word
+ --> $DIR/attribute.rs:37:21
+ |
+LL | #[proc_macro_derive(d8(a))]
+ | ^^^^^
+
+error: `self` cannot be a name of derive macro
+ --> $DIR/attribute.rs:41:21
+ |
+LL | #[proc_macro_derive(self)]
| ^^^^
-error: must only be one word
- --> $DIR/attribute.rs:40:35
+error: cannot override a built-in derive macro
+ --> $DIR/attribute.rs:45:21
|
-LL | #[proc_macro_derive(f, attributes(g = "h"))]
- | ^^^^^^^
+LL | #[proc_macro_derive(PartialEq)]
+ | ^^^^^^^^^
+
+error: second argument must be `attributes`
+ --> $DIR/attribute.rs:49:26
+ |
+LL | #[proc_macro_derive(d11, a)]
+ | ^
+
+error: attribute must be of form: `attributes(foo, bar)`
+ --> $DIR/attribute.rs:49:26
+ |
+LL | #[proc_macro_derive(d11, a)]
+ | ^
+
+error: attribute must be of form: `attributes(foo, bar)`
+ --> $DIR/attribute.rs:54:26
+ |
+LL | #[proc_macro_derive(d12, attributes)]
+ | ^^^^^^^^^^
+
+error: not a meta item
+ --> $DIR/attribute.rs:58:37
+ |
+LL | #[proc_macro_derive(d13, attributes("a"))]
+ | ^^^
error: must only be one word
- --> $DIR/attribute.rs:46:35
+ --> $DIR/attribute.rs:62:37
|
-LL | #[proc_macro_derive(i, attributes(j(k)))]
- | ^^^^
+LL | #[proc_macro_derive(d14, attributes(a = ""))]
+ | ^^^^^^
-error: attribute must have either one or two arguments
- --> $DIR/attribute.rs:52:1
+error: must only be one word
+ --> $DIR/attribute.rs:66:37
|
-LL | #[proc_macro_derive(l, attributes(m), n)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[proc_macro_derive(d15, attributes(m::a))]
+ | ^^^^
+
+error: must only be one word
+ --> $DIR/attribute.rs:70:37
+ |
+LL | #[proc_macro_derive(d16, attributes(a(b)))]
+ | ^^^^
+
+error: `self` cannot be a name of derive helper attribute
+ --> $DIR/attribute.rs:74:37
+ |
+LL | #[proc_macro_derive(d17, attributes(self))]
+ | ^^^^
error: attribute must be of the form `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]`
- --> $DIR/attribute.rs:8:1
+ --> $DIR/attribute.rs:9:1
|
LL | #[proc_macro_derive]
| ^^^^^^^^^^^^^^^^^^^^
error: attribute must be of the form `#[proc_macro_derive(TraitName, /*opt*/ attributes(name1, name2, ...))]`
- --> $DIR/attribute.rs:14:1
+ --> $DIR/attribute.rs:13:1
|
-LL | #[proc_macro_derive = "foo"]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #[proc_macro_derive = ""]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
-error: aborting due to 8 previous errors
+error: aborting due to 18 previous errors
diff --git a/src/test/ui/proc-macro/invalid-punct-ident-3.stderr b/src/test/ui/proc-macro/invalid-punct-ident-3.stderr
index 6ff47e3..24371f3 100644
--- a/src/test/ui/proc-macro/invalid-punct-ident-3.stderr
+++ b/src/test/ui/proc-macro/invalid-punct-ident-3.stderr
@@ -4,7 +4,7 @@
LL | invalid_raw_ident!();
| ^^^^^^^^^^^^^^^^^^^^^
|
- = help: message: `"self"` is not a valid raw identifier
+ = help: message: `self` cannot be a raw identifier
error: aborting due to previous error
diff --git a/src/test/ui/proc-macro/shadow-builtin.rs b/src/test/ui/proc-macro/shadow-builtin.rs
deleted file mode 100644
index afcc0eb..0000000
--- a/src/test/ui/proc-macro/shadow-builtin.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-// force-host
-// no-prefer-dynamic
-
-#![crate_type = "proc-macro"]
-
-extern crate proc_macro;
-
-use proc_macro::TokenStream;
-
-#[proc_macro_derive(PartialEq)]
-//~^ ERROR: cannot override a built-in #[derive] mode
-pub fn foo(input: TokenStream) -> TokenStream {
- input
-}
diff --git a/src/test/ui/proc-macro/shadow-builtin.stderr b/src/test/ui/proc-macro/shadow-builtin.stderr
deleted file mode 100644
index 6685795..0000000
--- a/src/test/ui/proc-macro/shadow-builtin.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: cannot override a built-in #[derive] mode
- --> $DIR/shadow-builtin.rs:10:21
- |
-LL | #[proc_macro_derive(PartialEq)]
- | ^^^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/qualified/qualified-path-params-2.rs b/src/test/ui/qualified/qualified-path-params-2.rs
index 8412983..ebdd749 100644
--- a/src/test/ui/qualified/qualified-path-params-2.rs
+++ b/src/test/ui/qualified/qualified-path-params-2.rs
@@ -16,7 +16,7 @@
}
type A = <S as Tr>::A::f<u8>;
-//~^ ERROR type arguments are not allowed on this entity
+//~^ ERROR type arguments are not allowed for this type
//~| ERROR ambiguous associated type
fn main() {}
diff --git a/src/test/ui/qualified/qualified-path-params-2.stderr b/src/test/ui/qualified/qualified-path-params-2.stderr
index 4e07384..2d14d6c 100644
--- a/src/test/ui/qualified/qualified-path-params-2.stderr
+++ b/src/test/ui/qualified/qualified-path-params-2.stderr
@@ -1,4 +1,4 @@
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/qualified-path-params-2.rs:18:26
|
LL | type A = <S as Tr>::A::f<u8>;
diff --git a/src/test/ui/regions/regions-free-region-ordering-caller.ast.stderr b/src/test/ui/regions/regions-free-region-ordering-caller.ast.stderr
index 73266ab..a33d358 100644
--- a/src/test/ui/regions/regions-free-region-ordering-caller.ast.stderr
+++ b/src/test/ui/regions/regions-free-region-ordering-caller.ast.stderr
@@ -5,7 +5,7 @@
| --------- ---------
| |
| these two types are declared with different lifetimes...
-LL | let z: Option<&'b &'a usize> = None;//[ast]~ ERROR E0623
+LL | let z: Option<&'b &'a usize> = None;
| ^^^^^^^^^^^^^^^^^^^^^ ...but data from `a` flows into `b` here
error[E0623]: lifetime mismatch
@@ -16,7 +16,7 @@
| |
| these two types are declared with different lifetimes...
LL | let y: Paramd<'a> = Paramd { x: a };
-LL | let z: Option<&'b Paramd<'a>> = None;//[ast]~ ERROR E0623
+LL | let z: Option<&'b Paramd<'a>> = None;
| ^^^^^^^^^^^^^^^^^^^^^^ ...but data from `a` flows into `b` here
error[E0623]: lifetime mismatch
@@ -24,7 +24,7 @@
|
LL | fn call4<'a, 'b>(a: &'a usize, b: &'b usize) {
| --------- --------- these two types are declared with different lifetimes...
-LL | let z: Option<&'a &'b usize> = None;//[ast]~ ERROR E0623
+LL | let z: Option<&'a &'b usize> = None;
| ^^^^^^^^^^^^^^^^^^^^^ ...but data from `b` flows into `a` here
error: aborting due to 3 previous errors
diff --git a/src/test/ui/regions/regions-free-region-ordering-caller.mir.stderr b/src/test/ui/regions/regions-free-region-ordering-caller.mir.stderr
index abec468..16eda28 100644
--- a/src/test/ui/regions/regions-free-region-ordering-caller.mir.stderr
+++ b/src/test/ui/regions/regions-free-region-ordering-caller.mir.stderr
@@ -5,7 +5,7 @@
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
-LL | let z: Option<&'b &'a usize> = None;//[ast]~ ERROR E0623
+LL | let z: Option<&'b &'a usize> = None;
| ^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'b`
error: lifetime may not live long enough
@@ -16,7 +16,7 @@
| |
| lifetime `'a` defined here
LL | let y: Paramd<'a> = Paramd { x: a };
-LL | let z: Option<&'b Paramd<'a>> = None;//[ast]~ ERROR E0623
+LL | let z: Option<&'b Paramd<'a>> = None;
| ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'b`
error: lifetime may not live long enough
@@ -26,7 +26,7 @@
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
-LL | let z: Option<&'a &'b usize> = None;//[ast]~ ERROR E0623
+LL | let z: Option<&'a &'b usize> = None;
| ^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
error: aborting due to 3 previous errors
diff --git a/src/test/ui/regions/regions-pattern-typing-issue-19997.ast.nll.stderr b/src/test/ui/regions/regions-pattern-typing-issue-19997.ast.nll.stderr
index 9356200..b1c5878 100644
--- a/src/test/ui/regions/regions-pattern-typing-issue-19997.ast.nll.stderr
+++ b/src/test/ui/regions/regions-pattern-typing-issue-19997.ast.nll.stderr
@@ -4,9 +4,9 @@
LL | match (&a1,) {
| --- borrow of `a1` occurs here
LL | (&ref b0,) => {
-LL | a1 = &f; //[ast]~ ERROR cannot assign
+LL | a1 = &f;
| ^^^^^^^ assignment to borrowed `a1` occurs here
-LL | //[mir]~^ ERROR cannot assign to `a1` because it is borrowed
+LL |
LL | drop(b0);
| -- borrow later used here
diff --git a/src/test/ui/regions/regions-pattern-typing-issue-19997.ast.stderr b/src/test/ui/regions/regions-pattern-typing-issue-19997.ast.stderr
index e23c6ad..0074d2b 100644
--- a/src/test/ui/regions/regions-pattern-typing-issue-19997.ast.stderr
+++ b/src/test/ui/regions/regions-pattern-typing-issue-19997.ast.stderr
@@ -4,7 +4,7 @@
LL | match (&a1,) {
| -- borrow of `a1` occurs here
LL | (&ref b0,) => {
-LL | a1 = &f; //[ast]~ ERROR cannot assign
+LL | a1 = &f;
| ^^^^^^^ assignment to borrowed `a1` occurs here
error: aborting due to previous error
diff --git a/src/test/ui/regions/regions-pattern-typing-issue-19997.mir.stderr b/src/test/ui/regions/regions-pattern-typing-issue-19997.mir.stderr
index 9356200..b1c5878 100644
--- a/src/test/ui/regions/regions-pattern-typing-issue-19997.mir.stderr
+++ b/src/test/ui/regions/regions-pattern-typing-issue-19997.mir.stderr
@@ -4,9 +4,9 @@
LL | match (&a1,) {
| --- borrow of `a1` occurs here
LL | (&ref b0,) => {
-LL | a1 = &f; //[ast]~ ERROR cannot assign
+LL | a1 = &f;
| ^^^^^^^ assignment to borrowed `a1` occurs here
-LL | //[mir]~^ ERROR cannot assign to `a1` because it is borrowed
+LL |
LL | drop(b0);
| -- borrow later used here
diff --git a/src/test/ui/regions/regions-static-bound.ll.stderr b/src/test/ui/regions/regions-static-bound.ll.stderr
index 4695a82..d0dc554 100644
--- a/src/test/ui/regions/regions-static-bound.ll.stderr
+++ b/src/test/ui/regions/regions-static-bound.ll.stderr
@@ -1,7 +1,7 @@
error[E0312]: lifetime of reference outlives lifetime of borrowed content...
--> $DIR/regions-static-bound.rs:9:5
|
-LL | t //[ll]~ ERROR E0312
+LL | t
| ^
|
= note: ...the reference is valid for the static lifetime...
@@ -16,7 +16,7 @@
|
LL | fn error(u: &(), v: &()) {
| --- help: add explicit lifetime `'static` to the type of `u`: `&'static ()`
-LL | static_id(&u); //[ll]~ ERROR explicit lifetime required in the type of `u` [E0621]
+LL | static_id(&u);
| ^^^^^^^^^ lifetime `'static` required
error[E0621]: explicit lifetime required in the type of `v`
@@ -25,7 +25,7 @@
LL | fn error(u: &(), v: &()) {
| --- help: add explicit lifetime `'static` to the type of `v`: `&'static ()`
...
-LL | static_id_indirect(&v); //[ll]~ ERROR explicit lifetime required in the type of `v` [E0621]
+LL | static_id_indirect(&v);
| ^^^^^^^^^^^^^^^^^^ lifetime `'static` required
error: aborting due to 3 previous errors
diff --git a/src/test/ui/regions/regions-static-bound.nll.stderr b/src/test/ui/regions/regions-static-bound.nll.stderr
index d6cec03..b5f3e6c 100644
--- a/src/test/ui/regions/regions-static-bound.nll.stderr
+++ b/src/test/ui/regions/regions-static-bound.nll.stderr
@@ -3,7 +3,7 @@
|
LL | fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a {
| -- lifetime `'a` defined here
-LL | t //[ll]~ ERROR E0312
+LL | t
| ^ returning this value requires that `'a` must outlive `'static`
error[E0621]: explicit lifetime required in the type of `u`
@@ -11,7 +11,7 @@
|
LL | fn error(u: &(), v: &()) {
| --- help: add explicit lifetime `'static` to the type of `u`: `&'static ()`
-LL | static_id(&u); //[ll]~ ERROR explicit lifetime required in the type of `u` [E0621]
+LL | static_id(&u);
| ^^^^^^^^^^^^^ lifetime `'static` required
error[E0621]: explicit lifetime required in the type of `v`
@@ -20,7 +20,7 @@
LL | fn error(u: &(), v: &()) {
| --- help: add explicit lifetime `'static` to the type of `v`: `&'static ()`
...
-LL | static_id_indirect(&v); //[ll]~ ERROR explicit lifetime required in the type of `v` [E0621]
+LL | static_id_indirect(&v);
| ^^^^^^^^^^^^^^^^^^^^^^ lifetime `'static` required
error: aborting due to 3 previous errors
diff --git a/src/test/ui/resolve/privacy-enum-ctor.stderr b/src/test/ui/resolve/privacy-enum-ctor.stderr
index 01f0941..75d9c97 100644
--- a/src/test/ui/resolve/privacy-enum-ctor.stderr
+++ b/src/test/ui/resolve/privacy-enum-ctor.stderr
@@ -3,22 +3,32 @@
|
LL | n::Z;
| ^^^^
+help: try using one of the enum's variants
|
- = note: did you mean to use one of the following variants?
- - `m::Z::Fn`
- - `m::Z::Struct`
- - `m::Z::Unit`
+LL | m::Z::Fn;
+ | ^^^^^^^^
+LL | m::Z::Struct;
+ | ^^^^^^^^^^^^
+LL | m::Z::Unit;
+ | ^^^^^^^^^^
error[E0423]: expected value, found enum `Z`
--> $DIR/privacy-enum-ctor.rs:25:9
|
LL | Z;
- | ^ help: a function with a similar name exists: `f`
+ | ^
+help: a function with a similar name exists
|
- = note: did you mean to use one of the following variants?
- - `m::Z::Fn`
- - `m::Z::Struct`
- - `m::Z::Unit`
+LL | f;
+ | ^
+help: try using one of the enum's variants
+ |
+LL | m::Z::Fn;
+ | ^^^^^^^^
+LL | m::Z::Struct;
+ | ^^^^^^^^^^^^
+LL | m::Z::Unit;
+ | ^^^^^^^^^^
error[E0423]: expected value, found struct variant `Z::Struct`
--> $DIR/privacy-enum-ctor.rs:29:20
@@ -31,15 +41,18 @@
|
LL | let _: E = m::E;
| ^^^^
- |
- = note: did you mean to use one of the following variants?
- - `E::Fn`
- - `E::Struct`
- - `E::Unit`
help: a function with a similar name exists
|
LL | let _: E = m::f;
| ^
+help: try using one of the enum's variants
+ |
+LL | let _: E = E::Fn;
+ | ^^^^^
+LL | let _: E = E::Struct;
+ | ^^^^^^^^^
+LL | let _: E = E::Unit;
+ | ^^^^^^^
help: possible better candidates are found in other modules, you can import them into scope
|
LL | use std::f32::consts::E;
@@ -58,11 +71,14 @@
|
LL | let _: E = E;
| ^
+help: try using one of the enum's variants
|
- = note: did you mean to use one of the following variants?
- - `E::Fn`
- - `E::Struct`
- - `E::Unit`
+LL | let _: E = E::Fn;
+ | ^^^^^
+LL | let _: E = E::Struct;
+ | ^^^^^^^^^
+LL | let _: E = E::Unit;
+ | ^^^^^^^
help: possible better candidates are found in other modules, you can import them into scope
|
LL | use std::f32::consts::E;
@@ -95,11 +111,14 @@
|
LL | let _: Z = m::n::Z;
| ^^^^^^^
+help: try using one of the enum's variants
|
- = note: did you mean to use one of the following variants?
- - `m::Z::Fn`
- - `m::Z::Struct`
- - `m::Z::Unit`
+LL | let _: Z = m::Z::Fn;
+ | ^^^^^^^^
+LL | let _: Z = m::Z::Struct;
+ | ^^^^^^^^^^^^
+LL | let _: Z = m::Z::Unit;
+ | ^^^^^^^^^^
error[E0412]: cannot find type `Z` in this scope
--> $DIR/privacy-enum-ctor.rs:61:12
diff --git a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs
index 3d24f49..67f7f80 100644
--- a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs
+++ b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs
@@ -33,6 +33,9 @@
// We can move `b` because it's Copy.
drop(b);
+ // Without parameters works as expected.
+ let _: () = dbg!();
+
// Test that we can borrow and that successive applications is still identity.
let a = NoCopy(1337);
let b: &NoCopy = dbg!(dbg!(&a));
@@ -69,17 +72,19 @@
" y: 24",
"}",
- ":38] &a = NoCopy(",
+ ":37]",
+
+ ":41] &a = NoCopy(",
" 1337",
")",
- ":38] dbg!(& a) = NoCopy(",
+ ":41] dbg!(& a) = NoCopy(",
" 1337",
")",
- ":43] f(&42) = 42",
+ ":46] f(&42) = 42",
"before",
- ":48] { foo += 1; eprintln!(\"before\"); 7331 } = 7331",
+ ":51] { foo += 1; eprintln!(\"before\"); 7331 } = 7331",
]);
}
diff --git a/src/test/ui/rfc1445/feature-gate.no_gate.stderr b/src/test/ui/rfc1445/feature-gate.no_gate.stderr
index 8c6a08d..370b74b 100644
--- a/src/test/ui/rfc1445/feature-gate.no_gate.stderr
+++ b/src/test/ui/rfc1445/feature-gate.no_gate.stderr
@@ -1,7 +1,7 @@
error[E0658]: the semantics of constant patterns is not yet settled (see issue #31434)
--> $DIR/feature-gate.rs:13:1
|
-LL | #[structural_match] //[no_gate]~ ERROR semantics of constant patterns is not yet settled
+LL | #[structural_match]
| ^^^^^^^^^^^^^^^^^^^
|
= help: add #![feature(structural_match)] to the crate attributes to enable
diff --git a/src/test/ui/rfc1445/feature-gate.with_gate.stderr b/src/test/ui/rfc1445/feature-gate.with_gate.stderr
index da68166..ca8dc75 100644
--- a/src/test/ui/rfc1445/feature-gate.with_gate.stderr
+++ b/src/test/ui/rfc1445/feature-gate.with_gate.stderr
@@ -1,7 +1,7 @@
error: compilation successful
--> $DIR/feature-gate.rs:21:1
|
-LL | / fn main() { //[with_gate]~ ERROR compilation successful
+LL | / fn main() {
LL | | let y = Foo { x: 1 };
LL | | match y {
LL | | FOO => { }
diff --git a/src/test/ui/rfc1598-generic-associated-types/collections.rs b/src/test/ui/rfc1598-generic-associated-types/collections.rs
index 5414bb4..ede6a3b 100644
--- a/src/test/ui/rfc1598-generic-associated-types/collections.rs
+++ b/src/test/ui/rfc1598-generic-associated-types/collections.rs
@@ -2,7 +2,7 @@
//~^ WARNING the feature `generic_associated_types` is incomplete
#![feature(associated_type_defaults)]
-// FIXME(#44265): "lifetime arguments are not allowed on this entity" errors will be addressed in a
+// FIXME(#44265): "lifetime arguments are not allowed for this type" errors will be addressed in a
// follow-up PR.
// A Collection trait and collection families. Based on
@@ -15,14 +15,14 @@
// Test associated type defaults with parameters
type Sibling<U>: Collection<U> =
<<Self as Collection<T>>::Family as CollectionFamily>::Member<U>;
- //~^ ERROR type arguments are not allowed on this entity [E0109]
+ //~^ ERROR type arguments are not allowed for this type [E0109]
fn empty() -> Self;
fn add(&mut self, value: T);
fn iterate<'iter>(&'iter self) -> Self::Iter<'iter>;
- //~^ ERROR lifetime arguments are not allowed on this entity [E0110]
+ //~^ ERROR lifetime arguments are not allowed for this type [E0109]
}
trait CollectionFamily {
@@ -48,13 +48,13 @@
}
fn iterate<'iter>(&'iter self) -> Self::Iter<'iter> {
- //~^ ERROR lifetime arguments are not allowed on this entity [E0110]
+ //~^ ERROR lifetime arguments are not allowed for this type [E0109]
self.iter()
}
}
fn floatify<C>(ints: &C) -> <<C as Collection<i32>>::Family as CollectionFamily>::Member<f32>
-//~^ ERROR type arguments are not allowed on this entity [E0109]
+//~^ ERROR type arguments are not allowed for this type [E0109]
where
C: Collection<i32>,
{
@@ -66,7 +66,7 @@
}
fn floatify_sibling<C>(ints: &C) -> <C as Collection<i32>>::Sibling<f32>
-//~^ ERROR type arguments are not allowed on this entity [E0109]
+//~^ ERROR type arguments are not allowed for this type [E0109]
where
C: Collection<i32>,
{
diff --git a/src/test/ui/rfc1598-generic-associated-types/collections.stderr b/src/test/ui/rfc1598-generic-associated-types/collections.stderr
index eeed04b..d0fe503 100644
--- a/src/test/ui/rfc1598-generic-associated-types/collections.stderr
+++ b/src/test/ui/rfc1598-generic-associated-types/collections.stderr
@@ -4,31 +4,31 @@
LL | #![feature(generic_associated_types)]
| ^^^^^^^^^^^^^^^^^^^^^^^^
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/collections.rs:56:90
|
LL | fn floatify<C>(ints: &C) -> <<C as Collection<i32>>::Family as CollectionFamily>::Member<f32>
| ^^^ type argument not allowed
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/collections.rs:68:69
|
LL | fn floatify_sibling<C>(ints: &C) -> <C as Collection<i32>>::Sibling<f32>
| ^^^ type argument not allowed
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/collections.rs:17:71
|
LL | <<Self as Collection<T>>::Family as CollectionFamily>::Member<U>;
| ^ type argument not allowed
-error[E0110]: lifetime arguments are not allowed on this entity
+error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/collections.rs:24:50
|
LL | fn iterate<'iter>(&'iter self) -> Self::Iter<'iter>;
| ^^^^^ lifetime argument not allowed
-error[E0110]: lifetime arguments are not allowed on this entity
+error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/collections.rs:50:50
|
LL | fn iterate<'iter>(&'iter self) -> Self::Iter<'iter> {
@@ -36,5 +36,4 @@
error: aborting due to 5 previous errors
-Some errors occurred: E0109, E0110.
-For more information about an error, try `rustc --explain E0109`.
+For more information about this error, try `rustc --explain E0109`.
diff --git a/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.rs b/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.rs
index d9c482e..3a459a4 100644
--- a/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.rs
+++ b/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.rs
@@ -3,7 +3,7 @@
use std::ops::Deref;
-// FIXME(#44265): "lifetime arguments are not allowed on this entity" errors will be addressed in a
+// FIXME(#44265): "lifetime arguments are not allowed for this type" errors will be addressed in a
// follow-up PR.
trait Foo {
@@ -15,15 +15,15 @@
// This weird type tests that we can use universal function call syntax to access the Item on
type Baa<'a>: Deref<Target = <Self::Quux<'a> as Foo>::Bar<'a, 'static>>;
- //~^ ERROR lifetime arguments are not allowed on this entity [E0110]
- //~| ERROR lifetime arguments are not allowed on this entity [E0110]
+ //~^ ERROR lifetime arguments are not allowed for this type [E0109]
+ //~| ERROR lifetime arguments are not allowed for this type [E0109]
}
impl<T> Baz for T where T: Foo {
type Quux<'a> = T;
type Baa<'a> = &'a <T as Foo>::Bar<'a, 'static>;
- //~^ ERROR lifetime arguments are not allowed on this entity [E0110]
+ //~^ ERROR lifetime arguments are not allowed for this type [E0109]
}
fn main() {}
diff --git a/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.stderr b/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.stderr
index fd6116d..b2dd523 100644
--- a/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.stderr
+++ b/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.stderr
@@ -4,19 +4,19 @@
LL | #![feature(generic_associated_types)]
| ^^^^^^^^^^^^^^^^^^^^^^^^
-error[E0110]: lifetime arguments are not allowed on this entity
+error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/construct_with_other_type.rs:17:46
|
LL | type Baa<'a>: Deref<Target = <Self::Quux<'a> as Foo>::Bar<'a, 'static>>;
| ^^ lifetime argument not allowed
-error[E0110]: lifetime arguments are not allowed on this entity
+error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/construct_with_other_type.rs:17:63
|
LL | type Baa<'a>: Deref<Target = <Self::Quux<'a> as Foo>::Bar<'a, 'static>>;
| ^^ lifetime argument not allowed
-error[E0110]: lifetime arguments are not allowed on this entity
+error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/construct_with_other_type.rs:25:40
|
LL | type Baa<'a> = &'a <T as Foo>::Bar<'a, 'static>;
@@ -24,4 +24,4 @@
error: aborting due to 3 previous errors
-For more information about this error, try `rustc --explain E0110`.
+For more information about this error, try `rustc --explain E0109`.
diff --git a/src/test/ui/rfc1598-generic-associated-types/generic_associated_type_undeclared_lifetimes.rs b/src/test/ui/rfc1598-generic-associated-types/generic_associated_type_undeclared_lifetimes.rs
index 2e6d747..150899a 100644
--- a/src/test/ui/rfc1598-generic-associated-types/generic_associated_type_undeclared_lifetimes.rs
+++ b/src/test/ui/rfc1598-generic-associated-types/generic_associated_type_undeclared_lifetimes.rs
@@ -3,20 +3,20 @@
use std::ops::Deref;
-// FIXME(#44265): "lifetime arguments are not allowed on this entity" errors will be addressed in a
+// FIXME(#44265): "lifetime arguments are not allowed for this type" errors will be addressed in a
// follow-up PR.
trait Iterable {
type Item<'a>;
type Iter<'a>: Iterator<Item = Self::Item<'a>>
- //~^ ERROR lifetime arguments are not allowed on this entity [E0110]
+ //~^ ERROR lifetime arguments are not allowed for this type [E0109]
+ Deref<Target = Self::Item<'b>>;
//~^ ERROR undeclared lifetime
- //~| ERROR lifetime arguments are not allowed on this entity [E0110]
+ //~| ERROR lifetime arguments are not allowed for this type [E0109]
fn iter<'a>(&'a self) -> Self::Iter<'undeclared>;
//~^ ERROR undeclared lifetime
- //~| ERROR lifetime arguments are not allowed on this entity [E0110]
+ //~| ERROR lifetime arguments are not allowed for this type [E0109]
}
fn main() {}
diff --git a/src/test/ui/rfc1598-generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr b/src/test/ui/rfc1598-generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr
index 3cebab6..d65edc6 100644
--- a/src/test/ui/rfc1598-generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr
+++ b/src/test/ui/rfc1598-generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr
@@ -16,19 +16,19 @@
LL | fn iter<'a>(&'a self) -> Self::Iter<'undeclared>;
| ^^^^^^^^^^^ undeclared lifetime
-error[E0110]: lifetime arguments are not allowed on this entity
+error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/generic_associated_type_undeclared_lifetimes.rs:11:47
|
LL | type Iter<'a>: Iterator<Item = Self::Item<'a>>
| ^^ lifetime argument not allowed
-error[E0110]: lifetime arguments are not allowed on this entity
+error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/generic_associated_type_undeclared_lifetimes.rs:13:37
|
LL | + Deref<Target = Self::Item<'b>>;
| ^^ lifetime argument not allowed
-error[E0110]: lifetime arguments are not allowed on this entity
+error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/generic_associated_type_undeclared_lifetimes.rs:17:41
|
LL | fn iter<'a>(&'a self) -> Self::Iter<'undeclared>;
@@ -36,5 +36,5 @@
error: aborting due to 5 previous errors
-Some errors occurred: E0110, E0261.
-For more information about an error, try `rustc --explain E0110`.
+Some errors occurred: E0109, E0261.
+For more information about an error, try `rustc --explain E0109`.
diff --git a/src/test/ui/rfc1598-generic-associated-types/iterable.rs b/src/test/ui/rfc1598-generic-associated-types/iterable.rs
index 6925850..29953b9 100644
--- a/src/test/ui/rfc1598-generic-associated-types/iterable.rs
+++ b/src/test/ui/rfc1598-generic-associated-types/iterable.rs
@@ -3,16 +3,16 @@
use std::ops::Deref;
-// FIXME(#44265): "lifetime arguments are not allowed on this entity" errors will be addressed in a
+// FIXME(#44265): "lifetime arguments are not allowed for this type" errors will be addressed in a
// follow-up PR.
trait Iterable {
type Item<'a>;
type Iter<'a>: Iterator<Item = Self::Item<'a>>;
- //~^ ERROR lifetime arguments are not allowed on this entity [E0110]
+ //~^ ERROR lifetime arguments are not allowed for this type [E0109]
fn iter<'a>(&'a self) -> Self::Iter<'a>;
- //~^ ERROR lifetime arguments are not allowed on this entity [E0110]
+ //~^ ERROR lifetime arguments are not allowed for this type [E0109]
}
// Impl for struct type
@@ -21,7 +21,7 @@
type Iter<'a> = std::slice::Iter<'a, T>;
fn iter<'a>(&'a self) -> Self::Iter<'a> {
- //~^ ERROR lifetime arguments are not allowed on this entity [E0110]
+ //~^ ERROR lifetime arguments are not allowed for this type [E0109]
self.iter()
}
}
@@ -32,18 +32,18 @@
type Iter<'a> = std::slice::Iter<'a, T>;
fn iter<'a>(&'a self) -> Self::Iter<'a> {
- //~^ ERROR lifetime arguments are not allowed on this entity [E0110]
+ //~^ ERROR lifetime arguments are not allowed for this type [E0109]
self.iter()
}
}
fn make_iter<'a, I: Iterable>(it: &'a I) -> I::Iter<'a> {
- //~^ ERROR lifetime arguments are not allowed on this entity [E0110]
+ //~^ ERROR lifetime arguments are not allowed for this type [E0109]
it.iter()
}
fn get_first<'a, I: Iterable>(it: &'a I) -> Option<I::Item<'a>> {
- //~^ ERROR lifetime arguments are not allowed on this entity [E0110]
+ //~^ ERROR lifetime arguments are not allowed for this type [E0109]
it.iter().next()
}
diff --git a/src/test/ui/rfc1598-generic-associated-types/iterable.stderr b/src/test/ui/rfc1598-generic-associated-types/iterable.stderr
index cc3ade6..6d5d0cc 100644
--- a/src/test/ui/rfc1598-generic-associated-types/iterable.stderr
+++ b/src/test/ui/rfc1598-generic-associated-types/iterable.stderr
@@ -4,37 +4,37 @@
LL | #![feature(generic_associated_types)]
| ^^^^^^^^^^^^^^^^^^^^^^^^
-error[E0110]: lifetime arguments are not allowed on this entity
+error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/iterable.rs:11:47
|
LL | type Iter<'a>: Iterator<Item = Self::Item<'a>>;
| ^^ lifetime argument not allowed
-error[E0110]: lifetime arguments are not allowed on this entity
+error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/iterable.rs:40:53
|
LL | fn make_iter<'a, I: Iterable>(it: &'a I) -> I::Iter<'a> {
| ^^ lifetime argument not allowed
-error[E0110]: lifetime arguments are not allowed on this entity
+error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/iterable.rs:45:60
|
LL | fn get_first<'a, I: Iterable>(it: &'a I) -> Option<I::Item<'a>> {
| ^^ lifetime argument not allowed
-error[E0110]: lifetime arguments are not allowed on this entity
+error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/iterable.rs:14:41
|
LL | fn iter<'a>(&'a self) -> Self::Iter<'a>;
| ^^ lifetime argument not allowed
-error[E0110]: lifetime arguments are not allowed on this entity
+error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/iterable.rs:23:41
|
LL | fn iter<'a>(&'a self) -> Self::Iter<'a> {
| ^^ lifetime argument not allowed
-error[E0110]: lifetime arguments are not allowed on this entity
+error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/iterable.rs:34:41
|
LL | fn iter<'a>(&'a self) -> Self::Iter<'a> {
@@ -42,4 +42,4 @@
error: aborting due to 6 previous errors
-For more information about this error, try `rustc --explain E0110`.
+For more information about this error, try `rustc --explain E0109`.
diff --git a/src/test/ui/rfc1598-generic-associated-types/parameter_number_and_kind.rs b/src/test/ui/rfc1598-generic-associated-types/parameter_number_and_kind.rs
index 851e331..aa3f4b1 100644
--- a/src/test/ui/rfc1598-generic-associated-types/parameter_number_and_kind.rs
+++ b/src/test/ui/rfc1598-generic-associated-types/parameter_number_and_kind.rs
@@ -2,7 +2,7 @@
//~^ WARNING the feature `generic_associated_types` is incomplete
#![feature(associated_type_defaults)]
-// FIXME(#44265): "lifetime arguments are not allowed on this entity" errors will be addressed in a
+// FIXME(#44265): "lifetime arguments are not allowed for this type" errors will be addressed in a
// follow-up PR.
// FIXME(#44265): Update expected errors once E110 is resolved, now does not get past `trait Foo`.
@@ -15,13 +15,13 @@
type E<'a, T>;
// Test parameters in default values
type FOk<T> = Self::E<'static, T>;
- //~^ ERROR type arguments are not allowed on this entity [E0109]
- //~| ERROR lifetime arguments are not allowed on this entity [E0110]
+ //~^ ERROR type arguments are not allowed for this type [E0109]
+ //~| ERROR lifetime arguments are not allowed for this type [E0109]
type FErr1 = Self::E<'static, 'static>; // Error
- //~^ ERROR lifetime arguments are not allowed on this entity [E0110]
+ //~^ ERROR lifetime arguments are not allowed for this type [E0109]
type FErr2<T> = Self::E<'static, T, u32>; // Error
- //~^ ERROR type arguments are not allowed on this entity [E0109]
- //~| ERROR lifetime arguments are not allowed on this entity [E0110]
+ //~^ ERROR type arguments are not allowed for this type [E0109]
+ //~| ERROR lifetime arguments are not allowed for this type [E0109]
}
struct Fooy;
diff --git a/src/test/ui/rfc1598-generic-associated-types/parameter_number_and_kind.stderr b/src/test/ui/rfc1598-generic-associated-types/parameter_number_and_kind.stderr
index 265b0fa..817d911 100644
--- a/src/test/ui/rfc1598-generic-associated-types/parameter_number_and_kind.stderr
+++ b/src/test/ui/rfc1598-generic-associated-types/parameter_number_and_kind.stderr
@@ -4,31 +4,31 @@
LL | #![feature(generic_associated_types)]
| ^^^^^^^^^^^^^^^^^^^^^^^^
-error[E0110]: lifetime arguments are not allowed on this entity
+error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/parameter_number_and_kind.rs:17:27
|
LL | type FOk<T> = Self::E<'static, T>;
| ^^^^^^^ lifetime argument not allowed
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/parameter_number_and_kind.rs:17:36
|
LL | type FOk<T> = Self::E<'static, T>;
| ^ type argument not allowed
-error[E0110]: lifetime arguments are not allowed on this entity
+error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/parameter_number_and_kind.rs:20:26
|
LL | type FErr1 = Self::E<'static, 'static>; // Error
| ^^^^^^^ lifetime argument not allowed
-error[E0110]: lifetime arguments are not allowed on this entity
+error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/parameter_number_and_kind.rs:22:29
|
LL | type FErr2<T> = Self::E<'static, T, u32>; // Error
| ^^^^^^^ lifetime argument not allowed
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/parameter_number_and_kind.rs:22:38
|
LL | type FErr2<T> = Self::E<'static, T, u32>; // Error
@@ -36,5 +36,4 @@
error: aborting due to 5 previous errors
-Some errors occurred: E0109, E0110.
-For more information about an error, try `rustc --explain E0109`.
+For more information about this error, try `rustc --explain E0109`.
diff --git a/src/test/ui/rfc1598-generic-associated-types/pointer_family.rs b/src/test/ui/rfc1598-generic-associated-types/pointer_family.rs
index 2d188ae..edeeaba 100644
--- a/src/test/ui/rfc1598-generic-associated-types/pointer_family.rs
+++ b/src/test/ui/rfc1598-generic-associated-types/pointer_family.rs
@@ -10,7 +10,7 @@
trait PointerFamily {
type Pointer<T>: Deref<Target = T>;
fn new<T>(value: T) -> Self::Pointer<T>;
- //~^ ERROR type arguments are not allowed on this entity [E0109]
+ //~^ ERROR type arguments are not allowed for this type [E0109]
}
struct ArcFamily;
@@ -18,7 +18,7 @@
impl PointerFamily for ArcFamily {
type Pointer<T> = Arc<T>;
fn new<T>(value: T) -> Self::Pointer<T> {
- //~^ ERROR type arguments are not allowed on this entity [E0109]
+ //~^ ERROR type arguments are not allowed for this type [E0109]
Arc::new(value)
}
}
@@ -28,14 +28,14 @@
impl PointerFamily for RcFamily {
type Pointer<T> = Rc<T>;
fn new<T>(value: T) -> Self::Pointer<T> {
- //~^ ERROR type arguments are not allowed on this entity [E0109]
+ //~^ ERROR type arguments are not allowed for this type [E0109]
Rc::new(value)
}
}
struct Foo<P: PointerFamily> {
bar: P::Pointer<String>,
- //~^ ERROR type arguments are not allowed on this entity [E0109]
+ //~^ ERROR type arguments are not allowed for this type [E0109]
}
fn main() {}
diff --git a/src/test/ui/rfc1598-generic-associated-types/pointer_family.stderr b/src/test/ui/rfc1598-generic-associated-types/pointer_family.stderr
index 2b9eed2..0966f8f 100644
--- a/src/test/ui/rfc1598-generic-associated-types/pointer_family.stderr
+++ b/src/test/ui/rfc1598-generic-associated-types/pointer_family.stderr
@@ -4,25 +4,25 @@
LL | #![feature(generic_associated_types)]
| ^^^^^^^^^^^^^^^^^^^^^^^^
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/pointer_family.rs:37:21
|
LL | bar: P::Pointer<String>,
| ^^^^^^ type argument not allowed
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/pointer_family.rs:12:42
|
LL | fn new<T>(value: T) -> Self::Pointer<T>;
| ^ type argument not allowed
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/pointer_family.rs:20:42
|
LL | fn new<T>(value: T) -> Self::Pointer<T> {
| ^ type argument not allowed
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/pointer_family.rs:30:42
|
LL | fn new<T>(value: T) -> Self::Pointer<T> {
diff --git a/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.rs b/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.rs
index e018416..4e177fb 100644
--- a/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.rs
+++ b/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.rs
@@ -10,13 +10,13 @@
type Item<'a>;
// Applying the lifetime parameter `'a` to `Self::Item` inside the trait.
fn next<'a>(&'a self) -> Option<Self::Item<'a>>;
- //~^ ERROR lifetime arguments are not allowed on this entity [E0110]
+ //~^ ERROR lifetime arguments are not allowed for this type [E0109]
}
struct Foo<T: StreamingIterator> {
// Applying a concrete lifetime to the constructor outside the trait.
bar: <T as StreamingIterator>::Item<'static>,
- //~^ ERROR lifetime arguments are not allowed on this entity [E0110]
+ //~^ ERROR lifetime arguments are not allowed for this type [E0109]
}
// Users can bound parameters by the type constructed by that trait's associated type constructor
@@ -24,7 +24,7 @@
//FIXME(sunjay): This next line should parse and be valid
//fn foo<T: for<'a> StreamingIterator<Item<'a>=&'a [i32]>>(iter: T) { /* ... */ }
fn foo<T>(iter: T) where T: StreamingIterator, for<'a> T::Item<'a>: Display { /* ... */ }
-//~^ ERROR lifetime arguments are not allowed on this entity [E0110]
+//~^ ERROR lifetime arguments are not allowed for this type [E0109]
// Full example of enumerate iterator
@@ -36,9 +36,9 @@
impl<I: StreamingIterator> StreamingIterator for StreamEnumerate<I> {
type Item<'a> = (usize, I::Item<'a>);
- //~^ ERROR lifetime arguments are not allowed on this entity [E0110]
+ //~^ ERROR lifetime arguments are not allowed for this type [E0109]
fn next<'a>(&'a self) -> Option<Self::Item<'a>> {
- //~^ ERROR lifetime arguments are not allowed on this entity [E0110]
+ //~^ ERROR lifetime arguments are not allowed for this type [E0109]
match self.iter.next() {
None => None,
Some(val) => {
diff --git a/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.stderr b/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.stderr
index 5afbba5..5fc1e3d 100644
--- a/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.stderr
+++ b/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.stderr
@@ -4,31 +4,31 @@
LL | #![feature(generic_associated_types)]
| ^^^^^^^^^^^^^^^^^^^^^^^^
-error[E0110]: lifetime arguments are not allowed on this entity
+error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/streaming_iterator.rs:18:41
|
LL | bar: <T as StreamingIterator>::Item<'static>,
| ^^^^^^^ lifetime argument not allowed
-error[E0110]: lifetime arguments are not allowed on this entity
+error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/streaming_iterator.rs:26:64
|
LL | fn foo<T>(iter: T) where T: StreamingIterator, for<'a> T::Item<'a>: Display { /* ... */ }
| ^^ lifetime argument not allowed
-error[E0110]: lifetime arguments are not allowed on this entity
+error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/streaming_iterator.rs:12:48
|
LL | fn next<'a>(&'a self) -> Option<Self::Item<'a>>;
| ^^ lifetime argument not allowed
-error[E0110]: lifetime arguments are not allowed on this entity
+error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/streaming_iterator.rs:38:37
|
LL | type Item<'a> = (usize, I::Item<'a>);
| ^^ lifetime argument not allowed
-error[E0110]: lifetime arguments are not allowed on this entity
+error[E0109]: lifetime arguments are not allowed for this type
--> $DIR/streaming_iterator.rs:40:48
|
LL | fn next<'a>(&'a self) -> Option<Self::Item<'a>> {
@@ -36,4 +36,4 @@
error: aborting due to 5 previous errors
-For more information about this error, try `rustc --explain E0110`.
+For more information about this error, try `rustc --explain E0109`.
diff --git a/src/test/ui/rust-2018/uniform-paths/auxiliary/cross-crate.rs b/src/test/ui/rust-2018/uniform-paths/auxiliary/cross-crate.rs
new file mode 100644
index 0000000..4aa5d18
--- /dev/null
+++ b/src/test/ui/rust-2018/uniform-paths/auxiliary/cross-crate.rs
@@ -0,0 +1,5 @@
+// edition:2018
+
+pub use ignore as built_in_attr;
+pub use u8 as built_in_type;
+pub use rustfmt as tool_mod;
diff --git a/src/test/ui/rust-2018/uniform-paths/cross-crate.rs b/src/test/ui/rust-2018/uniform-paths/cross-crate.rs
new file mode 100644
index 0000000..27d6dbf
--- /dev/null
+++ b/src/test/ui/rust-2018/uniform-paths/cross-crate.rs
@@ -0,0 +1,11 @@
+// edition:2018
+// aux-build:cross-crate.rs
+
+extern crate cross_crate;
+use cross_crate::*;
+
+#[built_in_attr] //~ ERROR cannot use a built-in attribute through an import
+#[tool_mod::skip] //~ ERROR cannot use a tool module through an import
+fn main() {
+ let _: built_in_type; // OK
+}
diff --git a/src/test/ui/rust-2018/uniform-paths/cross-crate.stderr b/src/test/ui/rust-2018/uniform-paths/cross-crate.stderr
new file mode 100644
index 0000000..fdde75f
--- /dev/null
+++ b/src/test/ui/rust-2018/uniform-paths/cross-crate.stderr
@@ -0,0 +1,26 @@
+error: cannot use a built-in attribute through an import
+ --> $DIR/cross-crate.rs:7:3
+ |
+LL | #[built_in_attr]
+ | ^^^^^^^^^^^^^
+ |
+note: the built-in attribute imported here
+ --> $DIR/cross-crate.rs:5:5
+ |
+LL | use cross_crate::*;
+ | ^^^^^^^^^^^^^^
+
+error: cannot use a tool module through an import
+ --> $DIR/cross-crate.rs:8:3
+ |
+LL | #[tool_mod::skip]
+ | ^^^^^^^^
+ |
+note: the tool module imported here
+ --> $DIR/cross-crate.rs:5:5
+ |
+LL | use cross_crate::*;
+ | ^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/simd-type.rs b/src/test/ui/simd-type.rs
index d1e2efa..9e4b7e7 100644
--- a/src/test/ui/simd-type.rs
+++ b/src/test/ui/simd-type.rs
@@ -7,7 +7,4 @@
#[repr(simd)]
struct i64f64(i64, f64); //~ ERROR SIMD vector should be homogeneous
-#[repr(simd)]
-struct int4(isize, isize, isize, isize); //~ ERROR SIMD vector element type should be machine type
-
fn main() {}
diff --git a/src/test/ui/simd-type.stderr b/src/test/ui/simd-type.stderr
index 027afcb..48b9916 100644
--- a/src/test/ui/simd-type.stderr
+++ b/src/test/ui/simd-type.stderr
@@ -10,13 +10,7 @@
LL | struct i64f64(i64, f64);
| ^^^^^^^^^^^^^^^^^^^^^^^^ SIMD elements must have the same type
-error[E0077]: SIMD vector element type should be machine type
- --> $DIR/simd-type.rs:11:1
- |
-LL | struct int4(isize, isize, isize, isize);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+error: aborting due to 2 previous errors
-error: aborting due to 3 previous errors
-
-Some errors occurred: E0075, E0076, E0077.
+Some errors occurred: E0075, E0076.
For more information about an error, try `rustc --explain E0075`.
diff --git a/src/test/ui/specialization/specialization-overlap-hygiene.rs b/src/test/ui/specialization/specialization-overlap-hygiene.rs
new file mode 100644
index 0000000..93e7c83
--- /dev/null
+++ b/src/test/ui/specialization/specialization-overlap-hygiene.rs
@@ -0,0 +1,23 @@
+#![feature(decl_macro)]
+
+struct X;
+
+macro_rules! define_f_legacy { () => {
+ fn f() {}
+}}
+macro define_g_modern() {
+ fn g() {}
+}
+
+impl X {
+ fn f() {} //~ ERROR duplicate definitions with name `f`
+ fn g() {} // OK
+}
+impl X {
+ define_f_legacy!();
+}
+impl X {
+ define_g_modern!();
+}
+
+fn main() {}
diff --git a/src/test/ui/specialization/specialization-overlap-hygiene.stderr b/src/test/ui/specialization/specialization-overlap-hygiene.stderr
new file mode 100644
index 0000000..6adf16d
--- /dev/null
+++ b/src/test/ui/specialization/specialization-overlap-hygiene.stderr
@@ -0,0 +1,12 @@
+error[E0592]: duplicate definitions with name `f`
+ --> $DIR/specialization-overlap-hygiene.rs:13:4
+ |
+LL | fn f() {}
+ | --------- other definition for `f`
+...
+LL | fn f() {}
+ | ^^^^^^^^^ duplicate definitions for `f`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0592`.
diff --git a/src/test/ui/structs/struct-path-associated-type.rs b/src/test/ui/structs/struct-path-associated-type.rs
index 7c77085..15b37fa 100644
--- a/src/test/ui/structs/struct-path-associated-type.rs
+++ b/src/test/ui/structs/struct-path-associated-type.rs
@@ -13,7 +13,7 @@
//~^ ERROR expected struct, variant or union type, found associated type
let z = T::A::<u8> {};
//~^ ERROR expected struct, variant or union type, found associated type
- //~| ERROR type arguments are not allowed on this entity
+ //~| ERROR type arguments are not allowed for this type
match S {
T::A {} => {}
//~^ ERROR expected struct, variant or union type, found associated type
@@ -22,7 +22,7 @@
fn g<T: Tr<A = S>>() {
let s = T::A {}; // OK
- let z = T::A::<u8> {}; //~ ERROR type arguments are not allowed on this entity
+ let z = T::A::<u8> {}; //~ ERROR type arguments are not allowed for this type
match S {
T::A {} => {} // OK
}
@@ -31,7 +31,7 @@
fn main() {
let s = S::A {}; //~ ERROR ambiguous associated type
let z = S::A::<u8> {}; //~ ERROR ambiguous associated type
- //~^ ERROR type arguments are not allowed on this entity
+ //~^ ERROR type arguments are not allowed for this type
match S {
S::A {} => {} //~ ERROR ambiguous associated type
}
diff --git a/src/test/ui/structs/struct-path-associated-type.stderr b/src/test/ui/structs/struct-path-associated-type.stderr
index 0ca64ed..f054bd3 100644
--- a/src/test/ui/structs/struct-path-associated-type.stderr
+++ b/src/test/ui/structs/struct-path-associated-type.stderr
@@ -4,7 +4,7 @@
LL | let s = T::A {};
| ^^^^ not a struct
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/struct-path-associated-type.rs:14:20
|
LL | let z = T::A::<u8> {};
@@ -22,7 +22,7 @@
LL | T::A {} => {}
| ^^^^ not a struct
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/struct-path-associated-type.rs:25:20
|
LL | let z = T::A::<u8> {};
@@ -34,7 +34,7 @@
LL | let s = S::A {};
| ^^^^ help: use fully-qualified syntax: `<S as Trait>::A`
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/struct-path-associated-type.rs:33:20
|
LL | let z = S::A::<u8> {};
diff --git a/src/test/ui/structs/struct-path-self.rs b/src/test/ui/structs/struct-path-self.rs
index 51ed9e5..77880bf 100644
--- a/src/test/ui/structs/struct-path-self.rs
+++ b/src/test/ui/structs/struct-path-self.rs
@@ -6,7 +6,7 @@
//~^ ERROR expected struct, variant or union type, found Self
let z = Self::<u8> {};
//~^ ERROR expected struct, variant or union type, found Self
- //~| ERROR type arguments are not allowed on this entity
+ //~| ERROR type arguments are not allowed for this type
match s {
Self { .. } => {}
//~^ ERROR expected struct, variant or union type, found Self
@@ -17,7 +17,7 @@
impl Tr for S {
fn f() {
let s = Self {}; // OK
- let z = Self::<u8> {}; //~ ERROR type arguments are not allowed on this entity
+ let z = Self::<u8> {}; //~ ERROR type arguments are not allowed for this type
match s {
Self { .. } => {} // OK
}
@@ -27,7 +27,7 @@
impl S {
fn g() {
let s = Self {}; // OK
- let z = Self::<u8> {}; //~ ERROR type arguments are not allowed on this entity
+ let z = Self::<u8> {}; //~ ERROR type arguments are not allowed for this type
match s {
Self { .. } => {} // OK
}
diff --git a/src/test/ui/structs/struct-path-self.stderr b/src/test/ui/structs/struct-path-self.stderr
index 0fb02b9..d9e84ac 100644
--- a/src/test/ui/structs/struct-path-self.stderr
+++ b/src/test/ui/structs/struct-path-self.stderr
@@ -4,7 +4,7 @@
LL | let s = Self {};
| ^^^^ not a struct
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/struct-path-self.rs:7:24
|
LL | let z = Self::<u8> {};
@@ -22,13 +22,13 @@
LL | Self { .. } => {}
| ^^^^ not a struct
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/struct-path-self.rs:20:24
|
LL | let z = Self::<u8> {};
| ^^ type argument not allowed
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/struct-path-self.rs:30:24
|
LL | let z = Self::<u8> {};
diff --git a/src/test/ui/suggestions/return-without-lifetime.rs b/src/test/ui/suggestions/return-without-lifetime.rs
new file mode 100644
index 0000000..9bfce11
--- /dev/null
+++ b/src/test/ui/suggestions/return-without-lifetime.rs
@@ -0,0 +1,10 @@
+struct Thing<'a>(&'a ());
+struct Foo<'a>(&usize);
+//~^ ERROR missing lifetime specifier
+
+fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() }
+//~^ ERROR missing lifetime specifier
+fn func2<'a>(_arg: &Thing<'a>) -> &() { unimplemented!() }
+//~^ ERROR missing lifetime specifier
+
+fn main() {}
diff --git a/src/test/ui/suggestions/return-without-lifetime.stderr b/src/test/ui/suggestions/return-without-lifetime.stderr
new file mode 100644
index 0000000..7f5ff95
--- /dev/null
+++ b/src/test/ui/suggestions/return-without-lifetime.stderr
@@ -0,0 +1,25 @@
+error[E0106]: missing lifetime specifier
+ --> $DIR/return-without-lifetime.rs:2:16
+ |
+LL | struct Foo<'a>(&usize);
+ | ^ help: consider using the named lifetime: `&'a`
+
+error[E0106]: missing lifetime specifier
+ --> $DIR/return-without-lifetime.rs:5:34
+ |
+LL | fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() }
+ | ^ help: consider using the named lifetime: `&'a`
+ |
+ = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from
+
+error[E0106]: missing lifetime specifier
+ --> $DIR/return-without-lifetime.rs:7:35
+ |
+LL | fn func2<'a>(_arg: &Thing<'a>) -> &() { unimplemented!() }
+ | ^ help: consider using the named lifetime: `&'a`
+ |
+ = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/suggestions/suggest-on-bare-closure-call.rs b/src/test/ui/suggestions/suggest-on-bare-closure-call.rs
new file mode 100644
index 0000000..355708c
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-on-bare-closure-call.rs
@@ -0,0 +1,4 @@
+fn main() {
+ let _ = ||{}();
+ //~^ ERROR expected function, found `()`
+}
diff --git a/src/test/ui/suggestions/suggest-on-bare-closure-call.stderr b/src/test/ui/suggestions/suggest-on-bare-closure-call.stderr
new file mode 100644
index 0000000..17001e3
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-on-bare-closure-call.stderr
@@ -0,0 +1,15 @@
+error[E0618]: expected function, found `()`
+ --> $DIR/suggest-on-bare-closure-call.rs:2:15
+ |
+LL | let _ = ||{}();
+ | ^^--
+ | |
+ | call expression requires function
+help: if you meant to create this closure and immediately call it, surround the closure with parenthesis
+ |
+LL | let _ = (||{})();
+ | ^ ^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0618`.
diff --git a/src/test/ui/type-alias-enum-variants.rs b/src/test/ui/type-alias-enum-variants.rs
index 3ec200d..c5974e5 100644
--- a/src/test/ui/type-alias-enum-variants.rs
+++ b/src/test/ui/type-alias-enum-variants.rs
@@ -7,5 +7,5 @@
let _ = Option::None::<u8>; // OK (Lint in future!)
let _ = Alias::<u8>::None; // OK
let _ = Alias::None::<u8>; // Error
- //~^ type arguments are not allowed on this entity
+ //~^ type arguments are not allowed for this type
}
diff --git a/src/test/ui/type-alias-enum-variants.stderr b/src/test/ui/type-alias-enum-variants.stderr
index cf81f5b..55f250f 100644
--- a/src/test/ui/type-alias-enum-variants.stderr
+++ b/src/test/ui/type-alias-enum-variants.stderr
@@ -1,4 +1,4 @@
-error[E0109]: type arguments are not allowed on this entity
+error[E0109]: type arguments are not allowed for this type
--> $DIR/type-alias-enum-variants.rs:9:27
|
LL | let _ = Alias::None::<u8>; // Error
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-mutated-upvar-from-fn-closure.ast.nll.stderr b/src/test/ui/unboxed-closures/unboxed-closures-mutated-upvar-from-fn-closure.ast.nll.stderr
index 2f83a64..3440ede 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-mutated-upvar-from-fn-closure.ast.nll.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closures-mutated-upvar-from-fn-closure.ast.nll.stderr
@@ -10,8 +10,8 @@
LL | call(|| {
| __________^
LL | | counter += 1;
-LL | | //[ast]~^ ERROR cannot assign to data in a captured outer variable in an `Fn` closure
-LL | | //[mir]~^^ ERROR cannot assign to `counter`
+LL | |
+LL | |
LL | | });
| |_____^
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-mutated-upvar-from-fn-closure.ast.stderr b/src/test/ui/unboxed-closures/unboxed-closures-mutated-upvar-from-fn-closure.ast.stderr
index 293f59f..0788350 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-mutated-upvar-from-fn-closure.ast.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closures-mutated-upvar-from-fn-closure.ast.stderr
@@ -10,8 +10,8 @@
LL | call(|| {
| __________^
LL | | counter += 1;
-LL | | //[ast]~^ ERROR cannot assign to data in a captured outer variable in an `Fn` closure
-LL | | //[mir]~^^ ERROR cannot assign to `counter`
+LL | |
+LL | |
LL | | });
| |_____^
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-mutated-upvar-from-fn-closure.mir.stderr b/src/test/ui/unboxed-closures/unboxed-closures-mutated-upvar-from-fn-closure.mir.stderr
index 2f83a64..3440ede 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-mutated-upvar-from-fn-closure.mir.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closures-mutated-upvar-from-fn-closure.mir.stderr
@@ -10,8 +10,8 @@
LL | call(|| {
| __________^
LL | | counter += 1;
-LL | | //[ast]~^ ERROR cannot assign to data in a captured outer variable in an `Fn` closure
-LL | | //[mir]~^^ ERROR cannot assign to `counter`
+LL | |
+LL | |
LL | | });
| |_____^
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index d44a51a..3c360a8 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -10,7 +10,7 @@
use std::path::{PathBuf, Path};
use std::process::{Command, Stdio};
-static HOSTS: &'static [&'static str] = &[
+static HOSTS: &[&str] = &[
"aarch64-unknown-linux-gnu",
"arm-unknown-linux-gnueabi",
"arm-unknown-linux-gnueabihf",
@@ -23,6 +23,10 @@
"mips64-unknown-linux-gnuabi64",
"mips64el-unknown-linux-gnuabi64",
"mipsel-unknown-linux-gnu",
+ "mipsisa32r6-unknown-linux-gnu",
+ "mipsisa32r6el-unknown-linux-gnu",
+ "mipsisa64r6-unknown-linux-gnuabi64",
+ "mipsisa64r6el-unknown-linux-gnuabi64",
"powerpc-unknown-linux-gnu",
"powerpc64-unknown-linux-gnu",
"powerpc64le-unknown-linux-gnu",
@@ -32,10 +36,11 @@
"x86_64-pc-windows-msvc",
"x86_64-unknown-freebsd",
"x86_64-unknown-linux-gnu",
+ "x86_64-unknown-linux-musl",
"x86_64-unknown-netbsd",
];
-static TARGETS: &'static [&'static str] = &[
+static TARGETS: &[&str] = &[
"aarch64-apple-ios",
"aarch64-fuchsia",
"aarch64-linux-android",
@@ -77,6 +82,10 @@
"mips-unknown-linux-musl",
"mips64-unknown-linux-gnuabi64",
"mips64el-unknown-linux-gnuabi64",
+ "mipsisa32r6-unknown-linux-gnu",
+ "mipsisa32r6el-unknown-linux-gnu",
+ "mipsisa64r6-unknown-linux-gnuabi64",
+ "mipsisa64r6el-unknown-linux-gnuabi64",
"mipsel-unknown-linux-gnu",
"mipsel-unknown-linux-musl",
"nvptx64-nvidia-cuda",
@@ -115,7 +124,7 @@
"x86_64-unknown-redox",
];
-static DOCS_TARGETS: &'static [&'static str] = &[
+static DOCS_TARGETS: &[&str] = &[
"i686-apple-darwin",
"i686-pc-windows-gnu",
"i686-pc-windows-msvc",
@@ -126,7 +135,7 @@
"x86_64-unknown-linux-gnu",
];
-static MINGW: &'static [&'static str] = &[
+static MINGW: &[&str] = &[
"i686-pc-windows-gnu",
"x86_64-pc-windows-gnu",
];
@@ -153,7 +162,7 @@
to: String,
}
-#[derive(Serialize)]
+#[derive(Serialize, Default)]
struct Target {
available: bool,
url: Option<String>,
@@ -165,17 +174,7 @@
}
impl Target {
- fn unavailable() -> Target {
- Target {
- available: false,
- url: None,
- hash: None,
- xz_url: None,
- xz_hash: None,
- components: None,
- extensions: None,
- }
- }
+ fn unavailable() -> Self { Self::default() }
}
#[derive(Serialize)]
@@ -184,6 +183,12 @@
target: String,
}
+impl Component {
+ fn from_str(pkg: &str, target: &str) -> Self {
+ Self { pkg: pkg.to_string(), target: target.to_string() }
+ }
+}
+
macro_rules! t {
($e:expr) => (match $e {
Ok(e) => e,
@@ -301,6 +306,25 @@
}.build();
}
+enum PkgType { RustSrc, Cargo, Rls, Clippy, Rustfmt, LlvmTools, Lldb, Miri, Other }
+
+impl PkgType {
+ fn from_component(component: &str) -> Self {
+ use PkgType::*;
+ match component {
+ "rust-src" => RustSrc,
+ "cargo" => Cargo,
+ "rls" | "rls-preview" => Rls,
+ "clippy" | "clippy-preview" => Clippy,
+ "rustfmt" | "rustfmt-preview" => Rustfmt,
+ "llvm-tools" | "llvm-tools-preview" => LlvmTools,
+ "lldb" | "lldb-preview" => Lldb,
+ "miri" | "miri-preview" => Miri,
+ _ => Other,
+ }
+ }
+}
+
impl Builder {
fn build(&mut self) {
self.rust_version = self.version("rust", "x86_64-unknown-linux-gnu");
@@ -349,39 +373,57 @@
renames: BTreeMap::new(),
profiles: BTreeMap::new(),
};
+ self.add_packages_to(&mut manifest);
+ self.add_profiles_to(&mut manifest);
+ self.add_renames_to(&mut manifest);
+ manifest.pkg.insert("rust".to_string(), self.rust_package(&manifest));
+ manifest
+ }
- self.package("rustc", &mut manifest.pkg, HOSTS);
- self.package("cargo", &mut manifest.pkg, HOSTS);
- self.package("rust-mingw", &mut manifest.pkg, MINGW);
- self.package("rust-std", &mut manifest.pkg, TARGETS);
- self.package("rust-docs", &mut manifest.pkg, DOCS_TARGETS);
- self.package("rust-src", &mut manifest.pkg, &["*"]);
- self.package("rls-preview", &mut manifest.pkg, HOSTS);
- self.package("clippy-preview", &mut manifest.pkg, HOSTS);
- self.package("miri", &mut manifest.pkg, HOSTS);
- self.package("rustfmt-preview", &mut manifest.pkg, HOSTS);
- self.package("rust-analysis", &mut manifest.pkg, TARGETS);
- self.package("llvm-tools-preview", &mut manifest.pkg, TARGETS);
- self.package("lldb-preview", &mut manifest.pkg, TARGETS);
+ fn add_packages_to(&mut self, manifest: &mut Manifest) {
+ let mut package = |name, targets| self.package(name, &mut manifest.pkg, targets);
+ package("rustc", HOSTS);
+ package("cargo", HOSTS);
+ package("rust-mingw", MINGW);
+ package("rust-std", TARGETS);
+ package("rust-docs", DOCS_TARGETS);
+ package("rust-src", &["*"]);
+ package("rls-preview", HOSTS);
+ package("clippy-preview", HOSTS);
+ package("miri-preview", HOSTS);
+ package("rustfmt-preview", HOSTS);
+ package("rust-analysis", TARGETS);
+ package("llvm-tools-preview", TARGETS);
+ package("lldb-preview", TARGETS);
+ }
- self.profile("minimal",
- &mut manifest.profiles,
- &["rustc", "cargo", "rust-std", "rust-mingw"]);
- self.profile("default",
- &mut manifest.profiles,
- &["rustc", "cargo", "rust-std", "rust-mingw",
- "rust-docs", "rustfmt-preview", "clippy-preview"]);
- self.profile("complete",
- &mut manifest.profiles,
- &["rustc", "cargo", "rust-std", "rust-mingw",
- "rust-docs", "rustfmt-preview", "clippy-preview",
- "rls-preview", "rust-src", "llvm-tools-preview",
- "lldb-preview", "rust-analysis", "miri"]);
+ fn add_profiles_to(&mut self, manifest: &mut Manifest) {
+ let mut profile = |name, pkgs| self.profile(name, &mut manifest.profiles, pkgs);
+ profile("minimal", &["rustc", "cargo", "rust-std", "rust-mingw"]);
+ profile("default", &[
+ "rustc", "cargo", "rust-std", "rust-mingw",
+ "rust-docs", "rustfmt-preview", "clippy-preview"
+ ]);
+ profile("complete", &[
+ "rustc", "cargo", "rust-std", "rust-mingw",
+ "rust-docs", "rustfmt-preview", "clippy-preview",
+ "rls-preview", "rust-src", "llvm-tools-preview",
+ "lldb-preview", "rust-analysis", "miri-preview"
+ ]);
+ }
- manifest.renames.insert("rls".to_owned(), Rename { to: "rls-preview".to_owned() });
- manifest.renames.insert("rustfmt".to_owned(), Rename { to: "rustfmt-preview".to_owned() });
- manifest.renames.insert("clippy".to_owned(), Rename { to: "clippy-preview".to_owned() });
+ fn add_renames_to(&self, manifest: &mut Manifest) {
+ let mut rename = |from: &str, to: &str| manifest.renames.insert(
+ from.to_owned(),
+ Rename { to: to.to_owned() }
+ );
+ rename("rls", "rls-preview");
+ rename("rustfmt", "rustfmt-preview");
+ rename("clippy", "clippy-preview");
+ rename("miri", "miri-preview");
+ }
+ fn rust_package(&mut self, manifest: &Manifest) -> Package {
let mut pkg = Package {
version: self.cached_version("rust")
.as_ref()
@@ -391,90 +433,82 @@
target: BTreeMap::new(),
};
for host in HOSTS {
- let filename = self.filename("rust", host);
- let digest = match self.digests.remove(&filename) {
- Some(digest) => digest,
- None => {
- pkg.target.insert(host.to_string(), Target::unavailable());
- continue
- }
- };
- let xz_filename = filename.replace(".tar.gz", ".tar.xz");
- let xz_digest = self.digests.remove(&xz_filename);
- let mut components = Vec::new();
- let mut extensions = Vec::new();
-
- // rustc/rust-std/cargo/docs are all required, and so is rust-mingw
- // if it's available for the target.
- components.extend(vec![
- Component { pkg: "rustc".to_string(), target: host.to_string() },
- Component { pkg: "rust-std".to_string(), target: host.to_string() },
- Component { pkg: "cargo".to_string(), target: host.to_string() },
- Component { pkg: "rust-docs".to_string(), target: host.to_string() },
- ]);
- if host.contains("pc-windows-gnu") {
- components.push(Component {
- pkg: "rust-mingw".to_string(),
- target: host.to_string(),
- });
+ if let Some(target) = self.target_host_combination(host, &manifest) {
+ pkg.target.insert(host.to_string(), target);
+ } else {
+ pkg.target.insert(host.to_string(), Target::unavailable());
+ continue
}
-
- // Tools are always present in the manifest, but might be marked as unavailable if they
- // weren't built
- extensions.extend(vec![
- Component { pkg: "clippy-preview".to_string(), target: host.to_string() },
- Component { pkg: "miri".to_string(), target: host.to_string() },
- Component { pkg: "rls-preview".to_string(), target: host.to_string() },
- Component { pkg: "rustfmt-preview".to_string(), target: host.to_string() },
- Component { pkg: "llvm-tools-preview".to_string(), target: host.to_string() },
- Component { pkg: "lldb-preview".to_string(), target: host.to_string() },
- Component { pkg: "rust-analysis".to_string(), target: host.to_string() },
- ]);
-
- for target in TARGETS {
- if target != host {
- extensions.push(Component {
- pkg: "rust-std".to_string(),
- target: target.to_string(),
- });
- }
- }
- extensions.push(Component {
- pkg: "rust-src".to_string(),
- target: "*".to_string(),
- });
-
- // If the components/extensions don't actually exist for this
- // particular host/target combination then nix it entirely from our
- // lists.
- {
- let has_component = |c: &Component| {
- if c.target == "*" {
- return true
- }
- let pkg = match manifest.pkg.get(&c.pkg) {
- Some(p) => p,
- None => return false,
- };
- pkg.target.get(&c.target).is_some()
- };
- extensions.retain(&has_component);
- components.retain(&has_component);
- }
-
- pkg.target.insert(host.to_string(), Target {
- available: true,
- url: Some(self.url(&filename)),
- hash: Some(digest),
- xz_url: xz_digest.as_ref().map(|_| self.url(&xz_filename)),
- xz_hash: xz_digest,
- components: Some(components),
- extensions: Some(extensions),
- });
}
- manifest.pkg.insert("rust".to_string(), pkg);
+ pkg
+ }
- manifest
+ fn target_host_combination(&mut self, host: &str, manifest: &Manifest) -> Option<Target> {
+ let filename = self.filename("rust", host);
+ let digest = self.digests.remove(&filename)?;
+ let xz_filename = filename.replace(".tar.gz", ".tar.xz");
+ let xz_digest = self.digests.remove(&xz_filename);
+ let mut components = Vec::new();
+ let mut extensions = Vec::new();
+
+ let host_component = |pkg| Component::from_str(pkg, host);
+
+ // rustc/rust-std/cargo/docs are all required,
+ // and so is rust-mingw if it's available for the target.
+ components.extend(vec![
+ host_component("rustc"),
+ host_component("rust-std"),
+ host_component("cargo"),
+ host_component("rust-docs"),
+ ]);
+ if host.contains("pc-windows-gnu") {
+ components.push(host_component("rust-mingw"));
+ }
+
+ // Tools are always present in the manifest,
+ // but might be marked as unavailable if they weren't built.
+ extensions.extend(vec![
+ host_component("clippy-preview"),
+ host_component("miri-preview"),
+ host_component("rls-preview"),
+ host_component("rustfmt-preview"),
+ host_component("llvm-tools-preview"),
+ host_component("lldb-preview"),
+ host_component("rust-analysis"),
+ ]);
+
+ extensions.extend(
+ TARGETS.iter()
+ .filter(|&&target| target != host)
+ .map(|target| Component::from_str("rust-std", target))
+ );
+ extensions.push(Component::from_str("rust-src", "*"));
+
+ // If the components/extensions don't actually exist for this
+ // particular host/target combination then nix it entirely from our
+ // lists.
+ let has_component = |c: &Component| {
+ if c.target == "*" {
+ return true
+ }
+ let pkg = match manifest.pkg.get(&c.pkg) {
+ Some(p) => p,
+ None => return false,
+ };
+ pkg.target.get(&c.target).is_some()
+ };
+ extensions.retain(&has_component);
+ components.retain(&has_component);
+
+ Some(Target {
+ available: true,
+ url: Some(self.url(&filename)),
+ hash: Some(digest),
+ xz_url: xz_digest.as_ref().map(|_| self.url(&xz_filename)),
+ xz_hash: xz_digest,
+ components: Some(components),
+ extensions: Some(extensions),
+ })
}
fn profile(&mut self,
@@ -488,10 +522,11 @@
pkgname: &str,
dst: &mut BTreeMap<String, Package>,
targets: &[&str]) {
- let (version, is_present) = match *self.cached_version(pkgname) {
- Some(ref version) => (version.clone(), true),
- None => (String::new(), false),
- };
+ let (version, is_present) = self.cached_version(pkgname)
+ .as_ref()
+ .cloned()
+ .map(|version| (version, true))
+ .unwrap_or_default();
let targets = targets.iter().map(|name| {
if is_present {
@@ -515,15 +550,7 @@
} else {
// If the component is not present for this build add it anyway but mark it as
// unavailable -- this way rustup won't allow upgrades without --force
- (name.to_string(), Target {
- available: false,
- url: None,
- hash: None,
- xz_url: None,
- xz_hash: None,
- components: None,
- extensions: None,
- })
+ (name.to_string(), Target::unavailable())
}
}).collect();
@@ -542,89 +569,65 @@
}
fn filename(&self, component: &str, target: &str) -> String {
- if component == "rust-src" {
- format!("rust-src-{}.tar.gz", self.rust_release)
- } else if component == "cargo" {
- format!("cargo-{}-{}.tar.gz", self.cargo_release, target)
- } else if component == "rls" || component == "rls-preview" {
- format!("rls-{}-{}.tar.gz", self.rls_release, target)
- } else if component == "clippy" || component == "clippy-preview" {
- format!("clippy-{}-{}.tar.gz", self.clippy_release, target)
- } else if component == "rustfmt" || component == "rustfmt-preview" {
- format!("rustfmt-{}-{}.tar.gz", self.rustfmt_release, target)
- } else if component == "llvm-tools" || component == "llvm-tools-preview" {
- format!("llvm-tools-{}-{}.tar.gz", self.llvm_tools_release, target)
- } else if component == "lldb" || component == "lldb-preview" {
- format!("lldb-{}-{}.tar.gz", self.lldb_release, target)
- } else if component == "miri" || component == "miri-preview" {
- format!("miri-{}-{}.tar.gz", self.miri_release, target)
- } else {
- format!("{}-{}-{}.tar.gz", component, self.rust_release, target)
+ use PkgType::*;
+ match PkgType::from_component(component) {
+ RustSrc => format!("rust-src-{}.tar.gz", self.rust_release),
+ Cargo => format!("cargo-{}-{}.tar.gz", self.cargo_release, target),
+ Rls => format!("rls-{}-{}.tar.gz", self.rls_release, target),
+ Clippy => format!("clippy-{}-{}.tar.gz", self.clippy_release, target),
+ Rustfmt => format!("rustfmt-{}-{}.tar.gz", self.rustfmt_release, target),
+ LlvmTools => format!("llvm-tools-{}-{}.tar.gz", self.llvm_tools_release, target),
+ Lldb => format!("lldb-{}-{}.tar.gz", self.lldb_release, target),
+ Miri => format!("miri-{}-{}.tar.gz", self.miri_release, target),
+ Other => format!("{}-{}-{}.tar.gz", component, self.rust_release, target),
}
}
fn cached_version(&self, component: &str) -> &Option<String> {
- if component == "cargo" {
- &self.cargo_version
- } else if component == "rls" || component == "rls-preview" {
- &self.rls_version
- } else if component == "clippy" || component == "clippy-preview" {
- &self.clippy_version
- } else if component == "rustfmt" || component == "rustfmt-preview" {
- &self.rustfmt_version
- } else if component == "llvm-tools" || component == "llvm-tools-preview" {
- &self.llvm_tools_version
- } else if component == "lldb" || component == "lldb-preview" {
- &self.lldb_version
- } else if component == "miri" || component == "miri-preview" {
- &self.miri_version
- } else {
- &self.rust_version
+ use PkgType::*;
+ match PkgType::from_component(component) {
+ Cargo => &self.cargo_version,
+ Rls => &self.rls_version,
+ Clippy => &self.clippy_version,
+ Rustfmt => &self.rustfmt_version,
+ LlvmTools => &self.llvm_tools_version,
+ Lldb => &self.lldb_version,
+ Miri => &self.miri_version,
+ _ => &self.rust_version,
}
}
fn cached_git_commit_hash(&self, component: &str) -> &Option<String> {
- if component == "cargo" {
- &self.cargo_git_commit_hash
- } else if component == "rls" || component == "rls-preview" {
- &self.rls_git_commit_hash
- } else if component == "clippy" || component == "clippy-preview" {
- &self.clippy_git_commit_hash
- } else if component == "rustfmt" || component == "rustfmt-preview" {
- &self.rustfmt_git_commit_hash
- } else if component == "llvm-tools" || component == "llvm-tools-preview" {
- &self.llvm_tools_git_commit_hash
- } else if component == "lldb" || component == "lldb-preview" {
- &self.lldb_git_commit_hash
- } else if component == "miri" || component == "miri-preview" {
- &self.miri_git_commit_hash
- } else {
- &self.rust_git_commit_hash
+ use PkgType::*;
+ match PkgType::from_component(component) {
+ Cargo => &self.cargo_git_commit_hash,
+ Rls => &self.rls_git_commit_hash,
+ Clippy => &self.clippy_git_commit_hash,
+ Rustfmt => &self.rustfmt_git_commit_hash,
+ LlvmTools => &self.llvm_tools_git_commit_hash,
+ Lldb => &self.lldb_git_commit_hash,
+ Miri => &self.miri_git_commit_hash,
+ _ => &self.rust_git_commit_hash,
}
}
fn version(&self, component: &str, target: &str) -> Option<String> {
- let mut cmd = Command::new("tar");
- let filename = self.filename(component, target);
- cmd.arg("xf")
- .arg(self.input.join(&filename))
- .arg(format!("{}/version", filename.replace(".tar.gz", "")))
- .arg("-O");
- let output = t!(cmd.output());
- if output.status.success() {
- Some(String::from_utf8_lossy(&output.stdout).trim().to_string())
- } else {
- // Perhaps we didn't build this package.
- None
- }
+ self.untar(component, target, |filename| format!("{}/version", filename))
}
fn git_commit_hash(&self, component: &str, target: &str) -> Option<String> {
+ self.untar(component, target, |filename| format!("{}/git-commit-hash", filename))
+ }
+
+ fn untar<F>(&self, component: &str, target: &str, dir: F) -> Option<String>
+ where
+ F: FnOnce(String) -> String
+ {
let mut cmd = Command::new("tar");
let filename = self.filename(component, target);
cmd.arg("xf")
.arg(self.input.join(&filename))
- .arg(format!("{}/git-commit-hash", filename.replace(".tar.gz", "")))
+ .arg(dir(filename.replace(".tar.gz", "")))
.arg("-O");
let output = t!(cmd.output());
if output.status.success() {
diff --git a/src/tools/clippy b/src/tools/clippy
index 016d92d..92612c9 160000
--- a/src/tools/clippy
+++ b/src/tools/clippy
@@ -1 +1 @@
-Subproject commit 016d92d6ed5ae8a3785b65aa300768abbc26f818
+Subproject commit 92612c9de159889f77f05855a77482ee1d895f51
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index f0991c8..80b8a8b 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -26,6 +26,7 @@
Ui,
JsDocTest,
MirOpt,
+ Assembly,
}
impl Mode {
@@ -62,6 +63,7 @@
"ui" => Ok(Ui),
"js-doc-test" => Ok(JsDocTest),
"mir-opt" => Ok(MirOpt),
+ "assembly" => Ok(Assembly),
_ => Err(()),
}
}
@@ -86,6 +88,7 @@
Ui => "ui",
JsDocTest => "js-doc-test",
MirOpt => "mir-opt",
+ Assembly => "assembly",
};
fmt::Display::fmt(s, f)
}
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index c2c4a6b..7bf5670 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -335,6 +335,7 @@
pub failure_status: i32,
pub run_rustfix: bool,
pub rustfix_only_machine_applicable: bool,
+ pub assembly_output: Option<String>,
}
impl TestProps {
@@ -370,6 +371,7 @@
failure_status: -1,
run_rustfix: false,
rustfix_only_machine_applicable: false,
+ assembly_output: None,
}
}
@@ -517,6 +519,10 @@
self.rustfix_only_machine_applicable =
config.parse_rustfix_only_machine_applicable(ln);
}
+
+ if self.assembly_output.is_none() {
+ self.assembly_output = config.parse_assembly_output(ln);
+ }
});
if self.failure_status == -1 {
@@ -594,6 +600,7 @@
fn parse_aux_build(&self, line: &str) -> Option<String> {
self.parse_name_value_directive(line, "aux-build")
+ .map(|r| r.trim().to_string())
}
fn parse_compile_flags(&self, line: &str) -> Option<String> {
@@ -676,6 +683,11 @@
self.parse_name_directive(line, "skip-codegen")
}
+ fn parse_assembly_output(&self, line: &str) -> Option<String> {
+ self.parse_name_value_directive(line, "assembly-output")
+ .map(|r| r.trim().to_string())
+ }
+
fn parse_env(&self, line: &str, name: &str) -> Option<(String, String)> {
self.parse_name_value_directive(line, name).map(|nv| {
// nv is either FOO or FOO=BAR
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 84dd671..3e3499e 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -4,7 +4,7 @@
use crate::common::{Codegen, CodegenUnits, DebugInfoBoth, DebugInfoGdb, DebugInfoLldb, Rustdoc};
use crate::common::{CompileFail, Pretty, RunFail, RunPass, RunPassValgrind};
use crate::common::{Config, TestPaths};
-use crate::common::{Incremental, MirOpt, RunMake, Ui, JsDocTest};
+use crate::common::{Incremental, MirOpt, RunMake, Ui, JsDocTest, Assembly};
use diff;
use crate::errors::{self, Error, ErrorKind};
use filetime::FileTime;
@@ -275,6 +275,7 @@
RunMake => self.run_rmake_test(),
RunPass | Ui => self.run_ui_test(),
MirOpt => self.run_mir_opt_test(),
+ Assembly => self.run_assembly_test(),
JsDocTest => self.run_js_doc_test(),
}
}
@@ -1606,6 +1607,7 @@
|| self.config.target.contains("emscripten")
|| (self.config.target.contains("musl") && !aux_props.force_host)
|| self.config.target.contains("wasm32")
+ || self.config.target.contains("nvptx")
{
// We primarily compile all auxiliary libraries as dynamic libraries
// to avoid code size bloat and large binaries as much as possible
@@ -1805,7 +1807,7 @@
rustc.arg(dir_opt);
}
RunFail | RunPassValgrind | Pretty | DebugInfoBoth | DebugInfoGdb | DebugInfoLldb
- | Codegen | Rustdoc | RunMake | CodegenUnits | JsDocTest => {
+ | Codegen | Rustdoc | RunMake | CodegenUnits | JsDocTest | Assembly => {
// do not use JSON output
}
}
@@ -2100,12 +2102,37 @@
self.compose_and_run_compiler(rustc, None)
}
- fn check_ir_with_filecheck(&self) -> ProcRes {
- let irfile = self.output_base_name().with_extension("ll");
+ fn compile_test_and_save_assembly(&self) -> (ProcRes, PathBuf) {
+ // This works with both `--emit asm` (as default output name for the assembly)
+ // and `ptx-linker` because the latter can write output at requested location.
+ let output_path = self.output_base_name().with_extension("s");
+
+ let output_file = TargetLocation::ThisFile(output_path.clone());
+ let mut rustc = self.make_compile_args(&self.testpaths.file, output_file);
+
+ rustc.arg("-L").arg(self.aux_output_dir_name());
+
+ match self.props.assembly_output.as_ref().map(AsRef::as_ref) {
+ Some("emit-asm") => {
+ rustc.arg("--emit=asm");
+ }
+
+ Some("ptx-linker") => {
+ // No extra flags needed.
+ }
+
+ Some(_) => self.fatal("unknown 'assembly-output' header"),
+ None => self.fatal("missing 'assembly-output' header"),
+ }
+
+ (self.compose_and_run_compiler(rustc, None), output_path)
+ }
+
+ fn verify_with_filecheck(&self, output: &Path) -> ProcRes {
let mut filecheck = Command::new(self.config.llvm_filecheck.as_ref().unwrap());
filecheck
.arg("--input-file")
- .arg(irfile)
+ .arg(output)
.arg(&self.testpaths.file);
// It would be more appropriate to make most of the arguments configurable through
// a comment-attribute similar to `compile-flags`. For example, --check-prefixes is a very
@@ -2124,12 +2151,29 @@
self.fatal("missing --llvm-filecheck");
}
- let mut proc_res = self.compile_test_and_save_ir();
+ let proc_res = self.compile_test_and_save_ir();
if !proc_res.status.success() {
self.fatal_proc_rec("compilation failed!", &proc_res);
}
- proc_res = self.check_ir_with_filecheck();
+ let output_path = self.output_base_name().with_extension("ll");
+ let proc_res = self.verify_with_filecheck(&output_path);
+ if !proc_res.status.success() {
+ self.fatal_proc_rec("verification with 'FileCheck' failed", &proc_res);
+ }
+ }
+
+ fn run_assembly_test(&self) {
+ if self.config.llvm_filecheck.is_none() {
+ self.fatal("missing --llvm-filecheck");
+ }
+
+ let (proc_res, output_path) = self.compile_test_and_save_assembly();
+ if !proc_res.status.success() {
+ self.fatal_proc_rec("compilation failed!", &proc_res);
+ }
+
+ let proc_res = self.verify_with_filecheck(&output_path);
if !proc_res.status.success() {
self.fatal_proc_rec("verification with 'FileCheck' failed", &proc_res);
}
@@ -3110,7 +3154,7 @@
// Remove test annotations like `//~ ERROR text` from the output,
// since they duplicate actual errors and make the output hard to read.
- normalized = Regex::new("\\s*//~.*").unwrap()
+ normalized = Regex::new("\\s*//(\\[.*\\])?~.*").unwrap()
.replace_all(&normalized, "").into_owned();
for rule in custom_rules {
diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs
index 240287f..50dce4b 100644
--- a/src/tools/compiletest/src/util.rs
+++ b/src/tools/compiletest/src/util.rs
@@ -41,7 +41,6 @@
("armv7", "arm"),
("armv7s", "arm"),
("asmjs", "asmjs"),
- ("cuda", "cuda"),
("hexagon", "hexagon"),
("i386", "x86"),
("i586", "x86"),
@@ -49,8 +48,17 @@
("mips", "mips"),
("mips64", "mips64"),
("mips64el", "mips64"),
+ ("mipsisa32r6", "mips"),
+ ("mipsisa32r6el", "mips"),
+ ("mipsisa64r6", "mips64"),
+ ("mipsisa64r6el", "mips64"),
("mipsel", "mips"),
+ ("mipsisa32r6", "mips"),
+ ("mipsisa32r6el", "mips"),
+ ("mipsisa64r6", "mips64"),
+ ("mipsisa64r6el", "mips64"),
("msp430", "msp430"),
+ ("nvptx64", "nvptx64"),
("powerpc", "powerpc"),
("powerpc64", "powerpc64"),
("powerpc64le", "powerpc64"),
@@ -158,7 +166,7 @@
fn test_get_arch() {
assert_eq!("x86_64", get_arch("x86_64-unknown-linux-gnu"));
assert_eq!("x86_64", get_arch("amd64"));
- assert_eq!("cuda", get_arch("nvptx64-nvidia-cuda"));
+ assert_eq!("nvptx64", get_arch("nvptx64-nvidia-cuda"));
}
#[test]
diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py
index fb6132a..f2a585e 100755
--- a/src/tools/publish_toolstate.py
+++ b/src/tools/publish_toolstate.py
@@ -12,7 +12,7 @@
except ImportError:
import urllib.request as urllib2
-# List of people to ping when the status of a tool changed.
+# List of people to ping when the status of a tool or a book changed.
MAINTAINERS = {
'miri': '@oli-obk @RalfJung @eddyb',
'clippy-driver': '@Manishearth @llogiq @mcarton @oli-obk @phansch',
@@ -22,6 +22,10 @@
'nomicon': '@frewsxcv @Gankro',
'reference': '@steveklabnik @Havvy @matthewjasper @alercah',
'rust-by-example': '@steveklabnik @marioidival @projektir',
+ 'embedded-book': (
+ '@adamgreig @andre-richter @jamesmunns @korken89 '
+ '@ryankurte @thejpster @therealprof'
+ ),
}
REPOS = {
@@ -33,6 +37,7 @@
'nomicon': 'https://github.com/rust-lang-nursery/nomicon',
'reference': 'https://github.com/rust-lang-nursery/reference',
'rust-by-example': 'https://github.com/rust-lang/rust-by-example',
+ 'embedded-book': 'https://github.com/rust-embedded/book',
}
@@ -70,7 +75,7 @@
cc @{}, the PR reviewer, and @rust-lang/compiler -- nominating for prioritization.
- ''').format(relevant_pr_number, tool, REPOS[tool], relevant_pr_user, pr_reviewer),
+ ''').format(relevant_pr_number, tool, REPOS.get(tool), relevant_pr_user, pr_reviewer),
'title': '`{}` no longer builds after {}'.format(tool, relevant_pr_number),
'assignees': assignees,
'labels': ['T-compiler', 'I-nominated'],
@@ -137,7 +142,7 @@
if build_failed:
try:
issue(
- tool, MAINTAINERS.get(tool),
+ tool, MAINTAINERS.get(tool, ''),
relevant_pr_number, relevant_pr_user, pr_reviewer,
)
except IOError as e:
diff --git a/src/tools/rls b/src/tools/rls
index 6840dd6..90f7ab0 160000
--- a/src/tools/rls
+++ b/src/tools/rls
@@ -1 +1 @@
-Subproject commit 6840dd69af3ada1f8a432075f1f0be679ea8a468
+Subproject commit 90f7ab070321ebc5ad217dc0d6db163c029dffd9
diff --git a/src/tools/rustfmt b/src/tools/rustfmt
index d6829d6..1427e4c 160000
--- a/src/tools/rustfmt
+++ b/src/tools/rustfmt
@@ -1 +1 @@
-Subproject commit d6829d62dca64dfe7ceaa96d1a9c1cd36428221d
+Subproject commit 1427e4c20ba5cdc80a338347585c9de71a0dea4d