diff options
553 files changed, 6271 insertions, 3178 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fd3da15a21b..958d9b67bdf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,13 +36,13 @@ jobs: matrix: name: - mingw-check - - x86_64-gnu-llvm-7 + - x86_64-gnu-llvm-8 - x86_64-gnu-tools include: - name: mingw-check os: ubuntu-latest-xl env: {} - - name: x86_64-gnu-llvm-7 + - name: x86_64-gnu-llvm-8 os: ubuntu-latest-xl env: {} - name: x86_64-gnu-tools @@ -352,7 +352,7 @@ jobs: - x86_64-gnu-debug - x86_64-gnu-distcheck - x86_64-gnu-full-bootstrap - - x86_64-gnu-llvm-7 + - x86_64-gnu-llvm-8 - x86_64-gnu-nopt - x86_64-gnu-tools - x86_64-mingw-1 @@ -469,7 +469,7 @@ jobs: - name: x86_64-gnu-full-bootstrap os: ubuntu-latest-xl env: {} - - name: x86_64-gnu-llvm-7 + - name: x86_64-gnu-llvm-8 env: RUST_BACKTRACE: 1 os: ubuntu-latest-xl diff --git a/.mailmap b/.mailmap index 78c3c3019af..aed3a4ca5b0 100644 --- a/.mailmap +++ b/.mailmap @@ -133,7 +133,7 @@ João Oliveira <hello@jxs.pt> joaoxsouls <joaoxsouls@gmail.com> Johann Hofmann <git@johann-hofmann.com> Johann <git@johann-hofmann.com> John Clements <clements@racket-lang.org> <clements@brinckerhoff.org> John Hodge <acessdev@gmail.com> John Hodge <tpg@mutabah.net> -John Kåre Alsaker <john.kare.alsaker@gmail.com> +John Kåre Alsaker <john.kare.alsaker@gmail.com> John Talling <inrustwetrust@users.noreply.github.com> Jonathan Bailey <jbailey@mozilla.com> <jbailey@jbailey-20809.local> Jonathan S <gereeter@gmail.com> Jonathan S <gereeter+code@gmail.com> @@ -153,7 +153,7 @@ Laurențiu Nicola <lnicola@dend.ro> Lee Jeffery <leejeffery@gmail.com> Lee Jeffery <lee@leejeffery.co.uk> Lee Wondong <wdlee91@gmail.com> Lennart Kudling <github@kudling.de> -Léo Testard <leo.testard@gmail.com> +Léo Testard <leo.testard@gmail.com> Lindsey Kuper <lindsey@composition.al> <lindsey@rockstargirl.org> Lindsey Kuper <lindsey@composition.al> <lkuper@mozilla.com> Luke Metz <luke.metz@students.olin.edu> diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2843944b2e1..051f5af7bc1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -188,7 +188,70 @@ with one another are rolled up. Speaking of tests, Rust has a comprehensive test suite. More information about it can be found [here][rctd]. -### External Dependencies +### External Dependencies (subtree) + +As a developer to this repository, you don't have to treat the following external projects +differently from other crates that are directly in this repo: + +* none so far, see https://github.com/rust-lang/rust/issues/70651 for more info + +They are just regular files and directories. This is in contrast to `submodule` dependencies +(see below for those). Only tool authors will actually use any operations here. + +#### Synchronizing a subtree + +There are two synchronization directions: `subtree push` and `subtree pull`. + +``` +git subtree push -P src/tools/clippy git@github.com:your-github-name/rust-clippy sync-from-rust +``` + +takes all the changes that +happened to the copy in this repo and creates commits on the remote repo that match the local +changes. Every local commit that touched the subtree causes a commit on the remote repo, but is +modified to move the files from the specified directory to the tool repo root. + +Make sure to not pick the `master` branch on the tool repo, so you can open a normal PR to the tool +to merge that subrepo push. + +``` +git subtree pull -P src/tools/clippy https://github.com/rust-lang/rust-clippy master +``` + +takes all changes since the last `subtree pull` from the tool repo +repo and adds these commits to the rustc repo + a merge commit that moves the tool changes into +the specified directory in the rust repository. + +It is recommended that you always do a push first and get that merged to the tool master branch. +Then, when you do a pull, the merge works without conflicts. +While it's definitely possible to resolve conflicts during a pull, you may have to redo the conflict +resolution if your PR doesn't get merged fast enough and there are new conflicts. Do not try to +rebase the result of a `git subtree pull`, rebasing merge commits is a bad idea in general. + +You always need to specify the `-P` prefix to the subtree directory and the corresponding remote +repository. If you specify the wrong directory or repository +you'll get very fun merges that try to push the wrong directory to the wrong remote repository. +Luckily you can just abort this without any consequences by throwing away either the pulled commits +in rustc or the pushed branch on the remote and try again. It is usually fairly obvious +that this is happening because you suddenly get thousands of commits that want to be synchronized. + +#### Creating a new subtree dependency + +If you want to create a new subtree dependency from an existing repository, call (from this +repository's root directory!) + +``` +git subtree add -P src/tools/clippy https://github.com/rust-lang/rust-clippy.git master +``` + +This will create a new commit, which you may not rebase under any circumstances! Delete the commit +and redo the operation if you need to rebase. + +Now you're done, the `src/tools/clippy` directory behaves as if clippy were part of the rustc +monorepo, so no one but you (or others that synchronize subtrees) actually needs to use `git subtree`. + + +### External Dependencies (submodules) Currently building Rust will also build the following external projects: @@ -221,7 +284,6 @@ before the PR is merged. Rust's build system builds a number of tools that make use of the 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 break because of your changes, you may run into a sort of "chicken and egg" diff --git a/Cargo.lock b/Cargo.lock index 73eaa2fa43b..41469fbafe9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -310,7 +310,6 @@ dependencies = [ "env_logger 0.7.1", "filetime", "flate2", - "fs2", "fwdansi", "git2", "git2-curl", @@ -335,7 +334,7 @@ dependencies = [ "pretty_env_logger", "remove_dir_all", "rustc-workspace-hack", - "rustfix 0.5.0", + "rustfix", "same-file", "semver", "serde", @@ -586,7 +585,7 @@ dependencies = [ "log", "miow 0.3.3", "regex", - "rustfix 0.5.0", + "rustfix", "serde", "serde_json", "walkdir", @@ -595,9 +594,9 @@ dependencies = [ [[package]] name = "compiletest_rs" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7b678957210a00ba0fbeacc23d38cbfbf29895564da1616564634351e1dac5e" +checksum = "9f737835bfbbe29ed1ff82d5137520338d7ed5bf1a1d4b9c1c7c58bb45b8fa29" dependencies = [ "diff", "filetime", @@ -606,7 +605,7 @@ dependencies = [ "log", "miow 0.3.3", "regex", - "rustfix 0.4.6", + "rustfix", "serde", "serde_derive", "serde_json", @@ -1084,9 +1083,9 @@ checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" [[package]] name = "filetime" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ff6d4dab0aa0c8e6346d46052e93b13a16cf847b54ed357087c35011048cc7d" +checksum = "f59efc38004c988e4201d11d263b8171f49a2e7ec0bdbb71773433f271504a5e" dependencies = [ "cfg-if", "libc", @@ -1147,16 +1146,6 @@ dependencies = [ ] [[package]] -name = "fs2" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" -dependencies = [ - "libc", - "winapi 0.3.8", -] - -[[package]] name = "fs_extra" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1262,9 +1251,9 @@ dependencies = [ [[package]] name = "git2" -version = "0.13.0" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7da16ceafe24cedd9ba02c4463a2b506b6493baf4317c79c5acb553134a3c15" +checksum = "2cfb93ca10f2934069c3aaafb753fbe0663f08ee009a01b6d62e062391447b15" dependencies = [ "bitflags", "libc", @@ -1797,18 +1786,18 @@ checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" [[package]] name = "libc" -version = "0.2.66" +version = "0.2.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558" +checksum = "99e85c08494b21a9054e7fe1374a732aeadaff3980b6990b94bfd3a70f690005" dependencies = [ "rustc-std-workspace-core", ] [[package]] name = "libgit2-sys" -version = "0.12.0+0.99.0" +version = "0.12.3+1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05dff41ac39e7b653f5f1550886cf00ba52f8e7f57210b633cdeedb3de5b236c" +checksum = "7637dc15e7f05a16011723e0448655081fc01a374bcd368e2c9b9c7f5c5ab3ea" dependencies = [ "cc", "libc", @@ -2715,9 +2704,9 @@ dependencies = [ [[package]] name = "racer" -version = "2.1.32" +version = "2.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e805a6c323d08b26270f0276cef35608456916dc266ef27434edbe666eceeeb5" +checksum = "54322b696f7df20e0d79d0244a1088f387b7164a5f17987c4ab984dec1a23e42" dependencies = [ "bitflags", "clap", @@ -3157,9 +3146,9 @@ dependencies = [ [[package]] name = "rustc-ap-arena" -version = "651.0.0" +version = "654.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "632704fb93ca8148957191e5d2d827082f93c4aa20cdd242fb46d8cca57029da" +checksum = "81dfcfbb0ddfd533abf8c076e3b49d1e5042d1962526a12ce2c66d514b24cca3" dependencies = [ "rustc-ap-rustc_data_structures", "smallvec 1.0.0", @@ -3167,15 +3156,15 @@ dependencies = [ [[package]] name = "rustc-ap-graphviz" -version = "651.0.0" +version = "654.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdd4689b814859c9f1b3e314ed2bde596acac428a256a16894635f600bed46b4" +checksum = "7490bb07b014a7f9531bde33c905a805e08095dbefdb4c9988a1b19fe6d019fd" [[package]] name = "rustc-ap-rustc_ast" -version = "651.0.0" +version = "654.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "101c1517d3fd19d083aaca5b113f9965e6ae353a0bb09c49959b0f62b95b75d9" +checksum = "189f16dbb8dd11089274c9ced58b0cae9e1ea3e434a58f3db683817eda849e58" dependencies = [ "log", "rustc-ap-rustc_data_structures", @@ -3190,10 +3179,11 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_ast_passes" -version = "651.0.0" +version = "654.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ab3f5a7e939b37c99d8ca371f09b10bb5b5c85ad5d5b8d1d736ce8248c71be0" +checksum = "bbe619609b56a617fa986332b066d53270093c816d8ff8281fc90e1dbe74c1cc" dependencies = [ + "itertools 0.8.0", "log", "rustc-ap-rustc_ast", "rustc-ap-rustc_ast_pretty", @@ -3208,9 +3198,9 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_ast_pretty" -version = "651.0.0" +version = "654.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05046d3a2b8de22b20bcda9a1c063dc5c1f2f721f042b6c2809df2d23c64a13e" +checksum = "26ab1495f7b420e937688749c1da5763aaabd6ebe8cacb758665a0b8481da094" dependencies = [ "log", "rustc-ap-rustc_ast", @@ -3220,9 +3210,9 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_attr" -version = "651.0.0" +version = "654.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f00b7ccad6fc3628fb44950435772945a425575f9ea0b3708c536fe75623a6e8" +checksum = "2e057495724c60729c1d1d9d49374e0b3ebd6d3481cd161b2871f52fe017b7b5" dependencies = [ "rustc-ap-rustc_ast", "rustc-ap-rustc_ast_pretty", @@ -3238,9 +3228,9 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_data_structures" -version = "651.0.0" +version = "654.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6121ab6766644fa76b711f65d4c39f2e335488ab768324567fed0ed191166e" +checksum = "d2130997667833692f4bec4681d0e73b066d5a01dac1d8a68f22068b82bf173a" dependencies = [ "bitflags", "cfg-if", @@ -3249,6 +3239,7 @@ dependencies = [ "indexmap", "jobserver", "lazy_static 1.4.0", + "libc", "log", "measureme", "parking_lot 0.10.0", @@ -3265,9 +3256,9 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_errors" -version = "651.0.0" +version = "654.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adab84c842003ad1c8435fd71b8d0cc19bf0d702a8a2147d5be06e083db2d207" +checksum = "908e1ea187c6bb368af4ba6db980001e920515e67371ddc4086e749baabe6080" dependencies = [ "annotate-snippets", "atty", @@ -3283,9 +3274,9 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_expand" -version = "651.0.0" +version = "654.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb001df541ea02b65c8e294252530010c6f90e3c6a5716e8e24e58c12dd1cd86" +checksum = "50066a75bca872ff933b0ee8a582d18ef1876c8054a392f60c39e538446bfb00" dependencies = [ "log", "rustc-ap-rustc_ast", @@ -3305,9 +3296,9 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_feature" -version = "651.0.0" +version = "654.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "446cc60613cc3b05d0bdbcab7feb02305790b5617fa43c532d51ae3223d677a4" +checksum = "96fb53e1710e6de7c2e371ca56c857b79f9b399aba58aa6b6fbed6e2f677d3f6" dependencies = [ "lazy_static 1.4.0", "rustc-ap-rustc_data_structures", @@ -3316,15 +3307,15 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_fs_util" -version = "651.0.0" +version = "654.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ac99d6f67e7db3bb300895630e769ed41bd3e336c0e725870c70e676c1a5ff1" +checksum = "e3f91357e5e468fc2729211571d769723c728a34e200d90a70164e945f881e09" [[package]] name = "rustc-ap-rustc_index" -version = "651.0.0" +version = "654.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5608c1cf50d2251b7e10a138cf6dd388e97f139b21c00b06a22d06f89c6591f6" +checksum = "32220c3e6cdf226f38e4474b747dca15f3106bb680c74f10b299af3f6cdb1663" dependencies = [ "rustc-ap-serialize", "smallvec 1.0.0", @@ -3332,18 +3323,18 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_lexer" -version = "651.0.0" +version = "654.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74e9c1c6f5dc85977b3adb6fb556b2ff23354d1a12021da15eb1d36353458bde" +checksum = "3b324d2a2bacad344e53e182e5ca04ffb74745b932849aa074f8f7fec8177da5" dependencies = [ "unicode-xid 0.2.0", ] [[package]] name = "rustc-ap-rustc_macros" -version = "651.0.0" +version = "654.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3226b5ec864312a5d23eb40a5d621ee06bdc0754228d20d6eb76d4ddc4f2d4a1" +checksum = "59686c56d5f1b3ed47d0f070c257ed35caf24ecf2d744dd11fe44b1014baee0f" dependencies = [ "proc-macro2 1.0.3", "quote 1.0.2", @@ -3353,9 +3344,9 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_parse" -version = "651.0.0" +version = "654.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3b042344c2280b50d5df0058d11379028a8f016a407e575bb3ea8b6c798049" +checksum = "2dfb0c11c591ec5f87bbadb10819795abc9035ff79a26703c1b6c9487ac51f49" dependencies = [ "bitflags", "log", @@ -3373,10 +3364,11 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_session" -version = "651.0.0" +version = "654.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff35ef4b5d9fbcb2fd539c7c908eb3cdd1f68ddbccd042945ef50ae65564f941" +checksum = "3d1a194b1a81d7233ee492847638dc9ebdb7d084300e5ade8dea0ceaa98f95b9" dependencies = [ + "getopts", "log", "num_cpus", "rustc-ap-rustc_ast", @@ -3392,26 +3384,28 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_span" -version = "651.0.0" +version = "654.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e323b1f4a824039886eed8e33cad20ea4f492a9f9b3c9441009797c91de3e87a" +checksum = "a648146050fed6b58e681ec22488e728f60e16036bb7497c9815e3debd1e4242" dependencies = [ "cfg-if", "log", + "md-5", "rustc-ap-arena", "rustc-ap-rustc_data_structures", "rustc-ap-rustc_index", "rustc-ap-rustc_macros", "rustc-ap-serialize", "scoped-tls", + "sha-1", "unicode-width", ] [[package]] name = "rustc-ap-rustc_target" -version = "651.0.0" +version = "654.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e161eb7b3a5b7993c6b480135296dc61476db80041d49dd446422742426e390b" +checksum = "28cf28798f0988b808e3616713630e4098d68c6f1f41052a2f7e922e094da744" dependencies = [ "bitflags", "log", @@ -3424,9 +3418,9 @@ dependencies = [ [[package]] name = "rustc-ap-serialize" -version = "651.0.0" +version = "654.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af510a659098d8c45a7303fb882fa780f4a87ec5f5d7a2053521e7d5d7f332c4" +checksum = "756e8f526ec7906e132188bf25e3c10a6ee42ab77294ecb3b3602647f0508eef" dependencies = [ "indexmap", "smallvec 1.0.0", @@ -4381,18 +4375,6 @@ dependencies = [ [[package]] name = "rustfix" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7150ac777a2931a53489f5a41eb0937b84e3092a20cd0e73ad436b65b507f607" -dependencies = [ - "failure", - "log", - "serde", - "serde_json", -] - -[[package]] -name = "rustfix" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "804b11883a5ce0ad0378fbf95a8dea59ee6b51c331a73b8f471b6bdaa3bd40c1" @@ -4415,7 +4397,7 @@ dependencies = [ [[package]] name = "rustfmt-nightly" -version = "1.4.13" +version = "1.4.14" dependencies = [ "annotate-snippets", "bytecount", @@ -4672,9 +4654,9 @@ checksum = "4ecf3b85f68e8abaa7555aa5abdb1153079387e60b718283d732f03897fcfc86" [[package]] name = "socket2" -version = "0.3.11" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85" +checksum = "03088793f677dce356f3ccc2edb1b314ad191ab702a5de3faf49304f7e104918" dependencies = [ "cfg-if", "libc", diff --git a/RELEASES.md b/RELEASES.md index 9ff0d14b353..36597b1864f 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,152 @@ +Version 1.43.0 (2020-04-23) +========================== + +Language +-------- +- [Fixed using binary operations with `&{number}` (e.g. `&1.0`) not having + the type inferred correctly.][68129] +- [Attributes such as `#[cfg()]` can now be used on `if` expressions.][69201] + +**Syntax only changes** +- [Allow `type Foo: Ord` syntactically.][69361] +- [Fuse associated and extern items up to defaultness.][69194] +- [Syntactically allow `self` in all `fn` contexts.][68764] +- [Merge `fn` syntax + cleanup item parsing.][68728] +- [`item` macro fragments can be interpolated into `trait`s, `impl`s, and `extern` blocks.][69366] + For example, you may now write: + ```rust + macro_rules! mac_trait { + ($i:item) => { + trait T { $i } + } + } + mac_trait! { + fn foo() {} + } + ``` + +These are still rejected *semantically*, so you will likely receive an error but +these changes can be seen and parsed by macros and +conditional compilation. + + +Compiler +-------- +- [You can now pass multiple lint flags to rustc to override the previous + flags.][67885] For example; `rustc -D unused -A unused-variables` denies + everything in the `unused` lint group except `unused-variables` which + is explicitly allowed. However, passing `rustc -A unused-variables -D unused` denies + everything in the `unused` lint group **including** `unused-variables` since + the allow flag is specified before the deny flag (and therefore overridden). +- [rustc will now prefer your system MinGW libraries over its bundled libraries + if they are available on `windows-gnu`.][67429] +- [rustc now buffers errors/warnings printed in JSON.][69227] + +Libraries +--------- +- [`Arc<[T; N]>`, `Box<[T; N]>`, and `Rc<[T; N]>`, now implement + `TryFrom<Arc<[T]>>`,`TryFrom<Box<[T]>>`, and `TryFrom<Rc<[T]>>` + respectively.][69538] **Note** These conversions are only available when `N` + is `0..=32`. +- [You can now use associated constants on floats and integers directly, rather + than having to import the module.][68952] e.g. You can now write `u32::MAX` or + `f32::NAN` with no imports. +- [`u8::is_ascii` is now `const`.][68984] +- [`String` now implements `AsMut<str>`.][68742] +- [Added the `primitive` module to `std` and `core`.][67637] This module + reexports Rust's primitive types. This is mainly useful in macros + where you want avoid these types being shadowed. +- [Relaxed some of the trait bounds on `HashMap` and `HashSet`.][67642] +- [`string::FromUtf8Error` now implements `Clone + Eq`.][68738] + +Stabilized APIs +--------------- +- [`Once::is_completed`] +- [`f32::LOG10_2`] +- [`f32::LOG2_10`] +- [`f64::LOG10_2`] +- [`f64::LOG2_10`] +- [`iter::once_with`] + +Cargo +----- +- [You can now set config `[profile]`s in your `.cargo/config`, or through + your environment.][cargo/7823] +- [Cargo will now set `CARGO_BIN_EXE_<name>` pointing to a binary's + executable path when running integration tests or benchmarks.][cargo/7697] + `<name>` is the name of your binary as-is e.g. If you wanted the executable + path for a binary named `my-program`you would use `env!("CARGO_BIN_EXE_my-program")`. + +Misc +---- +- [Certain checks in the `const_err` lint were deemed unrelated to const + evaluation][69185], and have been moved to the `unconditional_panic` and + `arithmetic_overflow` lints. + +Compatibility Notes +------------------- + +- [Having trailing syntax in the `assert!` macro is now a hard error.][69548] This + has been a warning since 1.36.0. +- [Fixed `Self` not having the correctly inferred type.][69340] This incorrectly + led to some instances being accepted, and now correctly emits a hard error. + +[69340]: https://github.com/rust-lang/rust/pull/69340 + +Internal Only +------------- +These changes provide no direct user facing benefits, but represent significant +improvements to the internals and overall performance of `rustc` and +related tools. + +- [All components are now built with `opt-level=3` instead of `2`.][67878] +- [Improved how rustc generates drop code.][67332] +- [Improved performance from `#[inline]`-ing certain hot functions.][69256] +- [traits: preallocate 2 Vecs of known initial size][69022] +- [Avoid exponential behaviour when relating types][68772] +- [Skip `Drop` terminators for enum variants without drop glue][68943] +- [Improve performance of coherence checks][68966] +- [Deduplicate types in the generator witness][68672] +- [Invert control in struct_lint_level.][68725] + +[67332]: https://github.com/rust-lang/rust/pull/67332/ +[67429]: https://github.com/rust-lang/rust/pull/67429/ +[67637]: https://github.com/rust-lang/rust/pull/67637/ +[67642]: https://github.com/rust-lang/rust/pull/67642/ +[67878]: https://github.com/rust-lang/rust/pull/67878/ +[67885]: https://github.com/rust-lang/rust/pull/67885/ +[68129]: https://github.com/rust-lang/rust/pull/68129/ +[68672]: https://github.com/rust-lang/rust/pull/68672/ +[68725]: https://github.com/rust-lang/rust/pull/68725/ +[68728]: https://github.com/rust-lang/rust/pull/68728/ +[68738]: https://github.com/rust-lang/rust/pull/68738/ +[68742]: https://github.com/rust-lang/rust/pull/68742/ +[68764]: https://github.com/rust-lang/rust/pull/68764/ +[68772]: https://github.com/rust-lang/rust/pull/68772/ +[68943]: https://github.com/rust-lang/rust/pull/68943/ +[68952]: https://github.com/rust-lang/rust/pull/68952/ +[68966]: https://github.com/rust-lang/rust/pull/68966/ +[68984]: https://github.com/rust-lang/rust/pull/68984/ +[69022]: https://github.com/rust-lang/rust/pull/69022/ +[69185]: https://github.com/rust-lang/rust/pull/69185/ +[69194]: https://github.com/rust-lang/rust/pull/69194/ +[69201]: https://github.com/rust-lang/rust/pull/69201/ +[69227]: https://github.com/rust-lang/rust/pull/69227/ +[69548]: https://github.com/rust-lang/rust/pull/69548/ +[69256]: https://github.com/rust-lang/rust/pull/69256/ +[69361]: https://github.com/rust-lang/rust/pull/69361/ +[69366]: https://github.com/rust-lang/rust/pull/69366/ +[69538]: https://github.com/rust-lang/rust/pull/69538/ +[cargo/7823]: https://github.com/rust-lang/cargo/pull/7823 +[cargo/7697]: https://github.com/rust-lang/cargo/pull/7697 +[`Once::is_completed`]: https://doc.rust-lang.org/std/sync/struct.Once.html#method.is_completed +[`f32::LOG10_2`]: https://doc.rust-lang.org/std/f32/consts/constant.LOG10_2.html +[`f32::LOG2_10`]: https://doc.rust-lang.org/std/f32/consts/constant.LOG2_10.html +[`f64::LOG10_2`]: https://doc.rust-lang.org/std/f64/consts/constant.LOG10_2.html +[`f64::LOG2_10`]: https://doc.rust-lang.org/std/f64/consts/constant.LOG2_10.html +[`iter::once_with`]: https://doc.rust-lang.org/std/iter/fn.once_with.html + + Version 1.42.0 (2020-03-12) ========================== diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index daa030c59d6..a8c00c8c3ca 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -134,11 +134,6 @@ fn main() { cmd.arg(format!("-Clinker={}", host_linker)); } - // Override linker flavor if necessary. - if let Ok(host_linker_flavor) = env::var("RUSTC_HOST_LINKER_FLAVOR") { - cmd.arg(format!("-Clinker-flavor={}", host_linker_flavor)); - } - if let Ok(s) = env::var("RUSTC_HOST_CRT_STATIC") { if s == "true" { cmd.arg("-C").arg("target-feature=+crt-static"); diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 7fc089d18f1..8d6c2db7926 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -969,27 +969,11 @@ impl<'a> Builder<'a> { // See https://github.com/rust-lang/rust/issues/68647. let can_use_lld = mode != Mode::Std; - // FIXME: The beta compiler doesn't pick the `lld-link` flavor for `*-pc-windows-msvc` - // Remove `RUSTC_HOST_LINKER_FLAVOR` when this is fixed - let lld_linker_flavor = |linker: &Path, target: Interned<String>| { - compiler.stage == 0 - && linker.file_name() == Some(OsStr::new("rust-lld")) - && target.contains("pc-windows-msvc") - }; - if let Some(host_linker) = self.linker(compiler.host, can_use_lld) { - if lld_linker_flavor(host_linker, compiler.host) { - cargo.env("RUSTC_HOST_LINKER_FLAVOR", "lld-link"); - } - cargo.env("RUSTC_HOST_LINKER", host_linker); } if let Some(target_linker) = self.linker(target, can_use_lld) { - if lld_linker_flavor(target_linker, target) { - rustflags.arg("-Clinker-flavor=lld-link"); - } - let target = crate::envify(&target); cargo.env(&format!("CARGO_TARGET_{}_LINKER", target), target_linker); } diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 1e380a20629..0c87695ff7c 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -289,11 +289,11 @@ fn check_llvm_version(builder: &Builder<'_>, llvm_config: &Path) { let version = output(cmd.arg("--version")); let mut parts = version.split('.').take(2).filter_map(|s| s.parse::<u32>().ok()); if let (Some(major), Some(_minor)) = (parts.next(), parts.next()) { - if major >= 7 { + if major >= 8 { return; } } - panic!("\n\nbad LLVM version: {}, need >=7.0\n\n", version) + panic!("\n\nbad LLVM version: {}, need >=8.0\n\n", version) } fn configure_cmake( diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 0bf507f9ebb..85c5d28bb89 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -627,8 +627,14 @@ impl Step for RustdocJSStd { if let Some(ref nodejs) = builder.config.nodejs { let mut command = Command::new(nodejs); command - .arg(builder.src.join("src/tools/rustdoc-js-std/tester.js")) + .arg(builder.src.join("src/tools/rustdoc-js/tester.js")) + .arg("--crate-name") + .arg("std") + .arg("--resource-suffix") + .arg(crate::channel::CFG_RELEASE_NUM) + .arg("--doc-folder") .arg(builder.doc_out(self.target)) + .arg("--test-folder") .arg(builder.src.join("src/test/rustdoc-js-std")); builder.ensure(crate::doc::Std { target: self.target, stage: builder.top_stage }); builder.run(&mut command); diff --git a/src/ci/azure-pipelines/auto.yml b/src/ci/azure-pipelines/auto.yml index 56fe3864204..46d3cf7a38c 100644 --- a/src/ci/azure-pipelines/auto.yml +++ b/src/ci/azure-pipelines/auto.yml @@ -29,7 +29,7 @@ jobs: - template: steps/run.yml strategy: matrix: - x86_64-gnu-llvm-7: + x86_64-gnu-llvm-8: RUST_BACKTRACE: 1 dist-x86_64-linux: {} dist-x86_64-linux-alt: diff --git a/src/ci/azure-pipelines/pr.yml b/src/ci/azure-pipelines/pr.yml index 37c1779b799..1fc8d187242 100644 --- a/src/ci/azure-pipelines/pr.yml +++ b/src/ci/azure-pipelines/pr.yml @@ -29,7 +29,7 @@ jobs: - template: steps/run.yml strategy: matrix: - x86_64-gnu-llvm-7: {} + x86_64-gnu-llvm-8: {} mingw-check: {} x86_64-gnu-tools: CI_ONLY_WHEN_SUBMODULES_CHANGED: 1 diff --git a/src/ci/docker/x86_64-gnu-llvm-7/Dockerfile b/src/ci/docker/x86_64-gnu-llvm-7/Dockerfile deleted file mode 100644 index 4b5d5cac516..00000000000 --- a/src/ci/docker/x86_64-gnu-llvm-7/Dockerfile +++ /dev/null @@ -1,38 +0,0 @@ -FROM ubuntu:18.04 - -RUN apt-get update && apt-get install -y --no-install-recommends \ - g++ \ - make \ - file \ - curl \ - ca-certificates \ - python2.7 \ - git \ - cmake \ - sudo \ - gdb \ - llvm-7-tools \ - libedit-dev \ - libssl-dev \ - pkg-config \ - zlib1g-dev \ - xz-utils \ - nodejs - -COPY scripts/sccache.sh /scripts/ -RUN sh /scripts/sccache.sh - -# using llvm-link-shared due to libffi issues -- see #34486 -ENV RUST_CONFIGURE_ARGS \ - --build=x86_64-unknown-linux-gnu \ - --llvm-root=/usr/lib/llvm-7 \ - --enable-llvm-link-shared \ - --set rust.thin-lto-import-instr-limit=10 - -ENV SCRIPT python2.7 ../x.py test --exclude src/tools/tidy && python2.7 ../x.py test src/tools/tidy - -# The purpose of this container isn't to test with debug assertions and -# this is run on all PRs, so let's get speedier builds by disabling these extra -# checks. -ENV NO_DEBUG_ASSERTIONS=1 -ENV NO_LLVM_ASSERTIONS=1 diff --git a/src/ci/docker/x86_64-gnu-llvm-8/Dockerfile b/src/ci/docker/x86_64-gnu-llvm-8/Dockerfile new file mode 100644 index 00000000000..58fdc6f2623 --- /dev/null +++ b/src/ci/docker/x86_64-gnu-llvm-8/Dockerfile @@ -0,0 +1,55 @@ +FROM ubuntu:18.04 + +RUN apt-get update && apt-get install -y --no-install-recommends \ + g++ \ + g++-arm-linux-gnueabi \ + make \ + file \ + curl \ + ca-certificates \ + python2.7 \ + git \ + cmake \ + sudo \ + gdb \ + llvm-8-tools \ + libedit-dev \ + libssl-dev \ + pkg-config \ + zlib1g-dev \ + xz-utils \ + nodejs + +COPY scripts/sccache.sh /scripts/ +RUN sh /scripts/sccache.sh + +# using llvm-link-shared due to libffi issues -- see #34486 +ENV RUST_CONFIGURE_ARGS \ + --build=x86_64-unknown-linux-gnu \ + --llvm-root=/usr/lib/llvm-8 \ + --enable-llvm-link-shared \ + --set rust.thin-lto-import-instr-limit=10 + +ENV SCRIPT python2.7 ../x.py test --exclude src/tools/tidy && \ + # Run the `mir-opt` tests again but this time for a 32-bit target. + # This enforces that tests using `// EMIT_MIR_FOR_EACH_BIT_WIDTH` have + # both 32-bit and 64-bit outputs updated by the PR author, before + # the PR is approved and tested for merging. + # It will also detect tests lacking `// EMIT_MIR_FOR_EACH_BIT_WIDTH`, + # despite having different output on 32-bit vs 64-bit targets. + # + # HACK(eddyb) `armv5te` is used (not `i686`) to support older LLVM than LLVM 9: + # https://github.com/rust-lang/compiler-builtins/pull/311#issuecomment-612270089. + # This also requires `--pass=build` because we can't execute the tests + # on the `x86_64` host when they're built as `armv5te` binaries. + # (we're only interested in the MIR output, so this doesn't matter) + python2.7 ../x.py test src/test/mir-opt --pass=build \ + --target=armv5te-unknown-linux-gnueabi && \ + # Run tidy at the very end, after all the other tests. + python2.7 ../x.py test src/tools/tidy + +# The purpose of this container isn't to test with debug assertions and +# this is run on all PRs, so let's get speedier builds by disabling these extra +# checks. +ENV NO_DEBUG_ASSERTIONS=1 +ENV NO_LLVM_ASSERTIONS=1 diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index 813c35cb9d5..df1467ea73a 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -259,13 +259,13 @@ jobs: matrix: name: - mingw-check - - x86_64-gnu-llvm-7 + - x86_64-gnu-llvm-8 - x86_64-gnu-tools include: - name: mingw-check <<: *job-linux-xl - - name: x86_64-gnu-llvm-7 + - name: x86_64-gnu-llvm-8 <<: *job-linux-xl - name: x86_64-gnu-tools @@ -349,7 +349,7 @@ jobs: - x86_64-gnu-debug - x86_64-gnu-distcheck - x86_64-gnu-full-bootstrap - - x86_64-gnu-llvm-7 + - x86_64-gnu-llvm-8 - x86_64-gnu-nopt - x86_64-gnu-tools - x86_64-mingw-1 @@ -471,7 +471,7 @@ jobs: - name: x86_64-gnu-full-bootstrap <<: *job-linux-xl - - name: x86_64-gnu-llvm-7 + - name: x86_64-gnu-llvm-8 env: RUST_BACKTRACE: 1 <<: *job-linux-xl diff --git a/src/doc/book b/src/doc/book -Subproject c8841f2841a2d26124319ddadd1b6a245f9a185 +Subproject f5db319e0b19c22964398d56bc63103d669e1bb diff --git a/src/doc/edition-guide b/src/doc/edition-guide -Subproject 37f9e6848411188a1062ead1bd8ebe4b8aa1689 +Subproject 8204c1d123472cd17f0c1c5c77300ae802eb027 diff --git a/src/doc/embedded-book b/src/doc/embedded-book -Subproject d22a9c487c78095afc4584f1d9b4ec43529d713 +Subproject 668fb07b6160b9c468f598e839c1e044db65de3 diff --git a/src/doc/reference b/src/doc/reference -Subproject 89dd146154474559536d5d4049a03831c501dee +Subproject 3ce94caed4cf967106c51ae86be5e098f7875f1 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example -Subproject a6638463efc7631bc0e8dc67ccd256d4e1b61f1 +Subproject c106d1683c3a2b0960f0f0fb01728cbb1980733 diff --git a/src/liballoc/collections/binary_heap.rs b/src/liballoc/collections/binary_heap.rs index a01e9b25dd6..03c9164fb90 100644 --- a/src/liballoc/collections/binary_heap.rs +++ b/src/liballoc/collections/binary_heap.rs @@ -1,10 +1,10 @@ //! A priority queue implemented with a binary heap. //! -//! Insertion and popping the largest element have `O(log n)` time complexity. +//! Insertion and popping the largest element have `O(log(n))` time complexity. //! Checking the largest element is `O(1)`. Converting a vector to a binary heap //! can be done in-place, and has `O(n)` complexity. A binary heap can also be -//! converted to a sorted vector in-place, allowing it to be used for an `O(n -//! log n)` in-place heapsort. +//! converted to a sorted vector in-place, allowing it to be used for an `O(n * log(n))` +//! in-place heapsort. //! //! # Examples //! @@ -233,9 +233,9 @@ use super::SpecExtend; /// /// # Time complexity /// -/// | [push] | [pop] | [peek]/[peek\_mut] | -/// |--------|----------|--------------------| -/// | O(1)~ | O(log n) | O(1) | +/// | [push] | [pop] | [peek]/[peek\_mut] | +/// |--------|-----------|--------------------| +/// | O(1)~ | O(log(n)) | O(1) | /// /// The value for `push` is an expected cost; the method documentation gives a /// more detailed analysis. @@ -398,7 +398,7 @@ impl<T: Ord> BinaryHeap<T> { /// /// # Time complexity /// - /// Cost is O(1) in the worst case. + /// Cost is `O(1)` in the worst case. #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")] pub fn peek_mut(&mut self) -> Option<PeekMut<'_, T>> { if self.is_empty() { None } else { Some(PeekMut { heap: self, sift: true }) } @@ -422,8 +422,7 @@ impl<T: Ord> BinaryHeap<T> { /// /// # Time complexity /// - /// The worst case cost of `pop` on a heap containing *n* elements is O(log - /// n). + /// The worst case cost of `pop` on a heap containing *n* elements is `O(log(n))`. #[stable(feature = "rust1", since = "1.0.0")] pub fn pop(&mut self) -> Option<T> { self.data.pop().map(|mut item| { @@ -456,15 +455,15 @@ impl<T: Ord> BinaryHeap<T> { /// /// The expected cost of `push`, averaged over every possible ordering of /// the elements being pushed, and over a sufficiently large number of - /// pushes, is O(1). This is the most meaningful cost metric when pushing + /// pushes, is `O(1)`. This is the most meaningful cost metric when pushing /// elements that are *not* already in any sorted pattern. /// /// The time complexity degrades if elements are pushed in predominantly /// ascending order. In the worst case, elements are pushed in ascending - /// sorted order and the amortized cost per push is O(log n) against a heap + /// sorted order and the amortized cost per push is `O(log(n))` against a heap /// containing *n* elements. /// - /// The worst case cost of a *single* call to `push` is O(n). The worst case + /// The worst case cost of a *single* call to `push` is `O(n)`. The worst case /// occurs when capacity is exhausted and needs a resize. The resize cost /// has been amortized in the previous figures. #[stable(feature = "rust1", since = "1.0.0")] @@ -623,7 +622,7 @@ impl<T: Ord> BinaryHeap<T> { // `rebuild` takes O(len1 + len2) operations // and about 2 * (len1 + len2) comparisons in the worst case - // while `extend` takes O(len2 * log_2(len1)) operations + // while `extend` takes O(len2 * log(len1)) operations // and about 1 * len2 * log_2(len1) comparisons in the worst case, // assuming len1 >= len2. #[inline] @@ -644,7 +643,7 @@ impl<T: Ord> BinaryHeap<T> { /// The remaining elements will be removed on drop in heap order. /// /// Note: - /// * `.drain_sorted()` is O(n lg n); much slower than `.drain()`. + /// * `.drain_sorted()` is `O(n * log(n))`; much slower than `.drain()`. /// You should use the latter for most cases. /// /// # Examples @@ -729,7 +728,7 @@ impl<T> BinaryHeap<T> { /// /// # Time complexity /// - /// Cost is O(1) in the worst case. + /// Cost is `O(1)` in the worst case. #[stable(feature = "rust1", since = "1.0.0")] pub fn peek(&self) -> Option<&T> { self.data.get(0) diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index 3fc1b5e16b3..91d93a1be1c 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -40,7 +40,7 @@ use UnderflowResult::*; /// performance on *small* nodes of elements which are cheap to compare. However in the future we /// would like to further explore choosing the optimal search strategy based on the choice of B, /// and possibly other factors. Using linear search, searching for a random element is expected -/// to take O(B log<sub>B</sub>n) comparisons, which is generally worse than a BST. In practice, +/// to take O(B * log(n)) comparisons, which is generally worse than a BST. In practice, /// however, performance is excellent. /// /// It is a logic error for a key to be modified in such a way that the key's ordering relative to @@ -2058,12 +2058,7 @@ where (Excluded(s), Excluded(e)) if s == e => { panic!("range start and end are equal and excluded in BTreeMap") } - (Included(s), Included(e)) - | (Included(s), Excluded(e)) - | (Excluded(s), Included(e)) - | (Excluded(s), Excluded(e)) - if s > e => - { + (Included(s) | Excluded(s), Included(e) | Excluded(e)) if s > e => { panic!("range start is greater than range end in BTreeMap") } _ => {} diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index 53d4f7239b7..af341e6c1ca 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -390,7 +390,7 @@ impl<T> LinkedList<T> { /// This reuses all the nodes from `other` and moves them into `self`. After /// this operation, `other` becomes empty. /// - /// This operation should compute in O(1) time and O(1) memory. + /// This operation should compute in `O(1)` time and `O(1)` memory. /// /// # Examples /// @@ -547,7 +547,7 @@ impl<T> LinkedList<T> { /// Returns `true` if the `LinkedList` is empty. /// - /// This operation should compute in O(1) time. + /// This operation should compute in `O(1)` time. /// /// # Examples /// @@ -568,7 +568,7 @@ impl<T> LinkedList<T> { /// Returns the length of the `LinkedList`. /// - /// This operation should compute in O(1) time. + /// This operation should compute in `O(1)` time. /// /// # Examples /// @@ -594,7 +594,7 @@ impl<T> LinkedList<T> { /// Removes all elements from the `LinkedList`. /// - /// This operation should compute in O(n) time. + /// This operation should compute in `O(n)` time. /// /// # Examples /// @@ -737,7 +737,7 @@ impl<T> LinkedList<T> { /// Adds an element first in the list. /// - /// This operation should compute in O(1) time. + /// This operation should compute in `O(1)` time. /// /// # Examples /// @@ -760,7 +760,7 @@ impl<T> LinkedList<T> { /// Removes the first element and returns it, or `None` if the list is /// empty. /// - /// This operation should compute in O(1) time. + /// This operation should compute in `O(1)` time. /// /// # Examples /// @@ -783,7 +783,7 @@ impl<T> LinkedList<T> { /// Appends an element to the back of a list. /// - /// This operation should compute in O(1) time. + /// This operation should compute in `O(1)` time. /// /// # Examples /// @@ -803,7 +803,7 @@ impl<T> LinkedList<T> { /// Removes the last element from a list and returns it, or `None` if /// it is empty. /// - /// This operation should compute in O(1) time. + /// This operation should compute in `O(1)` time. /// /// # Examples /// @@ -824,7 +824,7 @@ impl<T> LinkedList<T> { /// Splits the list into two at the given index. Returns everything after the given index, /// including the index. /// - /// This operation should compute in O(n) time. + /// This operation should compute in `O(n)` time. /// /// # Panics /// @@ -880,7 +880,7 @@ impl<T> LinkedList<T> { /// Removes the element at the given index and returns it. /// - /// This operation should compute in O(n) time. + /// This operation should compute in `O(n)` time. /// /// # Panics /// Panics if at >= len @@ -1198,6 +1198,14 @@ pub struct Cursor<'a, T: 'a> { } #[unstable(feature = "linked_list_cursors", issue = "58533")] +impl<T> Clone for Cursor<'_, T> { + fn clone(&self) -> Self { + let Cursor { index, current, list } = *self; + Cursor { index, current, list } + } +} + +#[unstable(feature = "linked_list_cursors", issue = "58533")] impl<T: fmt::Debug> fmt::Debug for Cursor<'_, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("Cursor").field(&self.list).field(&self.index()).finish() diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index 0ed9773630e..091b068b0b2 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -488,7 +488,7 @@ impl<T> VecDeque<T> { VecDeque { tail: 0, head: 0, buf: RawVec::with_capacity(cap) } } - /// Retrieves an element in the `VecDeque` by index. + /// Provides a reference to the element at the given index. /// /// Element at index 0 is the front of the queue. /// @@ -513,7 +513,7 @@ impl<T> VecDeque<T> { } } - /// Retrieves an element in the `VecDeque` mutably by index. + /// Provides a mutable reference to the element at the given index. /// /// Element at index 0 is the front of the queue. /// @@ -651,7 +651,7 @@ impl<T> VecDeque<T> { } } - /// Tries to reserves the minimum capacity for exactly `additional` more elements to + /// Tries to reserve the minimum capacity for exactly `additional` more elements to /// be inserted in the given `VecDeque<T>`. After calling `reserve_exact`, /// capacity will be greater than or equal to `self.len() + additional`. /// Does nothing if the capacity is already sufficient. @@ -662,7 +662,7 @@ impl<T> VecDeque<T> { /// /// # Errors /// - /// If the capacity overflows, or the allocator reports a failure, then an error + /// If the capacity overflows `usize`, or the allocator reports a failure, then an error /// is returned. /// /// # Examples @@ -678,7 +678,7 @@ impl<T> VecDeque<T> { /// // Pre-reserve the memory, exiting if we can't /// output.try_reserve_exact(data.len())?; /// - /// // Now we know this can't OOM in the middle of our complex work + /// // Now we know this can't OOM(Out-Of-Memory) in the middle of our complex work /// output.extend(data.iter().map(|&val| { /// val * 2 + 5 // very complicated /// })); @@ -700,7 +700,7 @@ impl<T> VecDeque<T> { /// /// # Errors /// - /// If the capacity overflows, or the allocator reports a failure, then an error + /// If the capacity overflows `usize`, or the allocator reports a failure, then an error /// is returned. /// /// # Examples @@ -1391,7 +1391,7 @@ impl<T> VecDeque<T> { /// Removes an element from anywhere in the `VecDeque` and returns it, /// replacing it with the first element. /// - /// This does not preserve ordering, but is O(1). + /// This does not preserve ordering, but is `O(1)`. /// /// Returns `None` if `index` is out of bounds. /// @@ -1426,7 +1426,7 @@ impl<T> VecDeque<T> { /// Removes an element from anywhere in the `VecDeque` and returns it, replacing it with the /// last element. /// - /// This does not preserve ordering, but is O(1). + /// This does not preserve ordering, but is `O(1)`. /// /// Returns `None` if `index` is out of bounds. /// @@ -2927,7 +2927,7 @@ impl<T> From<VecDeque<T>> for Vec<T> { /// [`Vec<T>`]: crate::vec::Vec /// [`VecDeque<T>`]: crate::collections::VecDeque /// - /// This never needs to re-allocate, but does need to do O(n) data movement if + /// This never needs to re-allocate, but does need to do `O(n)` data movement if /// the circular buffer doesn't happen to be at the beginning of the allocation. /// /// # Examples diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 121c1cde548..a2071844d5d 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -103,6 +103,7 @@ #![feature(new_uninit)] #![feature(nll)] #![feature(optin_builtin_traits)] +#![feature(or_patterns)] #![feature(pattern)] #![feature(ptr_internals)] #![feature(ptr_offset_from)] diff --git a/src/liballoc/macros.rs b/src/liballoc/macros.rs index 4bc0c3a079d..e163a166b49 100644 --- a/src/liballoc/macros.rs +++ b/src/liballoc/macros.rs @@ -42,10 +42,9 @@ macro_rules! vec { ($elem:expr; $n:expr) => ( $crate::vec::from_elem($elem, $n) ); - ($($x:expr),*) => ( - <[_]>::into_vec(box [$($x),*]) + ($($x:expr),+ $(,)?) => ( + <[_]>::into_vec(box [$($x),+]) ); - ($($x:expr,)*) => ($crate::vec![$($x),*]) } // HACK(japaric): with cfg(test) the inherent `[T]::into_vec` method, which is diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 4ae7532d992..53477288b59 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -140,7 +140,9 @@ mod hack { use crate::string::ToString; use crate::vec::Vec; - #[inline] + // We shouldn't add inline attribute to this since this is used in + // `vec!` macro mostly and causes perf regression. See #71204 for + // discussion and perf results. pub fn into_vec<T>(b: Box<[T]>) -> Vec<T> { unsafe { let len = b.len(); @@ -165,7 +167,7 @@ mod hack { impl<T> [T] { /// Sorts the slice. /// - /// This sort is stable (i.e., does not reorder equal elements) and `O(n log n)` worst-case. + /// This sort is stable (i.e., does not reorder equal elements) and `O(n * log(n))` worst-case. /// /// When applicable, unstable sorting is preferred because it is generally faster than stable /// sorting and it doesn't allocate auxiliary memory. @@ -200,7 +202,7 @@ impl<T> [T] { /// Sorts the slice with a comparator function. /// - /// This sort is stable (i.e., does not reorder equal elements) and `O(n log n)` worst-case. + /// This sort is stable (i.e., does not reorder equal elements) and `O(n * log(n))` worst-case. /// /// The comparator function must define a total ordering for the elements in the slice. If /// the ordering is not total, the order of the elements is unspecified. An order is a @@ -254,7 +256,7 @@ impl<T> [T] { /// Sorts the slice with a key extraction function. /// - /// This sort is stable (i.e., does not reorder equal elements) and `O(m n log(m n))` + /// This sort is stable (i.e., does not reorder equal elements) and `O(m * n * log(n))` /// worst-case, where the key function is `O(m)`. /// /// For expensive key functions (e.g. functions that are not simple property accesses or @@ -297,7 +299,7 @@ impl<T> [T] { /// /// During sorting, the key function is called only once per element. /// - /// This sort is stable (i.e., does not reorder equal elements) and `O(m n + n log n)` + /// This sort is stable (i.e., does not reorder equal elements) and `O(m * n + n * log(n))` /// worst-case, where the key function is `O(m)`. /// /// For simple key functions (e.g., functions that are property accesses or @@ -935,7 +937,7 @@ where /// 1. for every `i` in `1..runs.len()`: `runs[i - 1].len > runs[i].len` /// 2. for every `i` in `2..runs.len()`: `runs[i - 2].len > runs[i - 1].len + runs[i].len` /// -/// The invariants ensure that the total running time is `O(n log n)` worst-case. +/// The invariants ensure that the total running time is `O(n * log(n))` worst-case. fn merge_sort<T, F>(v: &mut [T], mut is_less: F) where F: FnMut(&T, &T) -> bool, diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index 1e5fe125c55..80fa8139915 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -482,6 +482,7 @@ impl String { /// [`String`]: struct.String.html /// [`u8`]: ../../std/primitive.u8.html /// [`Vec<u8>`]: ../../std/vec/struct.Vec.html + /// [`&str`]: ../../std/primitive.str.html /// [`str::from_utf8`]: ../../std/str/fn.from_utf8.html /// [`into_bytes`]: struct.String.html#method.into_bytes /// [`FromUtf8Error`]: struct.FromUtf8Error.html @@ -1827,7 +1828,13 @@ impl<'a> Extend<Cow<'a, str>> for String { } } -/// A convenience impl that delegates to the impl for `&str` +/// A convenience impl that delegates to the impl for `&str`. +/// +/// # Examples +/// +/// ``` +/// assert_eq!(String::from("Hello world").find("world"), Some(6)); +/// ``` #[unstable( feature = "pattern", reason = "API not fully fleshed out and ready to be stabilized", diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 7ef281ff208..b4a9da84787 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -971,7 +971,7 @@ impl<T> Vec<T> { } let len = self.len(); - if !(index < len) { + if index >= len { assert_failed(index, len); } unsafe { @@ -1010,7 +1010,7 @@ impl<T> Vec<T> { } let len = self.len(); - if !(index <= len) { + if index > len { assert_failed(index, len); } @@ -1058,7 +1058,7 @@ impl<T> Vec<T> { } let len = self.len(); - if !(index < len) { + if index >= len { assert_failed(index, len); } unsafe { @@ -1331,10 +1331,10 @@ impl<T> Vec<T> { panic!("end drain index (is {}) should be <= len (is {})", end, len); } - if !(start <= end) { + if start > end { start_assert_failed(start, end); } - if !(end <= len) { + if end > len { end_assert_failed(end, len); } @@ -1432,7 +1432,7 @@ impl<T> Vec<T> { panic!("`at` split index (is {}) should be <= len (is {})", at, len); } - if !(at <= self.len()) { + if at > self.len() { assert_failed(at, self.len()); } diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 8c542136a7f..335969b3ef0 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -858,7 +858,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> { #[must_use] #[stable(feature = "rust1", since = "1.0.0")] fn le(&self, other: &Rhs) -> bool { - matches!(self.partial_cmp(other), Some(Less) | Some(Equal)) + matches!(self.partial_cmp(other), Some(Less | Equal)) } /// This method tests greater than (for `self` and `other`) and is used by the `>` operator. @@ -895,7 +895,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> { #[must_use] #[stable(feature = "rust1", since = "1.0.0")] fn ge(&self, other: &Rhs) -> bool { - matches!(self.partial_cmp(other), Some(Greater) | Some(Equal)) + matches!(self.partial_cmp(other), Some(Greater | Equal)) } } diff --git a/src/libcore/default.rs b/src/libcore/default.rs index 15ac3aea8b7..06402a05d26 100644 --- a/src/libcore/default.rs +++ b/src/libcore/default.rs @@ -54,7 +54,7 @@ /// /// ## How can I implement `Default`? /// -/// Provides an implementation for the `default()` method that returns the value of +/// Provide an implementation for the `default()` method that returns the value of /// your type that should be the default: /// /// ``` diff --git a/src/libcore/future/mod.rs b/src/libcore/future/mod.rs index 8dfda7a4a32..a6b769147d0 100644 --- a/src/libcore/future/mod.rs +++ b/src/libcore/future/mod.rs @@ -77,9 +77,6 @@ where #[unstable(feature = "gen_future", issue = "50547")] #[cfg(not(bootstrap))] #[inline] -pub unsafe fn poll_with_context<F>(f: Pin<&mut F>, mut cx: ResumeTy) -> Poll<F::Output> -where - F: Future, -{ - F::poll(f, cx.0.as_mut()) +pub unsafe fn get_context<'a, 'b>(cx: ResumeTy) -> &'a mut Context<'b> { + &mut *cx.0.as_ptr().cast() } diff --git a/src/libcore/iter/adapters/fuse.rs b/src/libcore/iter/adapters/fuse.rs index 23bc215aa77..502fc2e6315 100644 --- a/src/libcore/iter/adapters/fuse.rs +++ b/src/libcore/iter/adapters/fuse.rs @@ -44,6 +44,19 @@ macro_rules! fuse { }; } +// NOTE: for `I: FusedIterator`, we assume that the iterator is always `Some`. +// Implementing this as a directly-expanded macro helps codegen performance. +macro_rules! unchecked { + ($self:ident) => { + match $self { + Fuse { iter: Some(iter) } => iter, + // SAFETY: the specialized iterator never sets `None` + Fuse { iter: None } => unsafe { intrinsics::unreachable() }, + } + }; +} + +// Any implementation here is made internal to avoid exposing default fns outside this trait #[stable(feature = "rust1", since = "1.0.0")] impl<I> Iterator for Fuse<I> where @@ -52,6 +65,193 @@ where type Item = <I as Iterator>::Item; #[inline] + fn next(&mut self) -> Option<Self::Item> { + FuseImpl::next(self) + } + + #[inline] + fn nth(&mut self, n: usize) -> Option<I::Item> { + FuseImpl::nth(self, n) + } + + #[inline] + fn last(self) -> Option<Self::Item> { + FuseImpl::last(self) + } + + #[inline] + fn count(self) -> usize { + FuseImpl::count(self) + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + FuseImpl::size_hint(self) + } + + #[inline] + fn try_fold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R + where + Self: Sized, + Fold: FnMut(Acc, Self::Item) -> R, + R: Try<Ok = Acc>, + { + FuseImpl::try_fold(self, acc, fold) + } + + #[inline] + fn fold<Acc, Fold>(self, acc: Acc, fold: Fold) -> Acc + where + Fold: FnMut(Acc, Self::Item) -> Acc, + { + FuseImpl::fold(self, acc, fold) + } + + #[inline] + fn find<P>(&mut self, predicate: P) -> Option<Self::Item> + where + P: FnMut(&Self::Item) -> bool, + { + FuseImpl::find(self, predicate) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<I> DoubleEndedIterator for Fuse<I> +where + I: DoubleEndedIterator, +{ + #[inline] + fn next_back(&mut self) -> Option<<I as Iterator>::Item> { + FuseImpl::next_back(self) + } + + #[inline] + fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> { + FuseImpl::nth_back(self, n) + } + + #[inline] + fn try_rfold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R + where + Self: Sized, + Fold: FnMut(Acc, Self::Item) -> R, + R: Try<Ok = Acc>, + { + FuseImpl::try_rfold(self, acc, fold) + } + + #[inline] + fn rfold<Acc, Fold>(self, acc: Acc, fold: Fold) -> Acc + where + Fold: FnMut(Acc, Self::Item) -> Acc, + { + FuseImpl::rfold(self, acc, fold) + } + + #[inline] + fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item> + where + P: FnMut(&Self::Item) -> bool, + { + FuseImpl::rfind(self, predicate) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<I> ExactSizeIterator for Fuse<I> +where + I: ExactSizeIterator, +{ + fn len(&self) -> usize { + FuseImpl::len(self) + } + + fn is_empty(&self) -> bool { + FuseImpl::is_empty(self) + } +} + +unsafe impl<I> TrustedRandomAccess for Fuse<I> +where + I: TrustedRandomAccess, +{ + unsafe fn get_unchecked(&mut self, i: usize) -> I::Item { + match self.iter { + Some(ref mut iter) => iter.get_unchecked(i), + // SAFETY: the caller asserts there is an item at `i`, so we're not exhausted. + None => intrinsics::unreachable(), + } + } + + fn may_have_side_effect() -> bool { + I::may_have_side_effect() + } +} + +// Fuse specialization trait +#[doc(hidden)] +trait FuseImpl<I> { + type Item; + + // Functions specific to any normal Iterators + fn next(&mut self) -> Option<Self::Item>; + fn nth(&mut self, n: usize) -> Option<Self::Item>; + fn last(self) -> Option<Self::Item>; + fn count(self) -> usize; + fn size_hint(&self) -> (usize, Option<usize>); + fn try_fold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R + where + Self: Sized, + Fold: FnMut(Acc, Self::Item) -> R, + R: Try<Ok = Acc>; + fn fold<Acc, Fold>(self, acc: Acc, fold: Fold) -> Acc + where + Fold: FnMut(Acc, Self::Item) -> Acc; + fn find<P>(&mut self, predicate: P) -> Option<Self::Item> + where + P: FnMut(&Self::Item) -> bool; + + // Functions specific to DoubleEndedIterators + fn next_back(&mut self) -> Option<Self::Item> + where + I: DoubleEndedIterator; + fn nth_back(&mut self, n: usize) -> Option<Self::Item> + where + I: DoubleEndedIterator; + fn try_rfold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R + where + Self: Sized, + Fold: FnMut(Acc, Self::Item) -> R, + R: Try<Ok = Acc>, + I: DoubleEndedIterator; + fn rfold<Acc, Fold>(self, acc: Acc, fold: Fold) -> Acc + where + Fold: FnMut(Acc, Self::Item) -> Acc, + I: DoubleEndedIterator; + fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item> + where + P: FnMut(&Self::Item) -> bool, + I: DoubleEndedIterator; + + // Functions specific to ExactSizeIterator + fn len(&self) -> usize + where + I: ExactSizeIterator; + fn is_empty(&self) -> bool + where + I: ExactSizeIterator; +} + +// General Fuse impl +#[doc(hidden)] +impl<I> FuseImpl<I> for Fuse<I> +where + I: Iterator, +{ + type Item = <I as Iterator>::Item; + + #[inline] default fn next(&mut self) -> Option<<I as Iterator>::Item> { fuse!(self.iter.next()) } @@ -117,20 +317,20 @@ where { fuse!(self.iter.find(predicate)) } -} -#[stable(feature = "rust1", since = "1.0.0")] -impl<I> DoubleEndedIterator for Fuse<I> -where - I: DoubleEndedIterator, -{ #[inline] - default fn next_back(&mut self) -> Option<<I as Iterator>::Item> { + default fn next_back(&mut self) -> Option<<I as Iterator>::Item> + where + I: DoubleEndedIterator, + { fuse!(self.iter.next_back()) } #[inline] - default fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> { + default fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> + where + I: DoubleEndedIterator, + { fuse!(self.iter.nth_back(n)) } @@ -140,6 +340,7 @@ where Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok = Acc>, + I: DoubleEndedIterator, { if let Some(ref mut iter) = self.iter { acc = iter.try_rfold(acc, fold)?; @@ -152,6 +353,7 @@ where default fn rfold<Acc, Fold>(self, mut acc: Acc, fold: Fold) -> Acc where Fold: FnMut(Acc, Self::Item) -> Acc, + I: DoubleEndedIterator, { if let Some(iter) = self.iter { acc = iter.rfold(acc, fold); @@ -163,24 +365,27 @@ where default fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item> where P: FnMut(&Self::Item) -> bool, + I: DoubleEndedIterator, { fuse!(self.iter.rfind(predicate)) } -} -#[stable(feature = "rust1", since = "1.0.0")] -impl<I> ExactSizeIterator for Fuse<I> -where - I: ExactSizeIterator, -{ - default fn len(&self) -> usize { + #[inline] + default fn len(&self) -> usize + where + I: ExactSizeIterator, + { match self.iter { Some(ref iter) => iter.len(), None => 0, } } - default fn is_empty(&self) -> bool { + #[inline] + default fn is_empty(&self) -> bool + where + I: ExactSizeIterator, + { match self.iter { Some(ref iter) => iter.is_empty(), None => true, @@ -188,20 +393,8 @@ where } } -// NOTE: for `I: FusedIterator`, we assume that the iterator is always `Some`. -// Implementing this as a directly-expanded macro helps codegen performance. -macro_rules! unchecked { - ($self:ident) => { - match $self { - Fuse { iter: Some(iter) } => iter, - // SAFETY: the specialized iterator never sets `None` - Fuse { iter: None } => unsafe { intrinsics::unreachable() }, - } - }; -} - -#[stable(feature = "fused", since = "1.26.0")] -impl<I> Iterator for Fuse<I> +#[doc(hidden)] +impl<I> FuseImpl<I> for Fuse<I> where I: FusedIterator, { @@ -255,20 +448,20 @@ where { unchecked!(self).find(predicate) } -} -#[stable(feature = "fused", since = "1.26.0")] -impl<I> DoubleEndedIterator for Fuse<I> -where - I: DoubleEndedIterator + FusedIterator, -{ #[inline] - fn next_back(&mut self) -> Option<<I as Iterator>::Item> { + fn next_back(&mut self) -> Option<<I as Iterator>::Item> + where + I: DoubleEndedIterator, + { unchecked!(self).next_back() } #[inline] - fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> { + fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> + where + I: DoubleEndedIterator, + { unchecked!(self).nth_back(n) } @@ -278,6 +471,7 @@ where Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok = Acc>, + I: DoubleEndedIterator, { unchecked!(self).try_rfold(init, fold) } @@ -286,6 +480,7 @@ where fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc where Fold: FnMut(Acc, Self::Item) -> Acc, + I: DoubleEndedIterator, { unchecked!(self).rfold(init, fold) } @@ -294,38 +489,24 @@ where fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item> where P: FnMut(&Self::Item) -> bool, + I: DoubleEndedIterator, { unchecked!(self).rfind(predicate) } -} -#[stable(feature = "rust1", since = "1.0.0")] -impl<I> ExactSizeIterator for Fuse<I> -where - I: ExactSizeIterator + FusedIterator, -{ - fn len(&self) -> usize { + #[inline] + fn len(&self) -> usize + where + I: ExactSizeIterator, + { unchecked!(self).len() } - fn is_empty(&self) -> bool { + #[inline] + fn is_empty(&self) -> bool + where + I: ExactSizeIterator, + { unchecked!(self).is_empty() } } - -unsafe impl<I> TrustedRandomAccess for Fuse<I> -where - I: TrustedRandomAccess, -{ - unsafe fn get_unchecked(&mut self, i: usize) -> I::Item { - match self.iter { - Some(ref mut iter) => iter.get_unchecked(i), - // SAFETY: the caller asserts there is an item at `i`, so we're not exhausted. - None => intrinsics::unreachable(), - } - } - - fn may_have_side_effect() -> bool { - I::may_have_side_effect() - } -} diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs index c8829817e19..34ca79154b6 100644 --- a/src/libcore/iter/traits/iterator.rs +++ b/src/libcore/iter/traits/iterator.rs @@ -3109,7 +3109,7 @@ pub trait Iterator { Self::Item: PartialOrd<I::Item>, Self: Sized, { - matches!(self.partial_cmp(other), Some(Ordering::Less) | Some(Ordering::Equal)) + matches!(self.partial_cmp(other), Some(Ordering::Less | Ordering::Equal)) } /// Determines if the elements of this `Iterator` are lexicographically @@ -3149,7 +3149,7 @@ pub trait Iterator { Self::Item: PartialOrd<I::Item>, Self: Sized, { - matches!(self.partial_cmp(other), Some(Ordering::Greater) | Some(Ordering::Equal)) + matches!(self.partial_cmp(other), Some(Ordering::Greater | Ordering::Equal)) } /// Checks if the elements of this iterator are sorted. diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index a04b7162c92..1c7bce3fac5 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -105,6 +105,7 @@ #![feature(exhaustive_patterns)] #![feature(no_core)] #![feature(optin_builtin_traits)] +#![feature(or_patterns)] #![feature(prelude_import)] #![feature(repr_simd, platform_intrinsics)] #![feature(rustc_attrs)] diff --git a/src/libcore/num/dec2flt/parse.rs b/src/libcore/num/dec2flt/parse.rs index 93b08bce853..2766843155a 100644 --- a/src/libcore/num/dec2flt/parse.rs +++ b/src/libcore/num/dec2flt/parse.rs @@ -54,7 +54,7 @@ pub fn parse_decimal(s: &str) -> ParseResult<'_> { match s.first() { None => Valid(Decimal::new(integral, b"", 0)), - Some(&b'e') | Some(&b'E') => { + Some(&b'e' | &b'E') => { if integral.is_empty() { return Invalid; // No digits before 'e' } @@ -70,7 +70,7 @@ pub fn parse_decimal(s: &str) -> ParseResult<'_> { match s.first() { None => Valid(Decimal::new(integral, fractional, 0)), - Some(&b'e') | Some(&b'E') => parse_exp(integral, fractional, &s[1..]), + Some(&b'e' | &b'E') => parse_exp(integral, fractional, &s[1..]), _ => Invalid, // Trailing junk after fractional part } } diff --git a/src/libcore/num/flt2dec/mod.rs b/src/libcore/num/flt2dec/mod.rs index f5cd26a1852..9adea94e87d 100644 --- a/src/libcore/num/flt2dec/mod.rs +++ b/src/libcore/num/flt2dec/mod.rs @@ -422,14 +422,14 @@ fn determine_sign(sign: Sign, decoded: &FullDecoded, negative: bool) -> &'static "+" } } - (_, Sign::Minus) | (_, Sign::MinusRaw) => { + (_, Sign::Minus | Sign::MinusRaw) => { if negative { "-" } else { "" } } - (_, Sign::MinusPlus) | (_, Sign::MinusPlusRaw) => { + (_, Sign::MinusPlus | Sign::MinusPlusRaw) => { if negative { "-" } else { diff --git a/src/libcore/ops/arith.rs b/src/libcore/ops/arith.rs index e9ec81394e3..622a138abe9 100644 --- a/src/libcore/ops/arith.rs +++ b/src/libcore/ops/arith.rs @@ -617,35 +617,22 @@ pub trait Neg { fn neg(self) -> Self::Output; } -macro_rules! neg_impl_core { - ($id:ident => $body:expr, $($t:ty)*) => ($( +macro_rules! neg_impl { + ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] impl Neg for $t { type Output = $t; #[inline] #[rustc_inherit_overflow_checks] - fn neg(self) -> $t { let $id = self; $body } + fn neg(self) -> $t { -self } } forward_ref_unop! { impl Neg, neg for $t } )*) } -macro_rules! neg_impl_numeric { - ($($t:ty)*) => { neg_impl_core!{ x => -x, $($t)*} } -} - -#[allow(unused_macros)] -macro_rules! neg_impl_unsigned { - ($($t:ty)*) => { - neg_impl_core!{ x => { - !x.wrapping_add(1) - }, $($t)*} } -} - -// neg_impl_unsigned! { usize u8 u16 u32 u64 } -neg_impl_numeric! { isize i8 i16 i32 i64 i128 f32 f64 } +neg_impl! { isize i8 i16 i32 i64 i128 f32 f64 } /// The addition assignment operator `+=`. /// diff --git a/src/libcore/ptr/const_ptr.rs b/src/libcore/ptr/const_ptr.rs index 52e224d2a02..729e0b897c0 100644 --- a/src/libcore/ptr/const_ptr.rs +++ b/src/libcore/ptr/const_ptr.rs @@ -706,6 +706,34 @@ impl<T: ?Sized> *const T { } } +#[cfg(not(bootstrap))] +#[lang = "const_slice_ptr"] +impl<T> *const [T] { + /// Returns the length of a raw slice. + /// + /// The returned value is the number of **elements**, not the number of bytes. + /// + /// This function is safe, even when the raw slice cannot be cast to a slice + /// reference because the pointer is null or unaligned. + /// + /// # Examples + /// + /// ```rust + /// #![feature(slice_ptr_len)] + /// + /// use std::ptr; + /// + /// let slice: *const [i8] = ptr::slice_from_raw_parts(ptr::null(), 3); + /// assert_eq!(slice.len(), 3); + /// ``` + #[inline] + #[unstable(feature = "slice_ptr_len", issue = "71146")] + #[rustc_const_unstable(feature = "const_slice_ptr_len", issue = "71146")] + pub const fn len(self) -> usize { + unsafe { Repr { rust: self }.raw }.len + } +} + // Equality for pointers #[stable(feature = "rust1", since = "1.0.0")] impl<T: ?Sized> PartialEq for *const T { diff --git a/src/libcore/ptr/mut_ptr.rs b/src/libcore/ptr/mut_ptr.rs index 9f85d781d69..3b7e83bf37f 100644 --- a/src/libcore/ptr/mut_ptr.rs +++ b/src/libcore/ptr/mut_ptr.rs @@ -894,6 +894,34 @@ impl<T: ?Sized> *mut T { } } +#[cfg(not(bootstrap))] +#[lang = "mut_slice_ptr"] +impl<T> *mut [T] { + /// Returns the length of a raw slice. + /// + /// The returned value is the number of **elements**, not the number of bytes. + /// + /// This function is safe, even when the raw slice cannot be cast to a slice + /// reference because the pointer is null or unaligned. + /// + /// # Examples + /// + /// ```rust + /// #![feature(slice_ptr_len)] + /// + /// use std::ptr; + /// + /// let slice: *mut [i8] = ptr::slice_from_raw_parts_mut(ptr::null_mut(), 3); + /// assert_eq!(slice.len(), 3); + /// ``` + #[inline] + #[unstable(feature = "slice_ptr_len", issue = "71146")] + #[rustc_const_unstable(feature = "const_slice_ptr_len", issue = "71146")] + pub const fn len(self) -> usize { + unsafe { Repr { rust_mut: self }.raw }.len + } +} + // Equality for pointers #[stable(feature = "rust1", since = "1.0.0")] impl<T: ?Sized> PartialEq for *mut T { diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 66aad324618..df976128b5e 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -1606,7 +1606,7 @@ impl<T> [T] { /// Sorts the slice, but may not preserve the order of equal elements. /// /// This sort is unstable (i.e., may reorder equal elements), in-place - /// (i.e., does not allocate), and `O(n log n)` worst-case. + /// (i.e., does not allocate), and `O(n * log(n))` worst-case. /// /// # Current implementation /// @@ -1642,7 +1642,7 @@ impl<T> [T] { /// elements. /// /// This sort is unstable (i.e., may reorder equal elements), in-place - /// (i.e., does not allocate), and `O(n log n)` worst-case. + /// (i.e., does not allocate), and `O(n * log(n))` worst-case. /// /// The comparator function must define a total ordering for the elements in the slice. If /// the ordering is not total, the order of the elements is unspecified. An order is a @@ -1697,7 +1697,7 @@ impl<T> [T] { /// elements. /// /// This sort is unstable (i.e., may reorder equal elements), in-place - /// (i.e., does not allocate), and `O(m n log(m n))` worst-case, where the key function is + /// (i.e., does not allocate), and `O(m * n * log(n))` worst-case, where the key function is /// `O(m)`. /// /// # Current implementation @@ -1957,7 +1957,7 @@ impl<T> [T] { // over all the elements, swapping as we go so that at the end // the elements we wish to keep are in the front, and those we // wish to reject are at the back. We can then split the slice. - // This operation is still O(n). + // This operation is still `O(n)`. // // Example: We start in this state, where `r` represents "next // read" and `w` represents "next_write`. diff --git a/src/libcore/slice/sort.rs b/src/libcore/slice/sort.rs index 019832e16f8..be3e7aaa2e8 100644 --- a/src/libcore/slice/sort.rs +++ b/src/libcore/slice/sort.rs @@ -143,7 +143,7 @@ where } } -/// Sorts `v` using heapsort, which guarantees `O(n log n)` worst-case. +/// Sorts `v` using heapsort, which guarantees `O(n * log(n))` worst-case. #[cold] pub fn heapsort<T, F>(v: &mut [T], is_less: &mut F) where @@ -621,7 +621,7 @@ where } // If too many bad pivot choices were made, simply fall back to heapsort in order to - // guarantee `O(n log n)` worst-case. + // guarantee `O(n * log(n))` worst-case. if limit == 0 { heapsort(v, is_less); return; @@ -684,7 +684,7 @@ where } } -/// Sorts `v` using pattern-defeating quicksort, which is `O(n log n)` worst-case. +/// Sorts `v` using pattern-defeating quicksort, which is `O(n * log(n))` worst-case. pub fn quicksort<T, F>(v: &mut [T], mut is_less: F) where F: FnMut(&T, &T) -> bool, diff --git a/src/libcore/str/pattern.rs b/src/libcore/str/pattern.rs index 30fd55f7b7f..708e4e5560e 100644 --- a/src/libcore/str/pattern.rs +++ b/src/libcore/str/pattern.rs @@ -451,7 +451,13 @@ unsafe impl<'a> ReverseSearcher<'a> for CharSearcher<'a> { impl<'a> DoubleEndedSearcher<'a> for CharSearcher<'a> {} -/// Searches for chars that are equal to a given char +/// Searches for chars that are equal to a given `char`. +/// +/// # Examples +/// +/// ``` +/// assert_eq!("Hello world".find('o'), Some(4)); +/// ``` impl<'a> Pattern<'a> for char { type Searcher = CharSearcher<'a>; @@ -696,7 +702,14 @@ unsafe impl<'a, 'b> ReverseSearcher<'a> for CharSliceSearcher<'a, 'b> { impl<'a, 'b> DoubleEndedSearcher<'a> for CharSliceSearcher<'a, 'b> {} -/// Searches for chars that are equal to any of the chars in the array +/// Searches for chars that are equal to any of the chars in the array. +/// +/// # Examples +/// +/// ``` +/// assert_eq!("Hello world".find(&['l', 'l'] as &[_]), Some(2)); +/// assert_eq!("Hello world".find(&['l', 'l'][..]), Some(2)); +/// ``` impl<'a, 'b> Pattern<'a> for &'b [char] { pattern_methods!(CharSliceSearcher<'a, 'b>, MultiCharEqPattern, CharSliceSearcher); } @@ -738,7 +751,14 @@ where impl<'a, F> DoubleEndedSearcher<'a> for CharPredicateSearcher<'a, F> where F: FnMut(char) -> bool {} -/// Searches for chars that match the given predicate +/// Searches for chars that match the given predicate. +/// +/// # Examples +/// +/// ``` +/// assert_eq!("Hello world".find(char::is_uppercase), Some(0)); +/// assert_eq!("Hello world".find(|c| "aeiou".contains(c)), Some(1)); +/// ``` impl<'a, F> Pattern<'a> for F where F: FnMut(char) -> bool, @@ -763,6 +783,12 @@ impl<'a, 'b, 'c> Pattern<'a> for &'c &'b str { /// /// Will handle the pattern `""` as returning empty matches at each character /// boundary. +/// +/// # Examples +/// +/// ``` +/// assert_eq!("Hello world".find("world"), Some(6)); +/// ``` impl<'a, 'b> Pattern<'a> for &'b str { type Searcher = StrSearcher<'a, 'b>; @@ -771,7 +797,7 @@ impl<'a, 'b> Pattern<'a> for &'b str { StrSearcher::new(haystack, self) } - /// Checks whether the pattern matches at the front of the haystack + /// Checks whether the pattern matches at the front of the haystack. #[inline] fn is_prefix_of(self, haystack: &'a str) -> bool { haystack.as_bytes().starts_with(self.as_bytes()) @@ -788,7 +814,7 @@ impl<'a, 'b> Pattern<'a> for &'b str { } } - /// Checks whether the pattern matches at the back of the haystack + /// Checks whether the pattern matches at the back of the haystack. #[inline] fn is_suffix_of(self, haystack: &'a str) -> bool { haystack.as_bytes().ends_with(self.as_bytes()) diff --git a/src/librustc_ast/lib.rs b/src/librustc_ast/lib.rs index 1687f828f24..4ba062625a4 100644 --- a/src/librustc_ast/lib.rs +++ b/src/librustc_ast/lib.rs @@ -33,7 +33,6 @@ pub mod util { pub mod comments; pub mod lev_distance; pub mod literal; - pub mod map_in_place; pub mod parser; } diff --git a/src/librustc_ast/mut_visit.rs b/src/librustc_ast/mut_visit.rs index a72a60c30b2..e66b358c4ac 100644 --- a/src/librustc_ast/mut_visit.rs +++ b/src/librustc_ast/mut_visit.rs @@ -11,8 +11,8 @@ use crate::ast::*; use crate::ptr::P; use crate::token::{self, Token}; use crate::tokenstream::*; -use crate::util::map_in_place::MapInPlace; +use rustc_data_structures::map_in_place::MapInPlace; use rustc_data_structures::sync::Lrc; use rustc_span::source_map::{respan, Spanned}; use rustc_span::Span; diff --git a/src/librustc_ast_lowering/expr.rs b/src/librustc_ast_lowering/expr.rs index 9984eb4e282..0eed47050aa 100644 --- a/src/librustc_ast_lowering/expr.rs +++ b/src/librustc_ast_lowering/expr.rs @@ -556,9 +556,9 @@ impl<'hir> LoweringContext<'_, 'hir> { /// ```rust /// match <expr> { /// mut pinned => loop { - /// match unsafe { ::std::future::poll_with_context( + /// match unsafe { ::std::future::Future::poll( /// <::std::pin::Pin>::new_unchecked(&mut pinned), - /// task_context, + /// ::std::future::get_context(task_context), /// ) } { /// ::std::task::Poll::Ready(result) => break result, /// ::std::task::Poll::Pending => {} @@ -590,6 +590,7 @@ impl<'hir> LoweringContext<'_, 'hir> { await_span, self.allow_gen_future.clone(), ); + let expr = self.lower_expr(expr); let pinned_ident = Ident::with_dummy_span(sym::pinned); let (pinned_pat, pinned_pat_hid) = @@ -598,9 +599,9 @@ impl<'hir> LoweringContext<'_, 'hir> { let task_context_ident = Ident::with_dummy_span(sym::_task_context); // unsafe { - // ::std::future::poll_with_context( + // ::std::future::Future::poll( // ::std::pin::Pin::new_unchecked(&mut pinned), - // task_context, + // ::std::future::get_context(task_context), // ) // } let poll_expr = { @@ -621,10 +622,15 @@ impl<'hir> LoweringContext<'_, 'hir> { arena_vec![self; ref_mut_pinned], ); let new_unchecked = self.expr(span, new_unchecked_expr_kind, ThinVec::new()); - let call = self.expr_call_std_path( + let get_context = self.expr_call_std_path_mut( gen_future_span, - &[sym::future, sym::poll_with_context], - arena_vec![self; new_unchecked, task_context], + &[sym::future, sym::get_context], + arena_vec![self; task_context], + ); + let call = self.expr_call_std_path( + span, + &[sym::future, sym::Future, sym::poll], + arena_vec![self; new_unchecked, get_context], ); self.arena.alloc(self.expr_unsafe(call)) }; @@ -671,7 +677,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let unit = self.expr_unit(span); let yield_expr = self.expr( span, - hir::ExprKind::Yield(unit, hir::YieldSource::Await), + hir::ExprKind::Yield(unit, hir::YieldSource::Await { expr: Some(expr.hir_id) }), ThinVec::new(), ); let yield_expr = self.arena.alloc(yield_expr); @@ -704,7 +710,6 @@ impl<'hir> LoweringContext<'_, 'hir> { // match <expr> { // mut pinned => loop { .. } // } - let expr = self.lower_expr(expr); hir::ExprKind::Match(expr, arena_vec![self; pinned_arm], hir::MatchSource::AwaitDesugar) } @@ -1326,25 +1331,43 @@ impl<'hir> LoweringContext<'_, 'hir> { self.arena.alloc(self.expr(sp, hir::ExprKind::Tup(&[]), ThinVec::new())) } + fn expr_call_mut( + &mut self, + span: Span, + e: &'hir hir::Expr<'hir>, + args: &'hir [hir::Expr<'hir>], + ) -> hir::Expr<'hir> { + self.expr(span, hir::ExprKind::Call(e, args), ThinVec::new()) + } + fn expr_call( &mut self, span: Span, e: &'hir hir::Expr<'hir>, args: &'hir [hir::Expr<'hir>], ) -> &'hir hir::Expr<'hir> { - self.arena.alloc(self.expr(span, hir::ExprKind::Call(e, args), ThinVec::new())) + self.arena.alloc(self.expr_call_mut(span, e, args)) } // Note: associated functions must use `expr_call_std_path`. - fn expr_call_std_path( + fn expr_call_std_path_mut( &mut self, span: Span, path_components: &[Symbol], args: &'hir [hir::Expr<'hir>], - ) -> &'hir hir::Expr<'hir> { + ) -> hir::Expr<'hir> { let path = self.arena.alloc(self.expr_std_path(span, path_components, None, ThinVec::new())); - self.expr_call(span, path, args) + self.expr_call_mut(span, path, args) + } + + fn expr_call_std_path( + &mut self, + span: Span, + path_components: &[Symbol], + args: &'hir [hir::Expr<'hir>], + ) -> &'hir hir::Expr<'hir> { + self.arena.alloc(self.expr_call_std_path_mut(span, path_components, args)) } // Create an expression calling an associated function of an std type. diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs index 9779954d759..c535885e70c 100644 --- a/src/librustc_ast_lowering/item.rs +++ b/src/librustc_ast_lowering/item.rs @@ -796,7 +796,7 @@ impl<'hir> LoweringContext<'_, 'hir> { (hir::AssocItemKind::Type, default.is_some()) } AssocItemKind::Fn(_, sig, _, default) => { - (hir::AssocItemKind::Method { has_self: sig.decl.has_self() }, default.is_some()) + (hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }, default.is_some()) } AssocItemKind::MacCall(..) => unimplemented!(), }; @@ -894,7 +894,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } } AssocItemKind::Fn(_, sig, ..) => { - hir::AssocItemKind::Method { has_self: sig.decl.has_self() } + hir::AssocItemKind::Fn { has_self: sig.decl.has_self() } } AssocItemKind::MacCall(..) => unimplemented!(), }, diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 9bb1f57a524..c2c7de9d21b 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -168,7 +168,7 @@ struct LoweringContext<'a, 'hir: 'a> { current_hir_id_owner: Vec<(LocalDefId, u32)>, item_local_id_counters: NodeMap<u32>, - node_id_to_hir_id: IndexVec<NodeId, hir::HirId>, + node_id_to_hir_id: IndexVec<NodeId, Option<hir::HirId>>, allow_try_trait: Option<Lrc<[Symbol]>>, allow_gen_future: Option<Lrc<[Symbol]>>, @@ -522,7 +522,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } self.lower_node_id(CRATE_NODE_ID); - debug_assert!(self.node_id_to_hir_id[CRATE_NODE_ID] == hir::CRATE_HIR_ID); + debug_assert!(self.node_id_to_hir_id[CRATE_NODE_ID] == Some(hir::CRATE_HIR_ID)); visit::walk_crate(&mut MiscCollector { lctx: &mut self, hir_id_owner: None }, c); visit::walk_crate(&mut item::ItemLowerer { lctx: &mut self }, c); @@ -530,7 +530,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let module = self.lower_mod(&c.module); let attrs = self.lower_attrs(&c.attrs); let body_ids = body_ids(&self.bodies); - let proc_macros = c.proc_macros.iter().map(|id| self.node_id_to_hir_id[*id]).collect(); + let proc_macros = + c.proc_macros.iter().map(|id| self.node_id_to_hir_id[*id].unwrap()).collect(); self.resolver.definitions().init_node_id_to_hir_id_mapping(self.node_id_to_hir_id); @@ -571,26 +572,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ast_node_id: NodeId, alloc_hir_id: impl FnOnce(&mut Self) -> hir::HirId, ) -> hir::HirId { - if ast_node_id == DUMMY_NODE_ID { - return hir::DUMMY_HIR_ID; - } + assert_ne!(ast_node_id, DUMMY_NODE_ID); let min_size = ast_node_id.as_usize() + 1; if min_size > self.node_id_to_hir_id.len() { - self.node_id_to_hir_id.resize(min_size, hir::DUMMY_HIR_ID); + self.node_id_to_hir_id.resize(min_size, None); } - let existing_hir_id = self.node_id_to_hir_id[ast_node_id]; - - if existing_hir_id == hir::DUMMY_HIR_ID { + if let Some(existing_hir_id) = self.node_id_to_hir_id[ast_node_id] { + existing_hir_id + } else { // Generate a new `HirId`. let hir_id = alloc_hir_id(self); - self.node_id_to_hir_id[ast_node_id] = hir_id; + self.node_id_to_hir_id[ast_node_id] = Some(hir_id); hir_id - } else { - existing_hir_id } } diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs index 9563325fe32..395fd746085 100644 --- a/src/librustc_ast_passes/ast_validation.rs +++ b/src/librustc_ast_passes/ast_validation.rs @@ -561,28 +561,6 @@ impl<'a> AstValidator<'a> { } } - /// We currently do not permit const generics in `const fn`, - /// as this is tantamount to allowing compile-time dependent typing. - /// - /// FIXME(const_generics): Is this really true / necessary? Discuss with @varkor. - /// At any rate, the restriction feels too syntactic. Consider moving it to e.g. typeck. - fn check_const_fn_const_generic(&self, span: Span, sig: &FnSig, generics: &Generics) { - if let Const::Yes(const_span) = sig.header.constness { - // Look for const generics and error if we find any. - for param in &generics.params { - if let GenericParamKind::Const { .. } = param.kind { - self.err_handler() - .struct_span_err( - span, - "const parameters are not permitted in const functions", - ) - .span_label(const_span, "`const` because of this") - .emit(); - } - } - } - } - fn check_item_named(&self, ident: Ident, kind: &str) { if ident.name != kw::Underscore { return; @@ -966,9 +944,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { .emit(); } } - ItemKind::Fn(def, ref sig, ref generics, ref body) => { + ItemKind::Fn(def, _, _, ref body) => { self.check_defaultness(item.span, def); - self.check_const_fn_const_generic(item.span, sig, generics); if body.is_none() { let msg = "free function without a body"; diff --git a/src/librustc_builtin_macros/deriving/debug.rs b/src/librustc_builtin_macros/deriving/debug.rs index f47be3c3c19..71f6eb44858 100644 --- a/src/librustc_builtin_macros/deriving/debug.rs +++ b/src/librustc_builtin_macros/deriving/debug.rs @@ -63,7 +63,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_> let span = cx.with_def_site_ctxt(span); let name = cx.expr_lit(span, ast::LitKind::Str(ident.name, ast::StrStyle::Cooked)); let builder = cx.ident_of("debug_trait_builder", span); - let builder_expr = cx.expr_ident(span, builder.clone()); + let builder_expr = cx.expr_ident(span, builder); let fmt = substr.nonself_args[0].clone(); diff --git a/src/librustc_builtin_macros/deriving/generic/mod.rs b/src/librustc_builtin_macros/deriving/generic/mod.rs index 9338f9afbbb..3a96c5aa8ed 100644 --- a/src/librustc_builtin_macros/deriving/generic/mod.rs +++ b/src/librustc_builtin_macros/deriving/generic/mod.rs @@ -184,8 +184,8 @@ use std::vec; use rustc_ast::ast::{self, BinOpKind, EnumDef, Expr, Generics, Ident, PatKind}; use rustc_ast::ast::{GenericArg, GenericParamKind, VariantData}; use rustc_ast::ptr::P; -use rustc_ast::util::map_in_place::MapInPlace; use rustc_attr as attr; +use rustc_data_structures::map_in_place::MapInPlace; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_session::parse::ParseSess; use rustc_span::source_map::respan; diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs index 784a3a87e98..004de8d8ca9 100644 --- a/src/librustc_codegen_llvm/attributes.rs +++ b/src/librustc_codegen_llvm/attributes.rs @@ -82,21 +82,12 @@ fn naked(val: &'ll Value, is_naked: bool) { pub fn set_frame_pointer_elimination(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) { if cx.sess().must_not_eliminate_frame_pointers() { - if llvm_util::get_major_version() >= 8 { - llvm::AddFunctionAttrStringValue( - llfn, - llvm::AttributePlace::Function, - const_cstr!("frame-pointer"), - const_cstr!("all"), - ); - } else { - llvm::AddFunctionAttrStringValue( - llfn, - llvm::AttributePlace::Function, - const_cstr!("no-frame-pointer-elim"), - const_cstr!("true"), - ); - } + llvm::AddFunctionAttrStringValue( + llfn, + llvm::AttributePlace::Function, + const_cstr!("frame-pointer"), + const_cstr!("all"), + ); } } diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs index 816329e06c7..e21cdee961d 100644 --- a/src/librustc_codegen_llvm/back/lto.rs +++ b/src/librustc_codegen_llvm/back/lto.rs @@ -463,15 +463,18 @@ fn thin_lto( // If previous imports have been deleted, or we get an IO error // reading the file storing them, then we'll just use `None` as the // prev_import_map, which will force the code to be recompiled. - let prev = - if path.exists() { ThinLTOImports::load_from_file(&path).ok() } else { None }; - let curr = ThinLTOImports::from_thin_lto_data(data); + let prev = if path.exists() { + ThinLTOImportMaps::load_from_file(&path).ok() + } else { + None + }; + let curr = ThinLTOImportMaps::from_thin_lto_data(data); (Some(path), prev, curr) } else { // If we don't compile incrementally, we don't need to load the // import data from LLVM. assert!(green_modules.is_empty()); - let curr = ThinLTOImports::default(); + let curr = ThinLTOImportMaps::default(); (None, None, curr) }; info!("thin LTO import map loaded"); @@ -497,10 +500,14 @@ fn thin_lto( let module_name = module_name_to_str(module_name); // If (1.) the module hasn't changed, and (2.) none of the modules - // it imports from has changed, *and* (3.) the import-set itself has - // not changed from the previous compile when it was last - // ThinLTO'ed, then we can re-use the post-ThinLTO version of the - // module. Otherwise, freshly perform LTO optimization. + // it imports from nor exports to have changed, *and* (3.) the + // import and export sets themselves have not changed from the + // previous compile when it was last ThinLTO'ed, then we can re-use + // the post-ThinLTO version of the module. Otherwise, freshly + // perform LTO optimization. + // + // (Note that globally, the export set is just the inverse of the + // import set.) // // This strategy means we can always save the computed imports as // canon: when we reuse the post-ThinLTO version, condition (3.) @@ -509,19 +516,30 @@ fn thin_lto( // version, the current import set *is* the correct one, since we // are doing the ThinLTO in this current compilation cycle.) // - // See rust-lang/rust#59535. + // For more discussion, see rust-lang/rust#59535 (where the import + // issue was discovered) and rust-lang/rust#69798 (where the + // analogous export issue was discovered). if let (Some(prev_import_map), true) = (prev_import_map.as_ref(), green_modules.contains_key(module_name)) { assert!(cgcx.incr_comp_session_dir.is_some()); - let prev_imports = prev_import_map.modules_imported_by(module_name); - let curr_imports = curr_import_map.modules_imported_by(module_name); + let prev_imports = prev_import_map.imports_of(module_name); + let curr_imports = curr_import_map.imports_of(module_name); + let prev_exports = prev_import_map.exports_of(module_name); + let curr_exports = curr_import_map.exports_of(module_name); let imports_all_green = curr_imports .iter() .all(|imported_module| green_modules.contains_key(imported_module)); + let exports_all_green = curr_exports + .iter() + .all(|exported_module| green_modules.contains_key(exported_module)); - if imports_all_green && equivalent_as_sets(prev_imports, curr_imports) { + if imports_all_green + && equivalent_as_sets(prev_imports, curr_imports) + && exports_all_green + && equivalent_as_sets(prev_exports, curr_exports) + { let work_product = green_modules[module_name].clone(); copy_jobs.push(work_product); info!(" - {}: re-used", module_name); @@ -881,17 +899,32 @@ pub unsafe fn optimize_thin_module( Ok(module) } +/// Summarizes module import/export relationships used by LLVM's ThinLTO pass. +/// +/// Note that we tend to have two such instances of `ThinLTOImportMaps` in use: +/// one loaded from a file that represents the relationships used during the +/// compilation associated with the incremetnal build artifacts we are +/// attempting to reuse, and another constructed via `from_thin_lto_data`, which +/// captures the relationships of ThinLTO in the current compilation. #[derive(Debug, Default)] -pub struct ThinLTOImports { +pub struct ThinLTOImportMaps { // key = llvm name of importing module, value = list of modules it imports from imports: FxHashMap<String, Vec<String>>, + // key = llvm name of exporting module, value = list of modules it exports to + exports: FxHashMap<String, Vec<String>>, } -impl ThinLTOImports { - fn modules_imported_by(&self, llvm_module_name: &str) -> &[String] { +impl ThinLTOImportMaps { + /// Returns modules imported by `llvm_module_name` during some ThinLTO pass. + fn imports_of(&self, llvm_module_name: &str) -> &[String] { self.imports.get(llvm_module_name).map(|v| &v[..]).unwrap_or(&[]) } + /// Returns modules exported by `llvm_module_name` during some ThinLTO pass. + fn exports_of(&self, llvm_module_name: &str) -> &[String] { + self.exports.get(llvm_module_name).map(|v| &v[..]).unwrap_or(&[]) + } + fn save_to_file(&self, path: &Path) -> io::Result<()> { use std::io::Write; let file = File::create(path)?; @@ -906,16 +939,20 @@ impl ThinLTOImports { Ok(()) } - fn load_from_file(path: &Path) -> io::Result<ThinLTOImports> { + fn load_from_file(path: &Path) -> io::Result<ThinLTOImportMaps> { use std::io::BufRead; let mut imports = FxHashMap::default(); - let mut current_module = None; - let mut current_imports = vec![]; + let mut exports: FxHashMap<_, Vec<_>> = FxHashMap::default(); + let mut current_module: Option<String> = None; + let mut current_imports: Vec<String> = vec![]; let file = File::open(path)?; for line in io::BufReader::new(file).lines() { let line = line?; if line.is_empty() { let importing_module = current_module.take().expect("Importing module not set"); + for imported in ¤t_imports { + exports.entry(imported.clone()).or_default().push(importing_module.clone()); + } imports.insert(importing_module, mem::replace(&mut current_imports, vec![])); } else if line.starts_with(' ') { // Space marks an imported module @@ -927,17 +964,17 @@ impl ThinLTOImports { current_module = Some(line.trim().to_string()); } } - Ok(ThinLTOImports { imports }) + Ok(ThinLTOImportMaps { imports, exports }) } /// Loads the ThinLTO import map from ThinLTOData. - unsafe fn from_thin_lto_data(data: *const llvm::ThinLTOData) -> ThinLTOImports { + unsafe fn from_thin_lto_data(data: *const llvm::ThinLTOData) -> ThinLTOImportMaps { unsafe extern "C" fn imported_module_callback( payload: *mut libc::c_void, importing_module_name: *const libc::c_char, imported_module_name: *const libc::c_char, ) { - let map = &mut *(payload as *mut ThinLTOImports); + let map = &mut *(payload as *mut ThinLTOImportMaps); let importing_module_name = CStr::from_ptr(importing_module_name); let importing_module_name = module_name_to_str(&importing_module_name); let imported_module_name = CStr::from_ptr(imported_module_name); @@ -951,8 +988,18 @@ impl ThinLTOImports { .get_mut(importing_module_name) .unwrap() .push(imported_module_name.to_owned()); + + if !map.exports.contains_key(imported_module_name) { + map.exports.insert(imported_module_name.to_owned(), vec![]); + } + + map.exports + .get_mut(imported_module_name) + .unwrap() + .push(importing_module_name.to_owned()); } - let mut map = ThinLTOImports::default(); + + let mut map = ThinLTOImportMaps::default(); llvm::LLVMRustGetThinLTOModuleImports( data, imported_module_callback, diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 82cd8589327..03bba7657bb 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -16,7 +16,6 @@ use crate::llvm::debuginfo::{ DIArray, DICompositeType, DIDescriptor, DIFile, DIFlags, DILexicalBlock, DIScope, DIType, DebugEmissionKind, }; -use crate::llvm_util; use crate::value::Value; use log::debug; @@ -1289,22 +1288,11 @@ fn prepare_union_metadata( // Enums //=----------------------------------------------------------------------------- -/// DWARF variant support is only available starting in LLVM 8. -/// Although the earlier enum debug info output did not work properly -/// in all situations, it is better for the time being to continue to -/// sometimes emit the old style rather than emit something completely -/// useless when rust is compiled against LLVM 6 or older. LLVM 7 -/// contains an early version of the DWARF variant support, and will -/// crash when handling the new debug info format. This function -/// decides which representation will be emitted. +/// DWARF variant support is only available starting in LLVM 8, but +/// on MSVC we have to use the fallback mode, because LLVM doesn't +/// lower variant parts to PDB. fn use_enum_fallback(cx: &CodegenCx<'_, '_>) -> bool { - // On MSVC we have to use the fallback mode, because LLVM doesn't - // lower variant parts to PDB. cx.sess().target.target.options.is_like_msvc - // LLVM version 7 did not release with an important bug fix; - // but the required patch is in the LLVM 8. Rust LLVM reports - // 8 as well. - || llvm_util::get_major_version() < 8 } // FIXME(eddyb) maybe precompute this? Right now it's computed once diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 63730c56f0e..86d10e91d6d 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -2,7 +2,6 @@ use crate::abi::{Abi, FnAbi, LlvmType, PassMode}; use crate::builder::Builder; use crate::context::CodegenCx; use crate::llvm; -use crate::llvm_util; use crate::type_::Type; use crate::type_of::LayoutLlvmExt; use crate::va_arg::emit_va_arg; @@ -11,7 +10,7 @@ use crate::value::Value; use rustc_ast::ast; use rustc_codegen_ssa::base::{compare_simd_types, to_immediate, wants_msvc_seh}; use rustc_codegen_ssa::common::span_invalid_monomorphization_error; -use rustc_codegen_ssa::common::{IntPredicate, TypeKind}; +use rustc_codegen_ssa::common::TypeKind; use rustc_codegen_ssa::glue; use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue}; use rustc_codegen_ssa::mir::place::PlaceRef; @@ -461,46 +460,14 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> { let is_add = name == "saturating_add"; let lhs = args[0].immediate(); let rhs = args[1].immediate(); - if llvm_util::get_major_version() >= 8 { - let llvm_name = &format!( - "llvm.{}{}.sat.i{}", - if signed { 's' } else { 'u' }, - if is_add { "add" } else { "sub" }, - width - ); - let llfn = self.get_intrinsic(llvm_name); - self.call(llfn, &[lhs, rhs], None) - } else { - let llvm_name = &format!( - "llvm.{}{}.with.overflow.i{}", - if signed { 's' } else { 'u' }, - if is_add { "add" } else { "sub" }, - width - ); - let llfn = self.get_intrinsic(llvm_name); - let pair = self.call(llfn, &[lhs, rhs], None); - let val = self.extract_value(pair, 0); - let overflow = self.extract_value(pair, 1); - let llty = self.type_ix(width); - - let limit = if signed { - let limit_lo = self - .const_uint_big(llty, (i128::MIN >> (128 - width)) as u128); - let limit_hi = self - .const_uint_big(llty, (i128::MAX >> (128 - width)) as u128); - let neg = self.icmp( - IntPredicate::IntSLT, - val, - self.const_uint(llty, 0), - ); - self.select(neg, limit_hi, limit_lo) - } else if is_add { - self.const_uint_big(llty, u128::MAX >> (128 - width)) - } else { - self.const_uint(llty, 0) - }; - self.select(overflow, limit, val) - } + let llvm_name = &format!( + "llvm.{}{}.sat.i{}", + if signed { 's' } else { 'u' }, + if is_add { "add" } else { "sub" }, + width + ); + let llfn = self.get_intrinsic(llvm_name); + self.call(llfn, &[lhs, rhs], None) } _ => bug!(), }, diff --git a/src/librustc_codegen_llvm/llvm_util.rs b/src/librustc_codegen_llvm/llvm_util.rs index a56c8802f3c..6f16b0fb79c 100644 --- a/src/librustc_codegen_llvm/llvm_util.rs +++ b/src/librustc_codegen_llvm/llvm_util.rs @@ -83,17 +83,15 @@ unsafe fn configure_llvm(sess: &Session) { if !sess.opts.debugging_opts.no_generate_arange_section { add("-generate-arange-section", false); } - if get_major_version() >= 8 { - match sess - .opts - .debugging_opts - .merge_functions - .unwrap_or(sess.target.target.options.merge_functions) - { - MergeFunctions::Disabled | MergeFunctions::Trampolines => {} - MergeFunctions::Aliases => { - add("-mergefunc-use-aliases", false); - } + match sess + .opts + .debugging_opts + .merge_functions + .unwrap_or(sess.target.target.options.merge_functions) + { + MergeFunctions::Disabled | MergeFunctions::Trampolines => {} + MergeFunctions::Aliases => { + add("-mergefunc-use-aliases", false); } } diff --git a/src/librustc_codegen_llvm/type_of.rs b/src/librustc_codegen_llvm/type_of.rs index f475ea741c8..77009aca6d3 100644 --- a/src/librustc_codegen_llvm/type_of.rs +++ b/src/librustc_codegen_llvm/type_of.rs @@ -81,7 +81,7 @@ fn uncached_llvm_type<'a, 'tcx>( }; match layout.fields { - FieldsShape::Union(_) => { + FieldsShape::Primitive | FieldsShape::Union(_) => { let fill = cx.type_padding_filler(layout.size, layout.align.abi); let packed = false; match name { @@ -368,7 +368,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> { _ => {} } match self.fields { - FieldsShape::Union(_) => { + FieldsShape::Primitive | FieldsShape::Union(_) => { bug!("TyAndLayout::llvm_field_index({:?}): not applicable", self) } diff --git a/src/librustc_codegen_ssa/Cargo.toml b/src/librustc_codegen_ssa/Cargo.toml index 717e32d4a0d..d9620a21d37 100644 --- a/src/librustc_codegen_ssa/Cargo.toml +++ b/src/librustc_codegen_ssa/Cargo.toml @@ -15,7 +15,7 @@ cc = "1.0.1" num_cpus = "1.0" memmap = "0.7" log = "0.4.5" -libc = "0.2.44" +libc = "0.2.50" jobserver = "0.1.11" tempfile = "3.1" diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index 20e64f0c488..4c66d901e7a 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -12,7 +12,7 @@ use rustc_session::search_paths::PathKind; /// need out of the shared crate context before we get rid of it. use rustc_session::{filesearch, Session}; use rustc_span::symbol::Symbol; -use rustc_target::spec::{LinkerFlavor, PanicStrategy, RelroLevel}; +use rustc_target::spec::{LinkerFlavor, LldFlavor, PanicStrategy, RelroLevel}; use super::archive::ArchiveBuilder; use super::command::Command; @@ -182,7 +182,9 @@ fn get_linker(sess: &Session, linker: &Path, flavor: LinkerFlavor) -> Command { // To comply with the Windows App Certification Kit, // MSVC needs to link with the Store versions of the runtime libraries (vcruntime, msvcrt, etc). let t = &sess.target.target; - if flavor == LinkerFlavor::Msvc && t.target_vendor == "uwp" { + if (flavor == LinkerFlavor::Msvc || flavor == LinkerFlavor::Lld(LldFlavor::Link)) + && t.target_vendor == "uwp" + { if let Some(ref tool) = msvc_tool { let original_path = tool.path(); if let Some(ref root_lib_path) = original_path.ancestors().nth(4) { @@ -759,7 +761,7 @@ fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) { } } LinkerFlavor::Gcc => { - if cfg!(target_os = "solaris") { + if cfg!(any(target_os = "solaris", target_os = "illumos")) { // On historical Solaris systems, "cc" may have // been Sun Studio, which is not flag-compatible // with "gcc". This history casts a long shadow, @@ -1530,13 +1532,8 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>( cmd.debuginfo(); // OBJECT-FILES-NO, AUDIT-ORDER - // We want to, by default, prevent the compiler from accidentally leaking in - // any system libraries, so we may explicitly ask linkers to not link to any - // libraries by default. Note that this does not happen for windows because - // windows pulls in some large number of libraries and I couldn't quite - // figure out which subset we wanted. - // - // This is all naturally configurable via the standard methods as well. + // We want to prevent the compiler from accidentally leaking in any system libraries, + // so by default we tell linkers not to link to any default libraries. if !sess.opts.cg.default_linker_libraries.unwrap_or(false) && sess.target.target.options.no_default_libraries { diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index 0baa37ae9f1..d8c5ddf586f 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -631,15 +631,7 @@ impl<'a> Linker for MsvcLinker<'a> { } fn no_default_libraries(&mut self) { - // Currently we don't pass the /NODEFAULTLIB flag to the linker on MSVC - // as there's been trouble in the past of linking the C++ standard - // library required by LLVM. This likely needs to happen one day, but - // in general Windows is also a more controlled environment than - // Unix, so it's not necessarily as critical that this be implemented. - // - // Note that there are also some licensing worries about statically - // linking some libraries which require a specific agreement, so it may - // not ever be possible for us to pass this flag. + self.cmd.arg("/NODEFAULTLIB"); } fn include_path(&mut self, path: &Path) { diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index 219d5aa77ea..49131386508 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -111,7 +111,9 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { destination: Option<(ReturnDest<'tcx, Bx::Value>, mir::BasicBlock)>, cleanup: Option<mir::BasicBlock>, ) { - if let Some(cleanup) = cleanup { + // If there is a cleanup block and the function we're calling can unwind, then + // do an invoke, otherwise do a call. + if let Some(cleanup) = cleanup.filter(|_| fn_abi.can_unwind) { let ret_bx = if let Some((_, target)) = destination { fx.blocks[target] } else { diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs index 69f11ed57ac..7d0e6998db4 100644 --- a/src/librustc_codegen_ssa/mir/operand.rs +++ b/src/librustc_codegen_ssa/mir/operand.rs @@ -6,6 +6,7 @@ use crate::glue; use crate::traits::*; use crate::MemFlags; +use rustc_errors::ErrorReported; use rustc_middle::mir; use rustc_middle::mir::interpret::{ConstValue, ErrorHandled, Pointer, Scalar}; use rustc_middle::ty::layout::TyAndLayout; @@ -447,8 +448,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.eval_mir_constant_to_operand(bx, constant).unwrap_or_else(|err| { match err { // errored or at least linted - ErrorHandled::Reported => {} - ErrorHandled::TooGeneric => bug!("codgen encountered polymorphic constant"), + ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted => {} + ErrorHandled::TooGeneric => { + bug!("codegen encountered polymorphic constant") + } } // Allow RalfJ to sleep soundly knowing that even refactorings that remove // the above error (or silence it under some conditions) will not cause UB. diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index d0180911567..d412eaeff74 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -67,6 +67,7 @@ pub mod fx; pub mod graph; pub mod jobserver; pub mod macros; +pub mod map_in_place; pub mod obligation_forest; pub mod owning_ref; pub mod ptr_key; diff --git a/src/librustc_ast/util/map_in_place.rs b/src/librustc_data_structures/map_in_place.rs index a237a6e6162..5dd9fc6e8bc 100644 --- a/src/librustc_ast/util/map_in_place.rs +++ b/src/librustc_data_structures/map_in_place.rs @@ -1,5 +1,3 @@ -// FIXME(Centril): Move to rustc_data_structures. - use smallvec::{Array, SmallVec}; use std::ptr; diff --git a/src/librustc_data_structures/stable_hasher.rs b/src/librustc_data_structures/stable_hasher.rs index a98e77cebd8..97b02eaef35 100644 --- a/src/librustc_data_structures/stable_hasher.rs +++ b/src/librustc_data_structures/stable_hasher.rs @@ -210,6 +210,12 @@ impl<CTX> HashStable<CTX> for ::std::num::NonZeroU32 { } } +impl<CTX> HashStable<CTX> for ::std::num::NonZeroUsize { + fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { + self.get().hash_stable(ctx, hasher) + } +} + impl<CTX> HashStable<CTX> for f32 { fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { let val: u32 = unsafe { ::std::mem::transmute(*self) }; diff --git a/src/librustc_error_codes/error_codes.rs b/src/librustc_error_codes/error_codes.rs index 8d9982131c3..225ede851b4 100644 --- a/src/librustc_error_codes/error_codes.rs +++ b/src/librustc_error_codes/error_codes.rs @@ -366,6 +366,7 @@ E0644: include_str!("./error_codes/E0644.md"), E0646: include_str!("./error_codes/E0646.md"), E0647: include_str!("./error_codes/E0647.md"), E0648: include_str!("./error_codes/E0648.md"), +E0657: include_str!("./error_codes/E0657.md"), E0658: include_str!("./error_codes/E0658.md"), E0659: include_str!("./error_codes/E0659.md"), E0660: include_str!("./error_codes/E0660.md"), @@ -394,6 +395,7 @@ E0703: include_str!("./error_codes/E0703.md"), E0704: include_str!("./error_codes/E0704.md"), E0705: include_str!("./error_codes/E0705.md"), E0706: include_str!("./error_codes/E0706.md"), +E0708: include_str!("./error_codes/E0708.md"), E0710: include_str!("./error_codes/E0710.md"), E0712: include_str!("./error_codes/E0712.md"), E0713: include_str!("./error_codes/E0713.md"), @@ -596,7 +598,6 @@ E0751: include_str!("./error_codes/E0751.md"), // used in argument position E0640, // infer outlives requirements // E0645, // trait aliases not finished - E0657, // `impl Trait` can only capture lifetimes bound at the fn level E0667, // `impl Trait` in projections E0687, // in-band lifetimes cannot be used in `fn`/`Fn` syntax E0688, // in-band lifetimes cannot be mixed with explicit lifetime binders @@ -604,8 +605,6 @@ E0751: include_str!("./error_codes/E0751.md"), E0696, // `continue` pointing to a labeled block // E0702, // replaced with a generic attribute input check // E0707, // multiple elided lifetimes used in arguments of `async fn` - E0708, // `async` non-`move` closures with parameters are not currently - // supported // E0709, // multiple different lifetimes used in arguments of `async fn` E0711, // a feature has been declared with conflicting stability attributes E0717, // rustc_promotable without stability attribute diff --git a/src/librustc_error_codes/error_codes/E0517.md b/src/librustc_error_codes/error_codes/E0517.md index f738d33560a..ae802245bd1 100644 --- a/src/librustc_error_codes/error_codes/E0517.md +++ b/src/librustc_error_codes/error_codes/E0517.md @@ -1,5 +1,4 @@ -This error indicates that a `#[repr(..)]` attribute was placed on an -unsupported item. +A `#[repr(..)]` attribute was placed on an unsupported item. Examples of erroneous code: diff --git a/src/librustc_error_codes/error_codes/E0518.md b/src/librustc_error_codes/error_codes/E0518.md index 1af9a3735fe..f04329bc4e6 100644 --- a/src/librustc_error_codes/error_codes/E0518.md +++ b/src/librustc_error_codes/error_codes/E0518.md @@ -1,7 +1,7 @@ -This error indicates that an `#[inline(..)]` attribute was incorrectly placed -on something other than a function or method. +An `#[inline(..)]` attribute was incorrectly placed on something other than a +function or method. -Examples of erroneous code: +Example of erroneous code: ```compile_fail,E0518 #[inline(always)] diff --git a/src/librustc_error_codes/error_codes/E0520.md b/src/librustc_error_codes/error_codes/E0520.md index e8a2b4da080..f9d7e02e5c8 100644 --- a/src/librustc_error_codes/error_codes/E0520.md +++ b/src/librustc_error_codes/error_codes/E0520.md @@ -1,5 +1,7 @@ A non-default implementation was already made on this type so it cannot be -specialized further. Erroneous code example: +specialized further. + +Erroneous code example: ```compile_fail,E0520 #![feature(specialization)] diff --git a/src/librustc_error_codes/error_codes/E0657.md b/src/librustc_error_codes/error_codes/E0657.md new file mode 100644 index 00000000000..7fe48c51147 --- /dev/null +++ b/src/librustc_error_codes/error_codes/E0657.md @@ -0,0 +1,57 @@ +A lifetime bound on a trait implementation was captured at an incorrect place. + +Erroneous code example: + +```compile_fail,E0657 +trait Id<T> {} +trait Lt<'a> {} + +impl<'a> Lt<'a> for () {} +impl<T> Id<T> for T {} + +fn free_fn_capture_hrtb_in_impl_trait() + -> Box<for<'a> Id<impl Lt<'a>>> // error! +{ + Box::new(()) +} + +struct Foo; +impl Foo { + fn impl_fn_capture_hrtb_in_impl_trait() + -> Box<for<'a> Id<impl Lt<'a>>> // error! + { + Box::new(()) + } +} +``` + +Here, you have used the inappropriate lifetime in the `impl Trait`, +The `impl Trait` can only capture lifetimes bound at the fn or impl +level. + +To fix this we have to define the lifetime at the function or impl +level and use that lifetime in the `impl Trait`. For example you can +define the lifetime at the function: + +``` +trait Id<T> {} +trait Lt<'a> {} + +impl<'a> Lt<'a> for () {} +impl<T> Id<T> for T {} + +fn free_fn_capture_hrtb_in_impl_trait<'b>() + -> Box<for<'a> Id<impl Lt<'b>>> // ok! +{ + Box::new(()) +} + +struct Foo; +impl Foo { + fn impl_fn_capture_hrtb_in_impl_trait<'b>() + -> Box<for<'a> Id<impl Lt<'b>>> // ok! + { + Box::new(()) + } +} +``` diff --git a/src/librustc_error_codes/error_codes/E0708.md b/src/librustc_error_codes/error_codes/E0708.md new file mode 100644 index 00000000000..a0f53e38b53 --- /dev/null +++ b/src/librustc_error_codes/error_codes/E0708.md @@ -0,0 +1,26 @@ +`async` non-`move` closures with parameters are currently not supported. + +Erroneous code example: + +```compile_fail,edition2018 +#![feature(async_closure)] + +fn main() { + let add_one = async |num: u8| { // error! + num + 1 + }; +} +``` + +`async` with non-move is currently not supported with the current +version, you can use successfully by using move: + +```edition2018 +#![feature(async_closure)] + +fn main() { + let add_one = async move |num: u8| { // ok! + num + 1 + }; +} +``` diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 3f5738a93a9..0023ff595fc 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -2005,7 +2005,7 @@ fn emit_to_destination( let _buffer_lock = lock::acquire_global_lock("rustc_errors"); for (pos, line) in rendered_buffer.iter().enumerate() { for part in line { - dst.apply_style(lvl.clone(), part.style)?; + dst.apply_style(*lvl, part.style)?; write!(dst, "{}", part.text)?; dst.reset()?; } diff --git a/src/librustc_expand/config.rs b/src/librustc_expand/config.rs index 72c09f35dfa..d79dabb5092 100644 --- a/src/librustc_expand/config.rs +++ b/src/librustc_expand/config.rs @@ -4,9 +4,9 @@ use rustc_ast::ast::{self, AttrItem, Attribute, MetaItem}; use rustc_ast::attr::HasAttrs; use rustc_ast::mut_visit::*; use rustc_ast::ptr::P; -use rustc_ast::util::map_in_place::MapInPlace; use rustc_attr as attr; use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::map_in_place::MapInPlace; use rustc_errors::{error_code, struct_span_err, Applicability, Handler}; use rustc_feature::{Feature, Features, State as FeatureState}; use rustc_feature::{ diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs index 51208906c2f..2618c758ca5 100644 --- a/src/librustc_expand/expand.rs +++ b/src/librustc_expand/expand.rs @@ -13,10 +13,10 @@ use rustc_ast::mut_visit::*; use rustc_ast::ptr::P; use rustc_ast::token; use rustc_ast::tokenstream::TokenStream; -use rustc_ast::util::map_in_place::MapInPlace; use rustc_ast::visit::{self, AssocCtxt, Visitor}; use rustc_ast_pretty::pprust; use rustc_attr::{self as attr, is_builtin_attr, HasAttrs}; +use rustc_data_structures::map_in_place::MapInPlace; use rustc_errors::{Applicability, PResult}; use rustc_feature::Features; use rustc_parse::parser::Parser; @@ -507,9 +507,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { expanded_fragments.push(Vec::new()); } expanded_fragments[depth - 1].push((expn_id, expanded_fragment)); - if !self.cx.ecfg.single_step { - invocations.extend(new_invocations.into_iter().rev()); - } + invocations.extend(new_invocations.into_iter().rev()); } self.cx.current_expansion = orig_expansion_data; @@ -1819,7 +1817,6 @@ pub struct ExpansionConfig<'feat> { pub recursion_limit: usize, pub trace_mac: bool, pub should_test: bool, // If false, strip `#[test]` nodes - pub single_step: bool, pub keep_macs: bool, } @@ -1831,7 +1828,6 @@ impl<'feat> ExpansionConfig<'feat> { recursion_limit: 1024, trace_mac: false, should_test: false, - single_step: false, keep_macs: false, } } diff --git a/src/librustc_hir/definitions.rs b/src/librustc_hir/definitions.rs index 58f34787613..1ac23677d47 100644 --- a/src/librustc_hir/definitions.rs +++ b/src/librustc_hir/definitions.rs @@ -7,7 +7,6 @@ pub use crate::def_id::DefPathHash; use crate::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use crate::hir; -use crate::hir_id::DUMMY_HIR_ID; use rustc_ast::ast; use rustc_ast::crate_disambiguator::CrateDisambiguator; @@ -87,7 +86,7 @@ pub struct Definitions { node_id_to_def_id: FxHashMap<ast::NodeId, LocalDefId>, def_id_to_node_id: IndexVec<LocalDefId, ast::NodeId>, - pub(super) node_id_to_hir_id: IndexVec<ast::NodeId, hir::HirId>, + pub(super) node_id_to_hir_id: IndexVec<ast::NodeId, Option<hir::HirId>>, /// The reverse mapping of `node_id_to_hir_id`. pub(super) hir_id_to_node_id: FxHashMap<hir::HirId, ast::NodeId>, @@ -345,8 +344,7 @@ impl Definitions { #[inline] pub fn as_local_hir_id(&self, def_id: DefId) -> Option<hir::HirId> { if let Some(def_id) = def_id.as_local() { - let hir_id = self.local_def_id_to_hir_id(def_id); - if hir_id != DUMMY_HIR_ID { Some(hir_id) } else { None } + Some(self.local_def_id_to_hir_id(def_id)) } else { None } @@ -359,12 +357,23 @@ impl Definitions { #[inline] pub fn node_id_to_hir_id(&self, node_id: ast::NodeId) -> hir::HirId { + self.node_id_to_hir_id[node_id].unwrap() + } + + #[inline] + pub fn opt_node_id_to_hir_id(&self, node_id: ast::NodeId) -> Option<hir::HirId> { self.node_id_to_hir_id[node_id] } #[inline] pub fn local_def_id_to_hir_id(&self, id: LocalDefId) -> hir::HirId { let node_id = self.def_id_to_node_id[id]; + self.node_id_to_hir_id[node_id].unwrap() + } + + #[inline] + pub fn opt_local_def_id_to_hir_id(&self, id: LocalDefId) -> Option<hir::HirId> { + let node_id = self.def_id_to_node_id[id]; self.node_id_to_hir_id[node_id] } @@ -470,7 +479,10 @@ impl Definitions { /// Initializes the `ast::NodeId` to `HirId` mapping once it has been generated during /// AST to HIR lowering. - pub fn init_node_id_to_hir_id_mapping(&mut self, mapping: IndexVec<ast::NodeId, hir::HirId>) { + pub fn init_node_id_to_hir_id_mapping( + &mut self, + mapping: IndexVec<ast::NodeId, Option<hir::HirId>>, + ) { assert!( self.node_id_to_hir_id.is_empty(), "trying to initialize `NodeId` -> `HirId` mapping twice" @@ -481,7 +493,7 @@ impl Definitions { self.hir_id_to_node_id = self .node_id_to_hir_id .iter_enumerated() - .map(|(node_id, &hir_id)| (hir_id, node_id)) + .filter_map(|(node_id, &hir_id)| hir_id.map(|hir_id| (hir_id, node_id))) .collect(); } diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs index b719d576d6f..b66e6101b50 100644 --- a/src/librustc_hir/hir.rs +++ b/src/librustc_hir/hir.rs @@ -1736,15 +1736,24 @@ pub struct Destination { #[derive(Copy, Clone, PartialEq, Eq, Debug, RustcEncodable, RustcDecodable, HashStable_Generic)] pub enum YieldSource { /// An `<expr>.await`. - Await, + Await { expr: Option<HirId> }, /// A plain `yield`. Yield, } +impl YieldSource { + pub fn is_await(&self) -> bool { + match self { + YieldSource::Await { .. } => true, + YieldSource::Yield => false, + } + } +} + impl fmt::Display for YieldSource { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(match self { - YieldSource::Await => "`await`", + YieldSource::Await { .. } => "`await`", YieldSource::Yield => "`yield`", }) } @@ -1755,7 +1764,7 @@ impl From<GeneratorKind> for YieldSource { match kind { // Guess based on the kind of the current generator. GeneratorKind::Gen => Self::Yield, - GeneratorKind::Async(_) => Self::Await, + GeneratorKind::Async(_) => Self::Await { expr: None }, } } } @@ -2515,7 +2524,7 @@ pub struct ImplItemRef<'hir> { #[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] pub enum AssocItemKind { Const, - Method { has_self: bool }, + Fn { has_self: bool }, Type, OpaqueTy, } diff --git a/src/librustc_hir/hir_id.rs b/src/librustc_hir/hir_id.rs index 1c7987e965f..d782c3dd70a 100644 --- a/src/librustc_hir/hir_id.rs +++ b/src/librustc_hir/hir_id.rs @@ -45,7 +45,4 @@ pub const CRATE_HIR_ID: HirId = HirId { local_id: ItemLocalId::from_u32(0), }; -pub const DUMMY_HIR_ID: HirId = - HirId { owner: LocalDefId { local_def_index: CRATE_DEF_INDEX }, local_id: DUMMY_ITEM_LOCAL_ID }; - pub const DUMMY_ITEM_LOCAL_ID: ItemLocalId = ItemLocalId::MAX; diff --git a/src/librustc_hir/lang_items.rs b/src/librustc_hir/lang_items.rs index 5a3a9cabeb4..53f72804a84 100644 --- a/src/librustc_hir/lang_items.rs +++ b/src/librustc_hir/lang_items.rs @@ -135,6 +135,8 @@ language_item_table! { SliceU8AllocImplItem, "slice_u8_alloc", slice_u8_alloc_impl, Target::Impl; ConstPtrImplItem, "const_ptr", const_ptr_impl, Target::Impl; MutPtrImplItem, "mut_ptr", mut_ptr_impl, Target::Impl; + ConstSlicePtrImplItem, "const_slice_ptr", const_slice_ptr_impl, Target::Impl; + MutSlicePtrImplItem, "mut_slice_ptr", mut_slice_ptr_impl, Target::Impl; I8ImplItem, "i8", i8_impl, Target::Impl; I16ImplItem, "i16", i16_impl, Target::Impl; I32ImplItem, "i32", i32_impl, Target::Impl; diff --git a/src/librustc_infer/infer/error_reporting/mod.rs b/src/librustc_infer/infer/error_reporting/mod.rs index db81ceea43f..3711d848d81 100644 --- a/src/librustc_infer/infer/error_reporting/mod.rs +++ b/src/librustc_infer/infer/error_reporting/mod.rs @@ -191,7 +191,7 @@ fn msg_span_from_early_bound_and_free_regions( let sm = tcx.sess.source_map(); let scope = region.free_region_binding_scope(tcx); - let node = tcx.hir().as_local_hir_id(scope).unwrap_or(hir::DUMMY_HIR_ID); + let node = tcx.hir().as_local_hir_id(scope).unwrap(); let tag = match tcx.hir().find(node) { Some(Node::Block(_)) | Some(Node::Expr(_)) => "body", Some(Node::Item(it)) => item_scope_tag(&it), @@ -304,8 +304,8 @@ pub fn unexpected_hidden_region_diagnostic( // down this path which gives a decent human readable // explanation. // - // (*) if not, the `tainted_by_errors` flag would be set to - // true in any case, so we wouldn't be here at all. + // (*) if not, the `tainted_by_errors` field would be set to + // `Some(ErrorReported)` in any case, so we wouldn't be here at all. note_and_explain_free_region( tcx, &mut err, @@ -871,7 +871,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { return Some(()); } if let &ty::Adt(def, _) = &ta.kind { - let path_ = self.tcx.def_path_str(def.did.clone()); + let path_ = self.tcx.def_path_str(def.did); if path_ == other_path { self.highlight_outer(&mut t1_out, &mut t2_out, path, sub, i, &other_ty); return Some(()); @@ -1091,8 +1091,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let sub_no_defaults_1 = self.strip_generic_default_params(def1.did, sub1); let sub_no_defaults_2 = self.strip_generic_default_params(def2.did, sub2); let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new()); - let path1 = self.tcx.def_path_str(def1.did.clone()); - let path2 = self.tcx.def_path_str(def2.did.clone()); + let path1 = self.tcx.def_path_str(def1.did); + let path2 = self.tcx.def_path_str(def2.did); if def1.did == def2.did { // Easy case. Replace same types with `_` to shorten the output and highlight // the differing ones. diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/util.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/util.rs index d35a589320b..7bbd2127bcf 100644 --- a/src/librustc_infer/infer/error_reporting/nice_region_error/util.rs +++ b/src/librustc_infer/infer/error_reporting/nice_region_error/util.rs @@ -118,7 +118,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { // enable E0621 for it. pub(super) fn is_self_anon(&self, is_first: bool, scope_def_id: DefId) -> bool { is_first - && self.tcx().opt_associated_item(scope_def_id).map(|i| i.method_has_self_argument) + && self.tcx().opt_associated_item(scope_def_id).map(|i| i.fn_has_self_parameter) == Some(true) } } diff --git a/src/librustc_infer/infer/freshen.rs b/src/librustc_infer/infer/freshen.rs index eeaa4c1661e..a95d276f4a8 100644 --- a/src/librustc_infer/infer/freshen.rs +++ b/src/librustc_infer/infer/freshen.rs @@ -251,7 +251,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> { bug!("unexpected const {:?}", ct) } - ty::ConstKind::Param(_) | ty::ConstKind::Value(_) | ty::ConstKind::Unevaluated(..) => {} + ty::ConstKind::Param(_) + | ty::ConstKind::Value(_) + | ty::ConstKind::Unevaluated(..) + | ty::ConstKind::Error => {} } ct.super_fold_with(self) diff --git a/src/librustc_infer/infer/outlives/obligations.rs b/src/librustc_infer/infer/outlives/obligations.rs index e6feb5e1edc..c904926e9d9 100644 --- a/src/librustc_infer/infer/outlives/obligations.rs +++ b/src/librustc_infer/infer/outlives/obligations.rs @@ -452,7 +452,7 @@ where // even though a satisfactory solution exists. let generic = GenericKind::Projection(projection_ty); let verify_bound = self.verify_bound.generic_bound(generic); - self.delegate.push_verify(origin, generic.clone(), region, verify_bound); + self.delegate.push_verify(origin, generic, region, verify_bound); } } diff --git a/src/librustc_infer/infer/outlives/verify.rs b/src/librustc_infer/infer/outlives/verify.rs index 5b6db324e6c..1a601d723cb 100644 --- a/src/librustc_infer/infer/outlives/verify.rs +++ b/src/librustc_infer/infer/outlives/verify.rs @@ -42,6 +42,31 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { match ty.kind { ty::Param(p) => self.param_bound(p), ty::Projection(data) => self.projection_bound(data), + ty::FnDef(_, substs) => { + // HACK(eddyb) ignore lifetimes found shallowly in `substs`. + // This is inconsistent with `ty::Adt` (including all substs), + // but consistent with previous (accidental) behavior. + // See https://github.com/rust-lang/rust/issues/70917 + // for further background and discussion. + let mut bounds = substs + .iter() + .filter_map(|&child| match child.unpack() { + GenericArgKind::Type(ty) => Some(self.type_bound(ty)), + GenericArgKind::Lifetime(_) => None, + GenericArgKind::Const(_) => Some(self.recursive_bound(child)), + }) + .filter(|bound| { + // Remove bounds that must hold, since they are not interesting. + !bound.must_hold() + }); + + match (bounds.next(), bounds.next()) { + (Some(first), None) => first, + (first, second) => VerifyBound::AllBounds( + first.into_iter().chain(second).chain(bounds).collect(), + ), + } + } _ => self.recursive_bound(ty.into()), } } @@ -297,7 +322,6 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { self.collect_outlives_from_predicate_list( move |ty| ty == identity_proj, traits::elaborate_predicates(tcx, trait_predicates) - .into_iter() .map(|o| o.predicate) .collect::<Vec<_>>(), ) diff --git a/src/librustc_infer/infer/resolve.rs b/src/librustc_infer/infer/resolve.rs index b908b75a257..bd9d108cfe8 100644 --- a/src/librustc_infer/infer/resolve.rs +++ b/src/librustc_infer/infer/resolve.rs @@ -227,7 +227,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> { match c.val { ty::ConstKind::Infer(InferConst::Var(vid)) => { self.err = Some(FixupError::UnresolvedConst(vid)); - return self.tcx().consts.err; + return self.tcx().mk_const(ty::Const { val: ty::ConstKind::Error, ty: c.ty }); } ty::ConstKind::Infer(InferConst::Fresh(_)) => { bug!("Unexpected const in full const resolver: {:?}", c); diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 910d53880f2..627a438c2c3 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1354,7 +1354,7 @@ declare_lint! { } pub struct UnnameableTestItems { - boundary: hir::HirId, // HirId of the item under which things are not nameable + boundary: Option<hir::HirId>, // HirId of the item under which things are not nameable items_nameable: bool, } @@ -1362,7 +1362,7 @@ impl_lint_pass!(UnnameableTestItems => [UNNAMEABLE_TEST_ITEMS]); impl UnnameableTestItems { pub fn new() -> Self { - Self { boundary: hir::DUMMY_HIR_ID, items_nameable: true } + Self { boundary: None, items_nameable: true } } } @@ -1372,7 +1372,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnameableTestItems { if let hir::ItemKind::Mod(..) = it.kind { } else { self.items_nameable = false; - self.boundary = it.hir_id; + self.boundary = Some(it.hir_id); } return; } @@ -1385,7 +1385,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnameableTestItems { } fn check_item_post(&mut self, _cx: &LateContext<'_, '_>, it: &hir::Item<'_>) { - if !self.items_nameable && self.boundary == it.hir_id { + if !self.items_nameable && self.boundary == Some(it.hir_id) { self.items_nameable = true; } } diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index aa805a2f2db..ee2ed8826ba 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -43,14 +43,14 @@ declare_lint! { #[derive(Copy, Clone)] pub struct TypeLimits { /// Id of the last visited negated expression - negated_expr_id: hir::HirId, + negated_expr_id: Option<hir::HirId>, } impl_lint_pass!(TypeLimits => [UNUSED_COMPARISONS, OVERFLOWING_LITERALS]); impl TypeLimits { pub fn new() -> TypeLimits { - TypeLimits { negated_expr_id: hir::DUMMY_HIR_ID } + TypeLimits { negated_expr_id: None } } } @@ -244,7 +244,7 @@ fn lint_int_literal<'a, 'tcx>( let int_type = t.normalize(cx.sess().target.ptr_width); let (min, max) = int_ty_range(int_type); let max = max as u128; - let negative = type_limits.negated_expr_id == e.hir_id; + let negative = type_limits.negated_expr_id == Some(e.hir_id); // Detect literal value out of range [min, max] inclusive // avoiding use of -min to prevent overflow/panic @@ -397,8 +397,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { match e.kind { hir::ExprKind::Unary(hir::UnOp::UnNeg, ref expr) => { // propagate negation, if the negation itself isn't negated - if self.negated_expr_id != e.hir_id { - self.negated_expr_id = expr.hir_id; + if self.negated_expr_id != Some(e.hir_id) { + self.negated_expr_id = Some(expr.hir_id); } } hir::ExprKind::Binary(binop, ref l, ref r) => { diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index aa7c87e9f7b..3e1e9cc70aa 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -384,7 +384,7 @@ trait UnusedDelimLint { fn is_expr_delims_necessary(inner: &ast::Expr, followed_by_block: bool) -> bool { followed_by_block && match inner.kind { - ast::ExprKind::Ret(_) | ast::ExprKind::Break(..) => true, + ExprKind::Ret(_) | ExprKind::Break(..) => true, _ => parser::contains_exterior_struct_lit(&inner), } } diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 3e5d7b8efd5..fe8fbd50627 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -686,7 +686,9 @@ impl<'a> CrateLoader<'a> { } fn inject_profiler_runtime(&mut self) { - if self.sess.opts.debugging_opts.profile || self.sess.opts.cg.profile_generate.enabled() { + if (self.sess.opts.debugging_opts.profile || self.sess.opts.cg.profile_generate.enabled()) + && !self.sess.opts.debugging_opts.no_profiler_runtime + { info!("loading profiler"); let name = Symbol::intern("profiler_builtins"); diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs index 078f9251adf..ef6f37c5dab 100644 --- a/src/librustc_metadata/rmeta/decoder.rs +++ b/src/librustc_metadata/rmeta/decoder.rs @@ -1153,7 +1153,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { EntryKind::AssocConst(container, _, _) => (ty::AssocKind::Const, container, false), EntryKind::AssocFn(data) => { let data = data.decode(self); - (ty::AssocKind::Method, data.container, data.has_self) + (ty::AssocKind::Fn, data.container, data.has_self) } EntryKind::AssocType(container) => (ty::AssocKind::Type, container, false), EntryKind::AssocOpaqueTy(container) => (ty::AssocKind::OpaqueTy, container, false), @@ -1167,7 +1167,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { defaultness: container.defaultness(), def_id: self.local_def_id(id), container: container.with_def_id(parent), - method_has_self_argument: has_self, + fn_has_self_parameter: has_self, } } diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs index d75298fae00..9c9869c8557 100644 --- a/src/librustc_metadata/rmeta/encoder.rs +++ b/src/librustc_metadata/rmeta/encoder.rs @@ -839,7 +839,7 @@ impl EncodeContext<'tcx> { rendered_const, ) } - ty::AssocKind::Method => { + ty::AssocKind::Fn => { let fn_data = if let hir::TraitItemKind::Fn(m_sig, m) = &ast_item.kind { let param_names = match *m { hir::TraitFn::Required(ref names) => { @@ -860,7 +860,7 @@ impl EncodeContext<'tcx> { EntryKind::AssocFn(self.lazy(AssocFnData { fn_data, container, - has_self: trait_item.method_has_self_argument, + has_self: trait_item.fn_has_self_parameter, })) } ty::AssocKind::Type => EntryKind::AssocType(container), @@ -874,7 +874,7 @@ impl EncodeContext<'tcx> { self.encode_const_stability(def_id); self.encode_deprecation(def_id); match trait_item.kind { - ty::AssocKind::Const | ty::AssocKind::Method => { + ty::AssocKind::Const | ty::AssocKind::Fn => { self.encode_item_type(def_id); } ty::AssocKind::Type => { @@ -884,7 +884,7 @@ impl EncodeContext<'tcx> { } ty::AssocKind::OpaqueTy => unreachable!(), } - if trait_item.kind == ty::AssocKind::Method { + if trait_item.kind == ty::AssocKind::Fn { record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); self.encode_variances_of(def_id); } @@ -931,7 +931,7 @@ impl EncodeContext<'tcx> { bug!() } } - ty::AssocKind::Method => { + ty::AssocKind::Fn => { let fn_data = if let hir::ImplItemKind::Fn(ref sig, body) = ast_item.kind { FnData { asyncness: sig.header.asyncness, @@ -944,7 +944,7 @@ impl EncodeContext<'tcx> { EntryKind::AssocFn(self.lazy(AssocFnData { fn_data, container, - has_self: impl_item.method_has_self_argument, + has_self: impl_item.fn_has_self_parameter, })) } ty::AssocKind::OpaqueTy => EntryKind::AssocOpaqueTy(container), @@ -958,7 +958,7 @@ impl EncodeContext<'tcx> { self.encode_const_stability(def_id); self.encode_deprecation(def_id); self.encode_item_type(def_id); - if impl_item.kind == ty::AssocKind::Method { + if impl_item.kind == ty::AssocKind::Fn { record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); self.encode_variances_of(def_id); } diff --git a/src/librustc_middle/hir/map/collector.rs b/src/librustc_middle/hir/map/collector.rs index 70ea856498d..2906da437ab 100644 --- a/src/librustc_middle/hir/map/collector.rs +++ b/src/librustc_middle/hir/map/collector.rs @@ -250,23 +250,16 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { None => format!("{:?}", node), }; - let forgot_str = if hir_id == hir::DUMMY_HIR_ID { - format!("\nMaybe you forgot to lower the node id {:?}?", node_id) - } else { - String::new() - }; - span_bug!( span, "inconsistent DepNode at `{:?}` for `{}`: \ - current_dep_node_owner={} ({:?}), hir_id.owner={} ({:?}){}", + current_dep_node_owner={} ({:?}), hir_id.owner={} ({:?})", self.source_map.span_to_string(span), node_str, self.definitions.def_path(self.current_dep_node_owner).to_string_no_crate(), self.current_dep_node_owner, self.definitions.def_path(hir_id.owner).to_string_no_crate(), hir_id.owner, - forgot_str, ) } } diff --git a/src/librustc_middle/hir/map/mod.rs b/src/librustc_middle/hir/map/mod.rs index 3eaacb54d5b..ead8529fad8 100644 --- a/src/librustc_middle/hir/map/mod.rs +++ b/src/librustc_middle/hir/map/mod.rs @@ -215,10 +215,20 @@ impl<'hir> Map<'hir> { } #[inline] + pub fn opt_node_id_to_hir_id(&self, node_id: NodeId) -> Option<HirId> { + self.tcx.definitions.opt_node_id_to_hir_id(node_id) + } + + #[inline] pub fn local_def_id_to_hir_id(&self, def_id: LocalDefId) -> HirId { self.tcx.definitions.local_def_id_to_hir_id(def_id) } + #[inline] + pub fn opt_local_def_id_to_hir_id(&self, def_id: LocalDefId) -> Option<HirId> { + self.tcx.definitions.opt_local_def_id_to_hir_id(def_id) + } + pub fn def_kind(&self, hir_id: HirId) -> Option<DefKind> { let node = self.find(hir_id)?; diff --git a/src/librustc_middle/middle/stability.rs b/src/librustc_middle/middle/stability.rs index 46525bdedad..1dd14b7c4ff 100644 --- a/src/librustc_middle/middle/stability.rs +++ b/src/librustc_middle/middle/stability.rs @@ -215,7 +215,6 @@ fn late_report_deprecation( suggestion: Option<Symbol>, lint: &'static Lint, span: Span, - def_id: DefId, hir_id: HirId, ) { if span.in_derive_expansion() { @@ -229,9 +228,6 @@ fn late_report_deprecation( } diag.emit() }); - if hir_id == hir::DUMMY_HIR_ID { - span_bug!(span, "emitted a {} lint with dummy HIR id: {:?}", lint.name, def_id); - } } /// Result of `TyCtxt::eval_stability`. @@ -296,7 +292,7 @@ impl<'tcx> TyCtxt<'tcx> { if !skip { let (message, lint) = deprecation_message(&depr_entry.attr, &self.def_path_str(def_id)); - late_report_deprecation(self, &message, None, lint, span, def_id, id); + late_report_deprecation(self, &message, None, lint, span, id); } }; } @@ -319,15 +315,7 @@ impl<'tcx> TyCtxt<'tcx> { if let Some(depr) = &stability.rustc_depr { let (message, lint) = rustc_deprecation_message(depr, &self.def_path_str(def_id)); - late_report_deprecation( - self, - &message, - depr.suggestion, - lint, - span, - def_id, - id, - ); + late_report_deprecation(self, &message, depr.suggestion, lint, span, id); } } } diff --git a/src/librustc_middle/mir/interpret/error.rs b/src/librustc_middle/mir/interpret/error.rs index 7844fb10840..c56dc5196c6 100644 --- a/src/librustc_middle/mir/interpret/error.rs +++ b/src/librustc_middle/mir/interpret/error.rs @@ -8,7 +8,7 @@ use crate::ty::{self, layout, Ty}; use backtrace::Backtrace; use rustc_data_structures::sync::Lock; -use rustc_errors::{struct_span_err, DiagnosticBuilder}; +use rustc_errors::{struct_span_err, DiagnosticBuilder, ErrorReported}; use rustc_hir as hir; use rustc_hir::definitions::DefPathData; use rustc_macros::HashStable; @@ -19,25 +19,16 @@ use std::{any::Any, fmt, mem}; #[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, RustcEncodable, RustcDecodable)] pub enum ErrorHandled { - /// Already reported a lint or an error for this evaluation. - Reported, + /// Already reported an error for this evaluation, and the compilation is + /// *guaranteed* to fail. Warnings/lints *must not* produce `Reported`. + Reported(ErrorReported), + /// Already emitted a lint for this evaluation. + Linted, /// Don't emit an error, the evaluation failed because the MIR was generic /// and the substs didn't fully monomorphize it. TooGeneric, } -impl ErrorHandled { - pub fn assert_reported(self) { - match self { - ErrorHandled::Reported => {} - ErrorHandled::TooGeneric => bug!( - "MIR interpretation failed without reporting an error \ - even though it was fully monomorphized" - ), - } - } -} - CloneTypeFoldableImpls! { ErrorHandled, } @@ -84,15 +75,12 @@ impl<'tcx> ConstEvalErr<'tcx> { tcx: TyCtxtAt<'tcx>, message: &str, emit: impl FnOnce(DiagnosticBuilder<'_>), - ) -> Result<(), ErrorHandled> { + ) -> ErrorHandled { self.struct_generic(tcx, message, emit, None) } pub fn report_as_error(&self, tcx: TyCtxtAt<'tcx>, message: &str) -> ErrorHandled { - match self.struct_error(tcx, message, |mut e| e.emit()) { - Ok(_) => ErrorHandled::Reported, - Err(x) => x, - } + self.struct_error(tcx, message, |mut e| e.emit()) } pub fn report_as_lint( @@ -102,7 +90,7 @@ impl<'tcx> ConstEvalErr<'tcx> { lint_root: hir::HirId, span: Option<Span>, ) -> ErrorHandled { - match self.struct_generic( + self.struct_generic( tcx, message, |mut lint: DiagnosticBuilder<'_>| { @@ -122,10 +110,7 @@ impl<'tcx> ConstEvalErr<'tcx> { lint.emit(); }, Some(lint_root), - ) { - Ok(_) => ErrorHandled::Reported, - Err(err) => err, - } + ) } /// Create a diagnostic for this const eval error. @@ -143,12 +128,14 @@ impl<'tcx> ConstEvalErr<'tcx> { message: &str, emit: impl FnOnce(DiagnosticBuilder<'_>), lint_root: Option<hir::HirId>, - ) -> Result<(), ErrorHandled> { + ) -> ErrorHandled { let must_error = match self.error { err_inval!(Layout(LayoutError::Unknown(_))) | err_inval!(TooGeneric) => { - return Err(ErrorHandled::TooGeneric); + return ErrorHandled::TooGeneric; + } + err_inval!(TypeckError(error_reported)) => { + return ErrorHandled::Reported(error_reported); } - err_inval!(TypeckError) => return Err(ErrorHandled::Reported), // We must *always* hard error on these, even if the caller wants just a lint. err_inval!(Layout(LayoutError::SizeOverflow(_))) => true, _ => false, @@ -183,6 +170,7 @@ impl<'tcx> ConstEvalErr<'tcx> { // caller thinks anyway. // See <https://github.com/rust-lang/rust/pull/63152>. finish(struct_error(tcx, &err_msg), None); + ErrorHandled::Reported(ErrorReported) } else { // Regular case. if let Some(lint_root) = lint_root { @@ -200,12 +188,13 @@ impl<'tcx> ConstEvalErr<'tcx> { tcx.span, |lint| finish(lint.build(message), Some(err_msg)), ); + ErrorHandled::Linted } else { // Report as hard error. finish(struct_error(tcx, message), Some(err_msg)); + ErrorHandled::Reported(ErrorReported) } } - Ok(()) } } @@ -246,7 +235,9 @@ fn print_backtrace(backtrace: &mut Backtrace) { impl From<ErrorHandled> for InterpErrorInfo<'_> { fn from(err: ErrorHandled) -> Self { match err { - ErrorHandled::Reported => err_inval!(ReferencedConstant), + ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted => { + err_inval!(ReferencedConstant) + } ErrorHandled::TooGeneric => err_inval!(TooGeneric), } .into() @@ -288,7 +279,7 @@ pub enum InvalidProgramInfo<'tcx> { /// which already produced an error. ReferencedConstant, /// Abort in case type errors are reached. - TypeckError, + TypeckError(ErrorReported), /// An error occurred during layout computation. Layout(layout::LayoutError<'tcx>), /// An invalid transmute happened. @@ -301,11 +292,13 @@ impl fmt::Debug for InvalidProgramInfo<'_> { match self { TooGeneric => write!(f, "encountered overly generic constant"), ReferencedConstant => write!(f, "referenced constant has errors"), - TypeckError => write!(f, "encountered constants with type errors, stopping evaluation"), + TypeckError(ErrorReported) => { + write!(f, "encountered constants with type errors, stopping evaluation") + } Layout(ref err) => write!(f, "{}", err), TransmuteSizeDiff(from_ty, to_ty) => write!( f, - "tried to transmute from {:?} to {:?}, but their sizes differed", + "transmuting `{}` to `{}` is not possible, because these types do not have the same size", from_ty, to_ty ), } @@ -431,7 +424,7 @@ impl fmt::Debug for UndefinedBehaviorInfo { "using uninitialized data, but this operation requires initialized memory" ), DeadLocal => write!(f, "accessing a dead local variable"), - ReadFromReturnPlace => write!(f, "tried to read from the return place"), + ReadFromReturnPlace => write!(f, "reading from return place"), } } } @@ -462,9 +455,9 @@ impl fmt::Debug for UnsupportedOpInfo { match self { Unsupported(ref msg) => write!(f, "{}", msg), ReadForeignStatic(did) => { - write!(f, "tried to read from foreign (extern) static {:?}", did) + write!(f, "cannot read from foreign (extern) static {:?}", did) } - NoMirFor(did) => write!(f, "could not load MIR for {:?}", did), + NoMirFor(did) => write!(f, "no MIR body is available for {:?}", did), ReadPointerAsBytes => write!(f, "unable to turn pointer into raw bytes",), ReadBytesAsPointer => write!(f, "unable to turn bytes into a pointer"), } diff --git a/src/librustc_middle/mir/mod.rs b/src/librustc_middle/mir/mod.rs index 212061cfd82..4063d290993 100644 --- a/src/librustc_middle/mir/mod.rs +++ b/src/librustc_middle/mir/mod.rs @@ -2611,14 +2611,14 @@ impl<'a, 'b> graph::GraphSuccessors<'b> for Body<'a> { type Iter = iter::Cloned<Successors<'b>>; } +/// `Location` represents the position of the start of the statement; or, if +/// `statement_index` equals the number of statements, then the start of the +/// terminator. #[derive(Copy, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, HashStable)] pub struct Location { /// The block that the location is within. pub block: BasicBlock, - /// The location is the position of the start of the statement; or, if - /// `statement_index` equals the number of statements, then the start of the - /// terminator. pub statement_index: usize, } diff --git a/src/librustc_middle/traits/specialization_graph.rs b/src/librustc_middle/traits/specialization_graph.rs index a2793f98050..bc743666e4a 100644 --- a/src/librustc_middle/traits/specialization_graph.rs +++ b/src/librustc_middle/traits/specialization_graph.rs @@ -107,13 +107,13 @@ impl<'tcx> Node { .find(move |impl_item| { match (trait_item_kind, impl_item.kind) { | (Const, Const) - | (Method, Method) + | (Fn, Fn) | (Type, Type) | (Type, OpaqueTy) // assoc. types can be made opaque in impls => tcx.hygienic_eq(impl_item.ident, trait_item_name, trait_def_id), | (Const, _) - | (Method, _) + | (Fn, _) | (Type, _) | (OpaqueTy, _) => false, diff --git a/src/librustc_middle/ty/adjustment.rs b/src/librustc_middle/ty/adjustment.rs index 851bffc2065..efd5adeba8c 100644 --- a/src/librustc_middle/ty/adjustment.rs +++ b/src/librustc_middle/ty/adjustment.rs @@ -123,7 +123,7 @@ impl<'tcx> OverloadedDeref<'tcx> { let method_def_id = tcx .associated_items(trait_def_id.unwrap()) .in_definition_order() - .find(|m| m.kind == ty::AssocKind::Method) + .find(|m| m.kind == ty::AssocKind::Fn) .unwrap() .def_id; (method_def_id, tcx.mk_substs_trait(source, &[])) diff --git a/src/librustc_middle/ty/context.rs b/src/librustc_middle/ty/context.rs index 9fa25a43637..3eec58251a0 100644 --- a/src/librustc_middle/ty/context.rs +++ b/src/librustc_middle/ty/context.rs @@ -182,7 +182,7 @@ pub struct CommonLifetimes<'tcx> { } pub struct CommonConsts<'tcx> { - pub err: &'tcx Const<'tcx>, + pub unit: &'tcx Const<'tcx>, } pub struct LocalTableInContext<'a, V> { @@ -410,8 +410,8 @@ pub struct TypeckTables<'tcx> { pub used_trait_imports: Lrc<DefIdSet>, /// If any errors occurred while type-checking this body, - /// this field will be set to `true`. - pub tainted_by_errors: bool, + /// this field will be set to `Some(ErrorReported)`. + pub tainted_by_errors: Option<ErrorReported>, /// All the opaque types that are restricted to concrete types /// by this function. @@ -447,7 +447,7 @@ impl<'tcx> TypeckTables<'tcx> { fru_field_types: Default::default(), coercion_casts: Default::default(), used_trait_imports: Lrc::new(Default::default()), - tainted_by_errors: false, + tainted_by_errors: None, concrete_opaque_types: Default::default(), upvar_list: Default::default(), generator_interior_types: Default::default(), @@ -858,9 +858,9 @@ impl<'tcx> CommonConsts<'tcx> { let mk_const = |c| interners.const_.intern(c, |c| Interned(interners.arena.alloc(c))).0; CommonConsts { - err: mk_const(ty::Const { + unit: mk_const(ty::Const { val: ty::ConstKind::Value(ConstValue::Scalar(Scalar::zst())), - ty: types.err, + ty: types.unit, }), } } @@ -1126,13 +1126,16 @@ impl<'tcx> TyCtxt<'tcx> { let mut trait_map: FxHashMap<_, FxHashMap<_, _>> = FxHashMap::default(); for (k, v) in resolutions.trait_map { - let hir_id = definitions.node_id_to_hir_id(k); - let map = trait_map.entry(hir_id.owner).or_default(); - let v = v - .into_iter() - .map(|tc| tc.map_import_ids(|id| definitions.node_id_to_hir_id(id))) - .collect(); - map.insert(hir_id.local_id, StableVec::new(v)); + // FIXME(#71104) Should really be using just `node_id_to_hir_id` but + // some `NodeId` do not seem to have a corresponding HirId. + if let Some(hir_id) = definitions.opt_node_id_to_hir_id(k) { + let map = trait_map.entry(hir_id.owner).or_default(); + let v = v + .into_iter() + .map(|tc| tc.map_import_ids(|id| definitions.node_id_to_hir_id(id))) + .collect(); + map.insert(hir_id.local_id, StableVec::new(v)); + } } GlobalCtxt { diff --git a/src/librustc_middle/ty/flags.rs b/src/librustc_middle/ty/flags.rs index 172f6d4608b..a88f3628109 100644 --- a/src/librustc_middle/ty/flags.rs +++ b/src/librustc_middle/ty/flags.rs @@ -70,14 +70,7 @@ impl FlagComputation { | &ty::Str | &ty::Foreign(..) => {} - // You might think that we could just return Error for - // any type containing Error as a component, and get - // rid of the TypeFlags::HAS_TY_ERR flag -- likewise for ty_bot (with - // the exception of function types that return bot). - // But doing so caused sporadic memory corruption, and - // neither I (tjc) nor nmatsakis could figure out why, - // so we're doing it this way. - &ty::Error => self.add_flags(TypeFlags::HAS_TY_ERR), + &ty::Error => self.add_flags(TypeFlags::HAS_ERROR), &ty::Param(_) => { self.add_flags(TypeFlags::HAS_TY_PARAM); @@ -239,6 +232,7 @@ impl FlagComputation { self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE); } ty::ConstKind::Value(_) => {} + ty::ConstKind::Error => self.add_flags(TypeFlags::HAS_ERROR), } } diff --git a/src/librustc_middle/ty/fold.rs b/src/librustc_middle/ty/fold.rs index d144e507691..248dd00ef47 100644 --- a/src/librustc_middle/ty/fold.rs +++ b/src/librustc_middle/ty/fold.rs @@ -82,7 +82,7 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone { self.has_type_flags(TypeFlags::HAS_TY_OPAQUE) } fn references_error(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_TY_ERR) + self.has_type_flags(TypeFlags::HAS_ERROR) } fn has_param_types_or_consts(&self) -> bool { self.has_type_flags(TypeFlags::HAS_TY_PARAM | TypeFlags::HAS_CT_PARAM) diff --git a/src/librustc_middle/ty/instance.rs b/src/librustc_middle/ty/instance.rs index 894f9070ce1..ca76cfb1492 100644 --- a/src/librustc_middle/ty/instance.rs +++ b/src/librustc_middle/ty/instance.rs @@ -366,7 +366,7 @@ impl<'tcx> Instance<'tcx> { let call_once = tcx .associated_items(fn_once) .in_definition_order() - .find(|it| it.kind == ty::AssocKind::Method) + .find(|it| it.kind == ty::AssocKind::Fn) .unwrap() .def_id; let def = ty::InstanceDef::ClosureOnceShim { call_once }; diff --git a/src/librustc_middle/ty/layout.rs b/src/librustc_middle/ty/layout.rs index 1bb338d43ad..5a210547f13 100644 --- a/src/librustc_middle/ty/layout.rs +++ b/src/librustc_middle/ty/layout.rs @@ -22,6 +22,7 @@ use std::cmp; use std::fmt; use std::iter; use std::mem; +use std::num::NonZeroUsize; use std::ops::Bound; pub trait IntegerExt { @@ -518,7 +519,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { // The never type. ty::Never => tcx.intern_layout(Layout { variants: Variants::Single { index: VariantIdx::new(0) }, - fields: FieldsShape::Union(0), + fields: FieldsShape::Primitive, abi: Abi::Uninhabited, largest_niche: None, align: dl.i8_align, @@ -744,7 +745,10 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { return Ok(tcx.intern_layout(Layout { variants: Variants::Single { index }, - fields: FieldsShape::Union(variants[index].len()), + fields: FieldsShape::Union( + NonZeroUsize::new(variants[index].len()) + .ok_or(LayoutError::Unknown(ty))?, + ), abi, largest_niche: None, align, @@ -1988,7 +1992,7 @@ where if index == variant_index && // Don't confuse variants of uninhabited enums with the enum itself. // For more details see https://github.com/rust-lang/rust/issues/69763. - this.fields != FieldsShape::Union(0) => + this.fields != FieldsShape::Primitive => { this.layout } @@ -2006,7 +2010,10 @@ where let tcx = cx.tcx(); tcx.intern_layout(Layout { variants: Variants::Single { index: variant_index }, - fields: FieldsShape::Union(fields), + fields: match NonZeroUsize::new(fields) { + Some(fields) => FieldsShape::Union(fields), + None => FieldsShape::Arbitrary { offsets: vec![], memory_index: vec![] }, + }, abi: Abi::Uninhabited, largest_niche: None, align: tcx.data_layout.i8_align, diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs index 0e6c4f26222..9f095847099 100644 --- a/src/librustc_middle/ty/mod.rs +++ b/src/librustc_middle/ty/mod.rs @@ -1,5 +1,3 @@ -// ignore-tidy-filelength - pub use self::fold::{TypeFoldable, TypeVisitor}; pub use self::AssocItemContainer::*; pub use self::BorrowKind::*; @@ -29,6 +27,7 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sorted_map::SortedIndexMultiMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::{self, par_iter, ParallelIterator}; +use rustc_errors::ErrorReported; use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Namespace, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, CRATE_DEF_INDEX}; @@ -192,58 +191,50 @@ pub struct AssocItem { pub container: AssocItemContainer, /// Whether this is a method with an explicit self - /// as its first argument, allowing method calls. - pub method_has_self_argument: bool, + /// as its first parameter, allowing method calls. + pub fn_has_self_parameter: bool, } #[derive(Copy, Clone, PartialEq, Debug, HashStable)] pub enum AssocKind { Const, - Method, + Fn, OpaqueTy, Type, } impl AssocKind { - pub fn suggestion_descr(&self) -> &'static str { - match self { - ty::AssocKind::Method => "method call", - ty::AssocKind::Type | ty::AssocKind::OpaqueTy => "associated type", - ty::AssocKind::Const => "associated constant", - } - } - pub fn namespace(&self) -> Namespace { match *self { ty::AssocKind::OpaqueTy | ty::AssocKind::Type => Namespace::TypeNS, - ty::AssocKind::Const | ty::AssocKind::Method => Namespace::ValueNS, + ty::AssocKind::Const | ty::AssocKind::Fn => Namespace::ValueNS, } } -} -impl AssocItem { - pub fn def_kind(&self) -> DefKind { - match self.kind { + pub fn as_def_kind(&self) -> DefKind { + match self { AssocKind::Const => DefKind::AssocConst, - AssocKind::Method => DefKind::AssocFn, + AssocKind::Fn => DefKind::AssocFn, AssocKind::Type => DefKind::AssocTy, AssocKind::OpaqueTy => DefKind::AssocOpaqueTy, } } +} +impl AssocItem { /// Tests whether the associated item admits a non-trivial implementation /// for ! pub fn relevant_for_never(&self) -> bool { match self.kind { AssocKind::OpaqueTy | AssocKind::Const | AssocKind::Type => true, // FIXME(canndrew): Be more thorough here, check if any argument is uninhabited. - AssocKind::Method => !self.method_has_self_argument, + AssocKind::Fn => !self.fn_has_self_parameter, } } pub fn signature(&self, tcx: TyCtxt<'_>) -> String { match self.kind { - ty::AssocKind::Method => { + ty::AssocKind::Fn => { // We skip the binder here because the binder would deanonymize all // late-bound regions, and we don't want method signatures to show up // `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound @@ -577,8 +568,8 @@ bitflags! { | TypeFlags::HAS_TY_OPAQUE.bits | TypeFlags::HAS_CT_PROJECTION.bits; - /// Is an error type reachable? - const HAS_TY_ERR = 1 << 13; + /// Is an error type/const reachable? + const HAS_ERROR = 1 << 13; /// Does this have any region that "appears free" in the type? /// Basically anything but [ReLateBound] and [ReErased]. @@ -2398,7 +2389,7 @@ impl<'tcx> AdtDef { None } } - Err(ErrorHandled::Reported) => { + Err(ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted) => { if !expr_did.is_local() { span_bug!( tcx.def_span(expr_did), @@ -2409,7 +2400,11 @@ impl<'tcx> AdtDef { None } Err(ErrorHandled::TooGeneric) => { - span_bug!(tcx.def_span(expr_did), "enum discriminant depends on generic arguments",) + tcx.sess.delay_span_bug( + tcx.def_span(expr_did), + "enum discriminant depends on generic arguments", + ); + None } } } @@ -2664,7 +2659,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn provided_trait_methods(self, id: DefId) -> impl 'tcx + Iterator<Item = &'tcx AssocItem> { self.associated_items(id) .in_definition_order() - .filter(|item| item.kind == AssocKind::Method && item.defaultness.has_value()) + .filter(|item| item.kind == AssocKind::Fn && item.defaultness.has_value()) } pub fn trait_relevant_for_never(self, did: DefId) -> bool { diff --git a/src/librustc_middle/ty/outlives.rs b/src/librustc_middle/ty/outlives.rs index 950539fbb0a..4fd4d0d1f06 100644 --- a/src/librustc_middle/ty/outlives.rs +++ b/src/librustc_middle/ty/outlives.rs @@ -62,6 +62,27 @@ fn compute_components(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, out: &mut SmallVec<[Compo // in the `subtys` iterator (e.g., when encountering a // projection). match ty.kind { + ty::FnDef(_, substs) => { + // HACK(eddyb) ignore lifetimes found shallowly in `substs`. + // This is inconsistent with `ty::Adt` (including all substs) + // and with `ty::Closure` (ignoring all substs other than + // upvars, of which a `ty::FnDef` doesn't have any), but + // consistent with previous (accidental) behavior. + // See https://github.com/rust-lang/rust/issues/70917 + // for further background and discussion. + for &child in substs { + match child.unpack() { + GenericArgKind::Type(ty) => { + compute_components(tcx, ty, out); + } + GenericArgKind::Lifetime(_) => {} + GenericArgKind::Const(_) => { + compute_components_recursive(tcx, child, out); + } + } + } + } + ty::Closure(_, ref substs) => { for upvar_ty in substs.as_closure().upvar_tys() { compute_components(tcx, upvar_ty, out); @@ -136,7 +157,7 @@ fn compute_components(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, out: &mut SmallVec<[Compo ty::Float(..) | // OutlivesScalar ty::Never | // ... ty::Adt(..) | // OutlivesNominalType - ty::Opaque(..) | // OutlivesNominalType (ish) + ty::Opaque(..) | // OutlivesNominalType (ish) ty::Foreign(..) | // OutlivesNominalType ty::Str | // OutlivesScalar (ish) ty::Array(..) | // ... @@ -144,15 +165,14 @@ fn compute_components(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, out: &mut SmallVec<[Compo ty::RawPtr(..) | // ... ty::Ref(..) | // OutlivesReference ty::Tuple(..) | // ... - ty::FnDef(..) | // OutlivesFunction (*) ty::FnPtr(_) | // OutlivesFunction (*) - ty::Dynamic(..) | // OutlivesObject, OutlivesFragment (*) + ty::Dynamic(..) | // OutlivesObject, OutlivesFragment (*) ty::Placeholder(..) | ty::Bound(..) | ty::Error => { - // (*) Bare functions and traits are both binders. In the - // RFC, this means we would add the bound regions to the - // "bound regions list". In our representation, no such + // (*) Function pointers and trait objects are both binders. + // In the RFC, this means we would add the bound regions to + // the "bound regions list". In our representation, no such // list is maintained explicitly, because bound regions // themselves can be readily identified. compute_components_recursive(tcx, ty.into(), out); diff --git a/src/librustc_middle/ty/print/pretty.rs b/src/librustc_middle/ty/print/pretty.rs index a8b7b6a4b97..2aa849f89c4 100644 --- a/src/librustc_middle/ty/print/pretty.rs +++ b/src/librustc_middle/ty/print/pretty.rs @@ -938,6 +938,7 @@ pub trait PrettyPrinter<'tcx>: self.pretty_print_bound_var(debruijn, bound_var)? } ty::ConstKind::Placeholder(placeholder) => p!(write("Placeholder({:?})", placeholder)), + ty::ConstKind::Error => p!(write("[const error]")), }; Ok(self) } diff --git a/src/librustc_middle/ty/query/mod.rs b/src/librustc_middle/ty/query/mod.rs index 9986eb88dc3..899479e65a7 100644 --- a/src/librustc_middle/ty/query/mod.rs +++ b/src/librustc_middle/ty/query/mod.rs @@ -189,3 +189,31 @@ pub fn force_from_dep_node<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> bool pub(crate) fn try_load_from_on_disk_cache<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &DepNode) { rustc_dep_node_try_load_from_on_disk_cache!(dep_node, tcx) } + +mod sealed { + use super::{DefId, LocalDefId}; + + /// An analogue of the `Into` trait that's intended only for query paramaters. + /// + /// This exists to allow queries to accept either `DefId` or `LocalDefId` while requiring that the + /// user call `to_def_id` to convert between them everywhere else. + pub trait IntoQueryParam<P> { + fn into_query_param(self) -> P; + } + + impl<P> IntoQueryParam<P> for P { + #[inline(always)] + fn into_query_param(self) -> P { + self + } + } + + impl IntoQueryParam<DefId> for LocalDefId { + #[inline(always)] + fn into_query_param(self) -> DefId { + self.to_def_id() + } + } +} + +use sealed::IntoQueryParam; diff --git a/src/librustc_middle/ty/query/plumbing.rs b/src/librustc_middle/ty/query/plumbing.rs index 1bb392f436f..068322b08b7 100644 --- a/src/librustc_middle/ty/query/plumbing.rs +++ b/src/librustc_middle/ty/query/plumbing.rs @@ -234,18 +234,23 @@ macro_rules! hash_result { macro_rules! define_queries { (<$tcx:tt> $($category:tt { - $($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident: $node:ident($K:ty) -> $V:ty,)* + $($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident: $node:ident($($K:tt)*) -> $V:ty,)* },)*) => { define_queries_inner! { <$tcx> - $($( $(#[$attr])* category<$category> [$($modifiers)*] fn $name: $node($K) -> $V,)*)* + $($( $(#[$attr])* category<$category> [$($modifiers)*] fn $name: $node($($K)*) -> $V,)*)* } } } +macro_rules! query_helper_param_ty { + (DefId) => { impl IntoQueryParam<DefId> }; + ($K:ty) => { $K }; +} + macro_rules! define_queries_inner { (<$tcx:tt> $($(#[$attr:meta])* category<$category:tt> - [$($modifiers:tt)*] fn $name:ident: $node:ident($K:ty) -> $V:ty,)*) => { + [$($modifiers:tt)*] fn $name:ident: $node:ident($($K:tt)*) -> $V:ty,)*) => { use std::mem; use crate::{ @@ -263,7 +268,7 @@ macro_rules! define_queries_inner { #[allow(nonstandard_style)] #[derive(Clone, Debug)] pub enum Query<$tcx> { - $($(#[$attr])* $name($K)),* + $($(#[$attr])* $name($($K)*)),* } impl<$tcx> Query<$tcx> { @@ -321,7 +326,7 @@ macro_rules! define_queries_inner { } $(impl<$tcx> QueryConfig<TyCtxt<$tcx>> for queries::$name<$tcx> { - type Key = $K; + type Key = $($K)*; type Value = $V; const NAME: &'static str = stringify!($name); const CATEGORY: ProfileCategory = $category; @@ -332,7 +337,7 @@ macro_rules! define_queries_inner { const EVAL_ALWAYS: bool = is_eval_always!([$($modifiers)*]); const DEP_KIND: dep_graph::DepKind = dep_graph::DepKind::$node; - type Cache = query_storage!([$($modifiers)*][$K, $V]); + type Cache = query_storage!([$($modifiers)*][$($K)*, $V]); #[inline(always)] fn query_state<'a>(tcx: TyCtxt<$tcx>) -> &'a QueryState<TyCtxt<$tcx>, Self::Cache> { @@ -380,8 +385,8 @@ macro_rules! define_queries_inner { impl TyCtxtEnsure<$tcx> { $($(#[$attr])* #[inline(always)] - pub fn $name(self, key: $K) { - ensure_query::<queries::$name<'_>, _>(self.tcx, key) + pub fn $name(self, key: query_helper_param_ty!($($K)*)) { + ensure_query::<queries::$name<'_>, _>(self.tcx, key.into_query_param()) })* } @@ -421,7 +426,7 @@ macro_rules! define_queries_inner { $($(#[$attr])* #[inline(always)] - pub fn $name(self, key: $K) -> $V { + pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V { self.at(DUMMY_SP).$name(key) })* @@ -458,14 +463,14 @@ macro_rules! define_queries_inner { impl TyCtxtAt<$tcx> { $($(#[$attr])* #[inline(always)] - pub fn $name(self, key: $K) -> $V { - get_query::<queries::$name<'_>, _>(self.tcx, self.span, key) + pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V { + get_query::<queries::$name<'_>, _>(self.tcx, self.span, key.into_query_param()) })* } define_provider_struct! { tcx: $tcx, - input: ($(([$($modifiers)*] [$name] [$K] [$V]))*) + input: ($(([$($modifiers)*] [$name] [$($K)*] [$V]))*) } impl<$tcx> Copy for Providers<$tcx> {} diff --git a/src/librustc_middle/ty/relate.rs b/src/librustc_middle/ty/relate.rs index 4d668e6ee59..f4f0b6c41b9 100644 --- a/src/librustc_middle/ty/relate.rs +++ b/src/librustc_middle/ty/relate.rs @@ -510,12 +510,21 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>( let tcx = relation.tcx(); let eagerly_eval = |x: &'tcx ty::Const<'tcx>| { + // FIXME(eddyb) this doesn't account for lifetime inference variables + // being erased by `eval`, *nor* for the polymorphic aspect of `eval`. + // That is, we could always use `eval` and it will just return the + // old value back if it doesn't succeed. if !x.val.needs_infer() { return x.eval(tcx, relation.param_env()).val; } x.val }; + // FIXME(eddyb) doesn't look like everything below checks that `a.ty == b.ty`. + // We could probably always assert it early, as `const` generic parameters + // are not allowed to depend on other generic parameters, i.e. are concrete. + // (although there could be normalization differences) + // Currently, the values that can be unified are primitive types, // and those that derive both `PartialEq` and `Eq`, corresponding // to structural-match types. @@ -524,6 +533,9 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>( // The caller should handle these cases! bug!("var types encountered in super_relate_consts: {:?} {:?}", a, b) } + + (ty::ConstKind::Error, _) | (_, ty::ConstKind::Error) => Ok(ty::ConstKind::Error), + (ty::ConstKind::Param(a_p), ty::ConstKind::Param(b_p)) if a_p.index == b_p.index => { return Ok(a); } diff --git a/src/librustc_middle/ty/structural_impls.rs b/src/librustc_middle/ty/structural_impls.rs index 0ac4466d34f..1c0ffe12314 100644 --- a/src/librustc_middle/ty/structural_impls.rs +++ b/src/librustc_middle/ty/structural_impls.rs @@ -1022,9 +1022,10 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> { ty::ConstKind::Unevaluated(did, substs, promoted) => { ty::ConstKind::Unevaluated(did, substs.fold_with(folder), promoted) } - ty::ConstKind::Value(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(..) => { - *self - } + ty::ConstKind::Value(_) + | ty::ConstKind::Bound(..) + | ty::ConstKind::Placeholder(..) + | ty::ConstKind::Error => *self, } } @@ -1033,9 +1034,10 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> { ty::ConstKind::Infer(ic) => ic.visit_with(visitor), ty::ConstKind::Param(p) => p.visit_with(visitor), ty::ConstKind::Unevaluated(_, substs, _) => substs.visit_with(visitor), - ty::ConstKind::Value(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) => { - false - } + ty::ConstKind::Value(_) + | ty::ConstKind::Bound(..) + | ty::ConstKind::Placeholder(_) + | ty::ConstKind::Error => false, } } } diff --git a/src/librustc_middle/ty/sty.rs b/src/librustc_middle/ty/sty.rs index 081e6f06b33..c80d4fb99b5 100644 --- a/src/librustc_middle/ty/sty.rs +++ b/src/librustc_middle/ty/sty.rs @@ -18,6 +18,7 @@ use crate::ty::{List, ParamEnv, ParamEnvAnd, TyS}; use polonius_engine::Atom; use rustc_ast::ast::{self, Ident}; use rustc_data_structures::captures::Captures; +use rustc_errors::ErrorReported; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_index::vec::Idx; @@ -2339,43 +2340,45 @@ impl<'tcx> Const<'tcx> { /// Tries to evaluate the constant if it is `Unevaluated`. If that doesn't succeed, return the /// unevaluated constant. pub fn eval(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> &Const<'tcx> { - let try_const_eval = |did, param_env: ParamEnv<'tcx>, substs, promoted| { + if let ConstKind::Unevaluated(did, substs, promoted) = self.val { + use crate::mir::interpret::ErrorHandled; + let param_env_and_substs = param_env.with_reveal_all().and(substs); - // Avoid querying `tcx.const_eval(...)` with any inference vars. - if param_env_and_substs.needs_infer() { - return None; - } + // HACK(eddyb) this erases lifetimes even though `const_eval_resolve` + // also does later, but we want to do it before checking for + // inference variables. + let param_env_and_substs = tcx.erase_regions(¶m_env_and_substs); + + // HACK(eddyb) when the query key would contain inference variables, + // attempt using identity substs and `ParamEnv` instead, that will succeed + // when the expression doesn't depend on any parameters. + // FIXME(eddyb, skinny121) pass `InferCtxt` into here when it's available, so that + // we can call `infcx.const_eval_resolve` which handles inference variables. + let param_env_and_substs = if param_env_and_substs.needs_infer() { + tcx.param_env(did).and(InternalSubsts::identity_for_item(tcx, did)) + } else { + param_env_and_substs + }; + // FIXME(eddyb) maybe the `const_eval_*` methods should take + // `ty::ParamEnvAnd<SubstsRef>` instead of having them separate. let (param_env, substs) = param_env_and_substs.into_parts(); - // try to resolve e.g. associated constants to their definition on an impl, and then // evaluate the const. - tcx.const_eval_resolve(param_env, did, substs, promoted, None) - .ok() - .map(|val| Const::from_value(tcx, val, self.ty)) - }; - - match self.val { - ConstKind::Unevaluated(did, substs, promoted) => { - // HACK(eddyb) when substs contain inference variables, - // attempt using identity substs instead, that will succeed - // when the expression doesn't depend on any parameters. - // FIXME(eddyb, skinny121) pass `InferCtxt` into here when it's available, so that - // we can call `infcx.const_eval_resolve` which handles inference variables. - if substs.needs_infer() { - let identity_substs = InternalSubsts::identity_for_item(tcx, did); - // The `ParamEnv` needs to match the `identity_substs`. - let identity_param_env = tcx.param_env(did); - match try_const_eval(did, identity_param_env, identity_substs, promoted) { - Some(ct) => ct.subst(tcx, substs), - None => self, - } - } else { - try_const_eval(did, param_env, substs, promoted).unwrap_or(self) + match tcx.const_eval_resolve(param_env, did, substs, promoted, None) { + // NOTE(eddyb) `val` contains no lifetimes/types/consts, + // and we use the original type, so nothing from `substs` + // (which may be identity substs, see above), + // can leak through `val` into the const we return. + Ok(val) => Const::from_value(tcx, val, self.ty), + Err(ErrorHandled::TooGeneric | ErrorHandled::Linted) => self, + Err(ErrorHandled::Reported(ErrorReported)) => { + tcx.mk_const(ty::Const { val: ty::ConstKind::Error, ty: self.ty }) } } - _ => self, + } else { + self } } @@ -2431,6 +2434,10 @@ pub enum ConstKind<'tcx> { /// Used to hold computed value. Value(ConstValue<'tcx>), + + /// A placeholder for a const which could not be computed; this is + /// propagated to avoid useless error messages. + Error, } #[cfg(target_arch = "x86_64")] diff --git a/src/librustc_middle/ty/trait_def.rs b/src/librustc_middle/ty/trait_def.rs index ed9054fcffd..912f8be1d33 100644 --- a/src/librustc_middle/ty/trait_def.rs +++ b/src/librustc_middle/ty/trait_def.rs @@ -193,7 +193,7 @@ pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> &Trai let mut impls = TraitImpls::default(); { - let mut add_impl = |impl_def_id| { + let mut add_impl = |impl_def_id: DefId| { let impl_self_ty = tcx.type_of(impl_def_id); if impl_def_id.is_local() && impl_self_ty.references_error() { return; diff --git a/src/librustc_middle/ty/walk.rs b/src/librustc_middle/ty/walk.rs index c7a317f39ad..b6cadd00996 100644 --- a/src/librustc_middle/ty/walk.rs +++ b/src/librustc_middle/ty/walk.rs @@ -170,7 +170,8 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>) | ty::ConstKind::Param(_) | ty::ConstKind::Placeholder(_) | ty::ConstKind::Bound(..) - | ty::ConstKind::Value(_) => {} + | ty::ConstKind::Value(_) + | ty::ConstKind::Error => {} ty::ConstKind::Unevaluated(_, substs, _) => { stack.extend(substs.iter().copied().rev()); diff --git a/src/librustc_mir/borrow_check/diagnostics/region_name.rs b/src/librustc_mir/borrow_check/diagnostics/region_name.rs index a085c2f7f69..e4ca54ffd5e 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_name.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_name.rs @@ -148,7 +148,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { /// /// This function would create a label like this: /// - /// ``` + /// ```text /// | fn foo(x: &u32) { .. } /// ------- fully elaborated type of `x` is `&'1 u32` /// ``` @@ -300,7 +300,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { /// elaborated type, returning something like `'1`. Result looks /// like: /// - /// ``` + /// ```text /// | fn foo(x: &u32) { .. } /// ------- fully elaborated type of `x` is `&'1 u32` /// ``` @@ -347,7 +347,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { /// that has no type annotation. /// For example, we might produce an annotation like this: /// - /// ``` + /// ```text /// | foo(|a, b| b) /// | - - /// | | | @@ -396,7 +396,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { /// that contains the anonymous reference we want to give a name /// to. For example, we might produce an annotation like this: /// - /// ``` + /// ```text /// | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item = &T>> { /// | - let's call the lifetime of this reference `'1` /// ``` @@ -600,7 +600,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { /// fully elaborated type, returning something like `'1`. Result /// looks like: /// - /// ``` + /// ```text /// | let x = Some(&22); /// - fully elaborated type of `x` is `Option<&'1 u32>` /// ``` diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 52847af214f..d525e7fe46f 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -3,7 +3,7 @@ use rustc_ast::ast::Name; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::graph::dominators::Dominators; -use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder}; +use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorReported}; use rustc_hir as hir; use rustc_hir::{def_id::DefId, HirId, Node}; use rustc_index::bit_set::BitSet; @@ -135,7 +135,7 @@ fn do_mir_borrowck<'a, 'tcx>( // Gather the upvars of a closure, if any. let tables = tcx.typeck_tables_of(def_id); - if tables.tainted_by_errors { + if let Some(ErrorReported) = tables.tainted_by_errors { infcx.set_tainted_by_errors(); } let upvars: Vec<_> = tables @@ -1056,7 +1056,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { place: {:?}", place_span.0 ); - this.reservation_error_reported.insert(place_span.0.clone()); + this.reservation_error_reported.insert(place_span.0); } Activation(_, activating) => { debug!( diff --git a/src/librustc_mir/borrow_check/region_infer/mod.rs b/src/librustc_mir/borrow_check/region_infer/mod.rs index 40012116633..7987b77997d 100644 --- a/src/librustc_mir/borrow_check/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/region_infer/mod.rs @@ -495,7 +495,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // to store those. Otherwise, we'll pass in `None` to the // functions below, which will trigger them to report errors // eagerly. - let mut outlives_requirements = infcx.tcx.is_closure(mir_def_id).then(|| vec![]); + let mut outlives_requirements = infcx.tcx.is_closure(mir_def_id).then(Vec::new); self.check_type_tests(infcx, body, outlives_requirements.as_mut(), &mut errors_buffer); diff --git a/src/librustc_mir/borrow_check/type_check/mod.rs b/src/librustc_mir/borrow_check/type_check/mod.rs index a118fe2db71..4dc4fb6d8e9 100644 --- a/src/librustc_mir/borrow_check/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/type_check/mod.rs @@ -1760,6 +1760,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } for (n, (fn_arg, op_arg)) in sig.inputs().iter().zip(args).enumerate() { let op_arg_ty = op_arg.ty(body, self.tcx()); + let op_arg_ty = self.normalize(op_arg_ty, term_location); let category = if from_hir_call { ConstraintCategory::CallArgument } else { @@ -2402,6 +2403,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } }; let operand_ty = operand.ty(body, tcx); + let operand_ty = self.normalize(operand_ty, location); if let Err(terr) = self.sub_types( operand_ty, diff --git a/src/librustc_mir/const_eval/eval_queries.rs b/src/librustc_mir/const_eval/eval_queries.rs index 97cdb32e2cd..8cb0ea91bc2 100644 --- a/src/librustc_mir/const_eval/eval_queries.rs +++ b/src/librustc_mir/const_eval/eval_queries.rs @@ -1,7 +1,7 @@ use super::{error_to_const_error, CompileTimeEvalContext, CompileTimeInterpreter, MemoryExtra}; use crate::interpret::eval_nullary_intrinsic; use crate::interpret::{ - intern_const_alloc_recursive, Allocation, ConstValue, GlobalId, ImmTy, Immediate, InternKind, + intern_const_alloc_recursive, Allocation, ConstValue, GlobalId, Immediate, InternKind, InterpCx, InterpResult, MPlaceTy, MemoryKind, OpTy, RawConst, RefTracking, Scalar, ScalarMaybeUndef, StackPopCleanup, }; @@ -147,25 +147,28 @@ pub(super) fn op_to_const<'tcx>( match immediate { Ok(mplace) => to_const_value(mplace), // see comment on `let try_as_immediate` above - Err(ImmTy { imm: Immediate::Scalar(x), .. }) => match x { - ScalarMaybeUndef::Scalar(s) => ConstValue::Scalar(s), - ScalarMaybeUndef::Undef => to_const_value(op.assert_mem_place(ecx)), + Err(imm) => match *imm { + Immediate::Scalar(x) => match x { + ScalarMaybeUndef::Scalar(s) => ConstValue::Scalar(s), + ScalarMaybeUndef::Undef => to_const_value(op.assert_mem_place(ecx)), + }, + Immediate::ScalarPair(a, b) => { + let (data, start) = match a.not_undef().unwrap() { + Scalar::Ptr(ptr) => { + (ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id), ptr.offset.bytes()) + } + Scalar::Raw { .. } => ( + ecx.tcx + .intern_const_alloc(Allocation::from_byte_aligned_bytes(b"" as &[u8])), + 0, + ), + }; + let len = b.to_machine_usize(&ecx.tcx.tcx).unwrap(); + let start = start.try_into().unwrap(); + let len: usize = len.try_into().unwrap(); + ConstValue::Slice { data, start, end: start + len } + } }, - Err(ImmTy { imm: Immediate::ScalarPair(a, b), .. }) => { - let (data, start) = match a.not_undef().unwrap() { - Scalar::Ptr(ptr) => { - (ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id), ptr.offset.bytes()) - } - Scalar::Raw { .. } => ( - ecx.tcx.intern_const_alloc(Allocation::from_byte_aligned_bytes(b"" as &[u8])), - 0, - ), - }; - let len = b.to_machine_usize(&ecx.tcx.tcx).unwrap(); - let start = start.try_into().unwrap(); - let len: usize = len.try_into().unwrap(); - ConstValue::Slice { data, start, end: start + len } - } } } @@ -210,13 +213,10 @@ fn validate_and_turn_into_const<'tcx>( val.map_err(|error| { let err = error_to_const_error(&ecx, error); - match err.struct_error(ecx.tcx, "it is undefined behavior to use this value", |mut diag| { + err.struct_error(ecx.tcx, "it is undefined behavior to use this value", |mut diag| { diag.note(note_on_undefined_behavior_error()); diag.emit(); - }) { - Ok(_) => ErrorHandled::Reported, - Err(err) => err, - } + }) }) } @@ -289,11 +289,10 @@ pub fn const_eval_raw_provider<'tcx>( let cid = key.value; let def_id = cid.instance.def.def_id(); - if def_id.is_local() - && tcx.has_typeck_tables(def_id) - && tcx.typeck_tables_of(def_id).tainted_by_errors - { - return Err(ErrorHandled::Reported); + if def_id.is_local() && tcx.has_typeck_tables(def_id) { + if let Some(error_reported) = tcx.typeck_tables_of(def_id).tainted_by_errors { + return Err(ErrorHandled::Reported(error_reported)); + } } let is_static = tcx.is_static(def_id); diff --git a/src/librustc_mir/const_eval/fn_queries.rs b/src/librustc_mir/const_eval/fn_queries.rs index f1dff4fceb4..bb33372692d 100644 --- a/src/librustc_mir/const_eval/fn_queries.rs +++ b/src/librustc_mir/const_eval/fn_queries.rs @@ -95,8 +95,16 @@ fn is_const_fn_raw(tcx: TyCtxt<'_>, def_id: DefId) -> bool { let node = tcx.hir().get(hir_id); - if let Some(whitelisted) = is_const_intrinsic(tcx, def_id) { - whitelisted + if let hir::Node::ForeignItem(hir::ForeignItem { kind: hir::ForeignItemKind::Fn(..), .. }) = + node + { + // Intrinsics use `rustc_const_{un,}stable` attributes to indicate constness. All other + // foreign items cannot be evaluated at compile-time. + if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = tcx.hir().get_foreign_abi(hir_id) { + tcx.lookup_const_stability(def_id).is_some() + } else { + false + } } else if let Some(fn_like) = FnLikeNode::from_node(node) { if fn_like.constness() == hir::Constness::Const { return true; @@ -112,21 +120,6 @@ fn is_const_fn_raw(tcx: TyCtxt<'_>, def_id: DefId) -> bool { } } -/// Const evaluability whitelist is here to check evaluability at the -/// top level beforehand. -fn is_const_intrinsic(tcx: TyCtxt<'_>, def_id: DefId) -> Option<bool> { - if tcx.is_closure(def_id) { - return None; - } - - match tcx.fn_sig(def_id).abi() { - Abi::RustIntrinsic | Abi::PlatformIntrinsic => { - Some(tcx.lookup_const_stability(def_id).is_some()) - } - _ => None, - } -} - /// Checks whether the given item is an `impl` that has a `const` modifier. fn is_const_impl_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); diff --git a/src/librustc_mir/const_eval/machine.rs b/src/librustc_mir/const_eval/machine.rs index e9263471478..e53ca6b31bb 100644 --- a/src/librustc_mir/const_eval/machine.rs +++ b/src/librustc_mir/const_eval/machine.rs @@ -13,8 +13,8 @@ use rustc_middle::mir::AssertMessage; use rustc_span::symbol::Symbol; use crate::interpret::{ - self, AllocId, Allocation, GlobalId, ImmTy, InterpCx, InterpResult, Memory, MemoryKind, OpTy, - PlaceTy, Pointer, Scalar, + self, AllocId, Allocation, Frame, GlobalId, ImmTy, InterpCx, InterpResult, Memory, MemoryKind, + OpTy, PlaceTy, Pointer, Scalar, }; use super::error::*; @@ -179,9 +179,12 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter { const GLOBAL_KIND: Option<!> = None; // no copying of globals from `tcx` to machine memory - // We do not check for alignment to avoid having to carry an `Align` - // in `ConstValue::ByRef`. - const CHECK_ALIGN: bool = false; + #[inline(always)] + fn enforce_alignment(_memory_extra: &Self::MemoryExtra) -> bool { + // We do not check for alignment to avoid having to carry an `Align` + // in `ConstValue::ByRef`. + false + } #[inline(always)] fn enforce_validity(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool { @@ -339,8 +342,11 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter { } #[inline(always)] - fn stack_push(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> { - Ok(()) + fn init_frame_extra( + _ecx: &mut InterpCx<'mir, 'tcx, Self>, + frame: Frame<'mir, 'tcx>, + ) -> InterpResult<'tcx, Frame<'mir, 'tcx>> { + Ok(frame) } fn before_access_global( @@ -350,15 +356,30 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter { static_def_id: Option<DefId>, is_write: bool, ) -> InterpResult<'tcx> { - if is_write && allocation.mutability == Mutability::Not { - Err(err_ub!(WriteToReadOnly(alloc_id)).into()) - } else if is_write { - Err(ConstEvalErrKind::ModifiedGlobal.into()) - } else if memory_extra.can_access_statics || static_def_id.is_none() { - // `static_def_id.is_none()` indicates this is not a static, but a const or so. - Ok(()) + if is_write { + // Write access. These are never allowed, but we give a targeted error message. + if allocation.mutability == Mutability::Not { + Err(err_ub!(WriteToReadOnly(alloc_id)).into()) + } else { + Err(ConstEvalErrKind::ModifiedGlobal.into()) + } } else { - Err(ConstEvalErrKind::ConstAccessesStatic.into()) + // Read access. These are usually allowed, with some exceptions. + if memory_extra.can_access_statics { + // Machine configuration allows us read from anything (e.g., `static` initializer). + Ok(()) + } else if static_def_id.is_some() { + // Machine configuration does not allow us to read statics + // (e.g., `const` initializer). + Err(ConstEvalErrKind::ConstAccessesStatic.into()) + } else { + // Immutable global, this read is fine. + // But make sure we never accept a read from something mutable, that would be + // unsound. The reason is that as the content of this allocation may be different + // now and at run-time, so if we permit reading now we might return the wrong value. + assert_eq!(allocation.mutability, Mutability::Not); + Ok(()) + } } } } diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs index fabe575c289..a5f46c28cd6 100644 --- a/src/librustc_mir/dataflow/move_paths/builder.rs +++ b/src/librustc_mir/dataflow/move_paths/builder.rs @@ -286,7 +286,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { // Box starts out uninitialized - need to create a separate // move-path for the interior so it will be separate from // the exterior. - self.create_move_path(self.builder.tcx.mk_place_deref(place.clone())); + self.create_move_path(self.builder.tcx.mk_place_deref(*place)); self.gather_init(place.as_ref(), InitKind::Shallow); } else { self.gather_init(place.as_ref(), InitKind::Deep); @@ -458,9 +458,8 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { for offset in from..to { let elem = ProjectionElem::ConstantIndex { offset, min_length: len, from_end: false }; - let path = self.add_move_path(base_path, &elem, |tcx| { - tcx.mk_place_elem(base_place.clone(), elem) - }); + let path = + self.add_move_path(base_path, &elem, |tcx| tcx.mk_place_elem(base_place, elem)); self.record_move(place, path); } } else { diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index e0b5f634bf3..fcbb2535797 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -159,6 +159,21 @@ impl<'tcx, Tag: Copy + 'static> LocalState<'tcx, Tag> { } } +impl<'mir, 'tcx, Tag> Frame<'mir, 'tcx, Tag> { + pub fn with_extra<Extra>(self, extra: Extra) -> Frame<'mir, 'tcx, Tag, Extra> { + Frame { + body: self.body, + instance: self.instance, + return_to_block: self.return_to_block, + return_place: self.return_place, + locals: self.locals, + block: self.block, + stmt: self.stmt, + extra, + } + } +} + impl<'mir, 'tcx, Tag, Extra> Frame<'mir, 'tcx, Tag, Extra> { /// Return the `SourceInfo` of the current instruction. pub fn current_source_info(&self) -> Option<mir::SourceInfo> { @@ -385,11 +400,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ) -> InterpResult<'tcx, mir::ReadOnlyBodyAndCache<'tcx, 'tcx>> { // do not continue if typeck errors occurred (can only occur in local crate) let did = instance.def_id(); - if did.is_local() - && self.tcx.has_typeck_tables(did) - && self.tcx.typeck_tables_of(did).tainted_by_errors - { - throw_inval!(TypeckError) + if did.is_local() && self.tcx.has_typeck_tables(did) { + if let Some(error_reported) = self.tcx.typeck_tables_of(did).tainted_by_errors { + throw_inval!(TypeckError(error_reported)) + } } trace!("load mir(instance={:?}, promoted={:?})", instance, promoted); if let Some(promoted) = promoted { @@ -586,8 +600,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ::log_settings::settings().indentation += 1; // first push a stack frame so we have access to the local substs - let extra = M::stack_push(self)?; - self.stack.push(Frame { + let pre_frame = Frame { body, block: Some(mir::START_BLOCK), return_to_block, @@ -597,8 +610,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { locals: IndexVec::new(), instance, stmt: 0, - extra, - }); + extra: (), + }; + let frame = M::init_frame_extra(self, pre_frame)?; + self.stack.push(frame); // don't allocate at all for trivial constants if body.local_decls.len() > 1 { @@ -630,6 +645,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.frame_mut().locals = locals; } + M::after_stack_push(self)?; info!("ENTERING({}) {}", self.cur_frame(), self.frame().instance); if self.stack.len() > *self.tcx.sess.recursion_limit.get() { @@ -725,16 +741,17 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } // Cleanup: deallocate all locals that are backed by an allocation. - for local in frame.locals { + for local in &frame.locals { self.deallocate_local(local.value)?; } - if M::stack_pop(self, frame.extra, unwinding)? == StackPopJump::NoJump { + let return_place = frame.return_place; + if M::after_stack_pop(self, frame, unwinding)? == StackPopJump::NoJump { // The hook already did everything. // We want to skip the `info!` below, hence early return. return Ok(()); } - // Normal return. + // Normal return, figure out where to jump. if unwinding { // Follow the unwind edge. let unwind = next_block.expect("Encountered StackPopCleanup::None when unwinding!"); @@ -743,7 +760,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Follow the normal return edge. // Validate the return value. Do this after deallocating so that we catch dangling // references. - if let Some(return_place) = frame.return_place { + if let Some(return_place) = return_place { if M::enforce_validity(self) { // Data got changed, better make sure it matches the type! // It is still possible that the return place held invalid data while diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index af415b3837f..480415676f6 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -5,6 +5,7 @@ use super::validity::RefTracking; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_errors::ErrorReported; use rustc_hir as hir; use rustc_middle::mir::interpret::{ErrorHandled, InterpResult}; use rustc_middle::ty::{self, Ty}; @@ -337,7 +338,9 @@ pub fn intern_const_alloc_recursive<M: CompileTimeMachine<'mir, 'tcx>>( diag.emit(); }, ) { - Ok(()) | Err(ErrorHandled::TooGeneric) | Err(ErrorHandled::Reported) => {} + ErrorHandled::TooGeneric + | ErrorHandled::Reported(ErrorReported) + | ErrorHandled::Linted => {} } } } diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs index fd67b088c93..8bf8d904cb2 100644 --- a/src/librustc_mir/interpret/machine.rs +++ b/src/librustc_mir/interpret/machine.rs @@ -118,7 +118,7 @@ pub trait Machine<'mir, 'tcx>: Sized { const GLOBAL_KIND: Option<Self::MemoryKind>; /// Whether memory accesses should be alignment-checked. - const CHECK_ALIGN: bool; + fn enforce_alignment(memory_extra: &Self::MemoryExtra) -> bool; /// Whether to enforce the validity invariant fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool; @@ -279,13 +279,21 @@ pub trait Machine<'mir, 'tcx>: Sized { Ok(()) } - /// Called immediately before a new stack frame got pushed. - fn stack_push(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx, Self::FrameExtra>; + /// Called immediately before a new stack frame gets pushed. + fn init_frame_extra( + ecx: &mut InterpCx<'mir, 'tcx, Self>, + frame: Frame<'mir, 'tcx, Self::PointerTag>, + ) -> InterpResult<'tcx, Frame<'mir, 'tcx, Self::PointerTag, Self::FrameExtra>>; + + /// Called immediately after a stack frame got pushed and its locals got initialized. + fn after_stack_push(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> { + Ok(()) + } - /// Called immediately after a stack frame gets popped - fn stack_pop( + /// Called immediately after a stack frame got popped, but before jumping back to the caller. + fn after_stack_pop( _ecx: &mut InterpCx<'mir, 'tcx, Self>, - _extra: Self::FrameExtra, + _frame: Frame<'mir, 'tcx, Self::PointerTag, Self::FrameExtra>, _unwinding: bool, ) -> InterpResult<'tcx, StackPopJump> { // By default, we do not support unwinding from panics diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 539537e9de8..efc43afd0f0 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -18,8 +18,8 @@ use rustc_middle::ty::{self, query::TyCtxtAt, Instance, ParamEnv}; use rustc_target::abi::{Align, HasDataLayout, Size, TargetDataLayout}; use super::{ - AllocId, AllocMap, Allocation, AllocationExtra, CheckInAllocMsg, ErrorHandled, GlobalAlloc, - GlobalId, InterpResult, Machine, MayLeak, Pointer, PointerArithmetic, Scalar, + AllocId, AllocMap, Allocation, AllocationExtra, CheckInAllocMsg, GlobalAlloc, GlobalId, + InterpResult, Machine, MayLeak, Pointer, PointerArithmetic, Scalar, }; use crate::util::pretty; @@ -323,12 +323,12 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { size: Size, align: Align, ) -> InterpResult<'tcx, Option<Pointer<M::PointerTag>>> { - let align = M::CHECK_ALIGN.then_some(align); + let align = M::enforce_alignment(&self.extra).then_some(align); self.check_ptr_access_align(sptr, size, align, CheckInAllocMsg::MemoryAccessTest) } /// Like `check_ptr_access`, but *definitely* checks alignment when `align` - /// is `Some` (overriding `M::CHECK_ALIGN`). Also lets the caller control + /// is `Some` (overriding `M::enforce_alignment`). Also lets the caller control /// the error message for the out-of-bounds case. pub fn check_ptr_access_align( &self, @@ -462,10 +462,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { // no need to report anything, the const_eval call takes care of that // for statics assert!(tcx.is_static(def_id)); - match err { - ErrorHandled::Reported => err_inval!(ReferencedConstant), - ErrorHandled::TooGeneric => err_inval!(TooGeneric), - } + err })?; // Make sure we use the ID of the resolved memory, not the lazy one! let id = raw_const.alloc_id; diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 3741f31927e..2317a1fea07 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -4,6 +4,7 @@ use std::convert::TryFrom; use std::fmt::Write; +use rustc_errors::ErrorReported; use rustc_hir::def::Namespace; use rustc_macros::HashStable; use rustc_middle::ty::layout::{IntegerExt, PrimitiveExt, TyAndLayout}; @@ -87,7 +88,7 @@ impl<'tcx, Tag> Immediate<Tag> { // as input for binary and cast operations. #[derive(Copy, Clone, Debug)] pub struct ImmTy<'tcx, Tag = ()> { - pub(crate) imm: Immediate<Tag>, + imm: Immediate<Tag>, pub layout: TyAndLayout<'tcx>, } @@ -184,6 +185,11 @@ impl<'tcx, Tag: Copy> ImmTy<'tcx, Tag> { } #[inline] + pub fn from_immediate(imm: Immediate<Tag>, layout: TyAndLayout<'tcx>) -> Self { + ImmTy { imm, layout } + } + + #[inline] pub fn try_from_uint(i: impl Into<u128>, layout: TyAndLayout<'tcx>) -> Option<Self> { Some(Self::from_scalar(Scalar::try_from_uint(i, layout.size)?, layout)) } @@ -424,7 +430,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Ok(OpTy { op, layout }) } - /// Every place can be read from, so we can turn them into an operand + /// Every place can be read from, so we can turn them into an operand. + /// This will definitely return `Indirect` if the place is a `Ptr`, i.e., this + /// will never actually read from memory. #[inline(always)] pub fn place_to_op( &self, @@ -511,6 +519,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Early-return cases. let val_val = match val.val { ty::ConstKind::Param(_) => throw_inval!(TooGeneric), + ty::ConstKind::Error => throw_inval!(TypeckError(ErrorReported)), ty::ConstKind::Unevaluated(def_id, substs, promoted) => { let instance = self.resolve(def_id, substs)?; // We use `const_eval` here and `const_eval_raw` elsewhere in mir interpretation. diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 828df9a0930..71275452fb6 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -26,7 +26,7 @@ pub enum MemPlaceMeta<Tag = (), Id = AllocId> { /// `Sized` types or unsized `extern type` None, /// The address of this place may not be taken. This protects the `MemPlace` from coming from - /// a ZST Operand with a backing allocation and being converted to an integer address. This + /// a ZST Operand without a backing allocation and being converted to an integer address. This /// should be impossible, because you can't take the address of an operand, but this is a second /// protection layer ensuring that we don't mess up. Poison, @@ -247,7 +247,7 @@ impl<'tcx, Tag: ::std::fmt::Debug + Copy> OpTy<'tcx, Tag> { Operand::Immediate(_) if self.layout.is_zst() => { Ok(MPlaceTy::dangling(self.layout, cx)) } - Operand::Immediate(imm) => Err(ImmTy { imm, layout: self.layout }), + Operand::Immediate(imm) => Err(ImmTy::from_immediate(imm, self.layout)), } } @@ -549,7 +549,7 @@ where let n = base.len(self)?; if n < u64::from(min_length) { // This can only be reached in ConstProp and non-rustc-MIR. - throw_ub!(BoundsCheckFailed { len: min_length.into(), index: n.into() }); + throw_ub!(BoundsCheckFailed { len: min_length.into(), index: n }); } let index = if from_end { diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index 2d8551b2bbf..49fee1bddcb 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -407,7 +407,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let this_receiver_ptr = self.layout_of(receiver_ptr_ty)?.field(self, 0)?; // Adjust receiver argument. args[0] = - OpTy::from(ImmTy { layout: this_receiver_ptr, imm: receiver_place.ptr.into() }); + OpTy::from(ImmTy::from_immediate(receiver_place.ptr.into(), this_receiver_ptr)); trace!("Patched self operand to {:#?}", args[0]); // recurse with concrete function self.eval_fn_call(drop_fn, caller_abi, &args, ret, unwind) @@ -436,10 +436,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { _ => (instance, place), }; - let arg = ImmTy { - imm: place.to_ref(), - layout: self.layout_of(self.tcx.mk_mut_ptr(place.layout.ty))?, - }; + let arg = ImmTy::from_immediate( + place.to_ref(), + self.layout_of(self.tcx.mk_mut_ptr(place.layout.ty))?, + ); let ty = self.tcx.mk_unit(); // return type is () let dest = MPlaceTy::dangling(self.layout_of(ty)?, self); diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index 701e394415b..2dffd78d776 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -6,6 +6,7 @@ use std::convert::TryFrom; use std::fmt::Write; +use std::num::NonZeroUsize; use std::ops::RangeInclusive; use rustc_data_structures::fx::FxHashSet; @@ -322,7 +323,11 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M let value = self.ecx.read_immediate(value)?; // Handle wide pointers. // Check metadata early, for better diagnostics - let place = try_validation!(self.ecx.ref_to_mplace(value), "undefined pointer", self.path); + let place = try_validation!( + self.ecx.ref_to_mplace(value), + format_args!("uninitialized {}", kind), + self.path + ); if place.layout.is_unsized() { self.check_wide_ptr_meta(place.meta, place.layout)?; } @@ -334,7 +339,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M format_args!("invalid {} metadata: {}", kind, msg), self.path ), - _ => bug!("Unexpected error during ptr size_and_align_of: {}", err), + _ => bug!("unexpected error during ptr size_and_align_of: {}", err), }, }; let (size, align) = size_and_align @@ -477,10 +482,11 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M } ty::RawPtr(..) => { // We are conservative with undef for integers, but try to - // actually enforce our current rules for raw pointers. + // actually enforce the strict rules for raw pointers (mostly because + // that lets us re-use `ref_to_mplace`). let place = try_validation!( self.ecx.ref_to_mplace(self.ecx.read_immediate(value)?), - "undefined pointer", + "uninitialized raw pointer", self.path ); if place.layout.is_unsized() { @@ -642,10 +648,11 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> } #[inline(always)] - fn visit_union(&mut self, op: OpTy<'tcx, M::PointerTag>, fields: usize) -> InterpResult<'tcx> { - // Empty unions are not accepted by rustc. But uninhabited enums - // claim to be unions, so allow them, too. - assert!(op.layout.abi.is_uninhabited() || fields > 0); + fn visit_union( + &mut self, + _op: OpTy<'tcx, M::PointerTag>, + _fields: NonZeroUsize, + ) -> InterpResult<'tcx> { Ok(()) } @@ -776,14 +783,14 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> // For some errors we might be able to provide extra information match err.kind { err_ub!(InvalidUndefBytes(Some(ptr))) => { - // Some byte was undefined, determine which + // Some byte was uninitialized, determine which // element that byte belongs to so we can // provide an index. let i = usize::try_from(ptr.offset.bytes() / layout.size.bytes()) .unwrap(); self.path.push(PathElem::ArrayElem(i)); - throw_validation_failure!("undefined bytes", self.path) + throw_validation_failure!("uninitialized bytes", self.path) } // Other errors shouldn't be possible _ => return Err(err), diff --git a/src/librustc_mir/interpret/visitor.rs b/src/librustc_mir/interpret/visitor.rs index e03984f4d0b..00d39452c49 100644 --- a/src/librustc_mir/interpret/visitor.rs +++ b/src/librustc_mir/interpret/visitor.rs @@ -6,6 +6,8 @@ use rustc_middle::ty; use rustc_middle::ty::layout::TyAndLayout; use rustc_target::abi::{FieldsShape, VariantIdx, Variants}; +use std::num::NonZeroUsize; + use super::{InterpCx, MPlaceTy, Machine, OpTy}; // A thing that we can project into, and that has a layout. @@ -130,7 +132,7 @@ macro_rules! make_value_visitor { } /// Visits the given value as a union. No automatic recursion can happen here. #[inline(always)] - fn visit_union(&mut self, _v: Self::V, _fields: usize) -> InterpResult<'tcx> + fn visit_union(&mut self, _v: Self::V, _fields: NonZeroUsize) -> InterpResult<'tcx> { Ok(()) } @@ -208,6 +210,7 @@ macro_rules! make_value_visitor { // Visit the fields of this value. match v.layout().fields { + FieldsShape::Primitive => {}, FieldsShape::Union(fields) => { self.visit_union(v, fields)?; }, diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index d8ceda96a25..32d28bb0d13 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -178,6 +178,7 @@ use crate::monomorphize; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::{par_iter, MTLock, MTRef, ParallelIterator}; +use rustc_errors::ErrorReported; use rustc_hir as hir; use rustc_hir::def_id::{DefId, DefIdMap, LOCAL_CRATE}; use rustc_hir::itemlikevisit::ItemLikeVisitor; @@ -335,7 +336,7 @@ fn collect_items_rec<'tcx>( recursion_depths: &mut DefIdMap<usize>, inlining_map: MTRef<'_, MTLock<InliningMap<'tcx>>>, ) { - if !visited.lock_mut().insert(starting_point.clone()) { + if !visited.lock_mut().insert(starting_point) { // We've been here already, no need to search again. return; } @@ -602,7 +603,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { ty::ConstKind::Unevaluated(def_id, substs, promoted) => { match self.tcx.const_eval_resolve(param_env, def_id, substs, promoted, None) { Ok(val) => collect_const_value(self.tcx, val, self.output), - Err(ErrorHandled::Reported) => {} + Err(ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted) => {} Err(ErrorHandled::TooGeneric) => span_bug!( self.tcx.def_span(def_id), "collection encountered polymorphic constant", diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 67de81ed77b..a5034baa78e 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -74,7 +74,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx let call_mut = tcx .associated_items(fn_mut) .in_definition_order() - .find(|it| it.kind == ty::AssocKind::Method) + .find(|it| it.kind == ty::AssocKind::Fn) .unwrap() .def_id; @@ -538,7 +538,7 @@ impl CloneShimBuilder<'tcx> { // BB #2 // `dest[i] = Clone::clone(src[beg])`; // Goto #3 if ok, #5 if unwinding happens. - let dest_field = self.tcx.mk_place_index(dest.clone(), beg); + let dest_field = self.tcx.mk_place_index(dest, beg); let src_field = self.tcx.mk_place_index(src, beg); self.make_clone_call(dest_field, src_field, ty, BasicBlock::new(3), BasicBlock::new(5)); @@ -620,9 +620,9 @@ impl CloneShimBuilder<'tcx> { let mut previous_field = None; for (i, ity) in tys.enumerate() { let field = Field::new(i); - let src_field = self.tcx.mk_place_field(src.clone(), field, ity); + let src_field = self.tcx.mk_place_field(src, field, ity); - let dest_field = self.tcx.mk_place_field(dest.clone(), field, ity); + let dest_field = self.tcx.mk_place_field(dest, field, ity); // #(2i + 1) is the cleanup block for the previous clone operation let cleanup_block = self.block_index_offset(1); @@ -633,7 +633,7 @@ impl CloneShimBuilder<'tcx> { // BB #(2i) // `dest.i = Clone::clone(&src.i);` // Goto #(2i + 2) if ok, #(2i + 1) if unwinding happens. - self.make_clone_call(dest_field.clone(), src_field, ity, next_block, cleanup_block); + self.make_clone_call(dest_field, src_field, ity, next_block, cleanup_block); // BB #(2i + 1) (cleanup) if let Some((previous_field, previous_cleanup)) = previous_field.take() { diff --git a/src/librustc_mir/transform/add_retag.rs b/src/librustc_mir/transform/add_retag.rs index 5c016b0c515..d0de0a09873 100644 --- a/src/librustc_mir/transform/add_retag.rs +++ b/src/librustc_mir/transform/add_retag.rs @@ -58,10 +58,14 @@ fn may_be_reference(ty: Ty<'tcx>) -> bool { } impl<'tcx> MirPass<'tcx> for AddRetag { - fn run_pass(&self, tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut BodyAndCache<'tcx>) { + fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut BodyAndCache<'tcx>) { if !tcx.sess.opts.debugging_opts.mir_emit_retag { return; } + + // We need an `AllCallEdges` pass before we can do any work. + super::add_call_guards::AllCallEdges.run_pass(tcx, src, body); + let (span, arg_count) = (body.span, body.arg_count); let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut(); let needs_retag = |place: &Place<'tcx>| { diff --git a/src/librustc_mir/transform/check_consts/mod.rs b/src/librustc_mir/transform/check_consts/mod.rs index bce3a506b1d..1f916d5fc1d 100644 --- a/src/librustc_mir/transform/check_consts/mod.rs +++ b/src/librustc_mir/transform/check_consts/mod.rs @@ -13,7 +13,7 @@ use std::fmt; pub use self::qualifs::Qualif; -pub mod ops; +mod ops; pub mod qualifs; mod resolver; pub mod validation; diff --git a/src/librustc_mir/transform/check_consts/ops.rs b/src/librustc_mir/transform/check_consts/ops.rs index af7af7388bd..b5e62aa2013 100644 --- a/src/librustc_mir/transform/check_consts/ops.rs +++ b/src/librustc_mir/transform/check_consts/ops.rs @@ -90,16 +90,6 @@ impl NonConstOp for FnCallNonConst { } } -/// A function call where the callee is not a function definition or function pointer, e.g. a -/// closure. -/// -/// This can be subdivided in the future to produce a better error message. -#[derive(Debug)] -pub struct FnCallOther; -impl NonConstOp for FnCallOther { - const IS_SUPPORTED_IN_MIRI: bool = false; -} - /// A call to a `#[unstable]` const fn or `#[rustc_const_unstable]` function. /// /// Contains the name of the feature that would allow the use of this function. @@ -123,8 +113,6 @@ impl NonConstOp for FnCallUnstable { #[derive(Debug)] pub struct HeapAllocation; impl NonConstOp for HeapAllocation { - const IS_SUPPORTED_IN_MIRI: bool = false; - fn emit_error(&self, item: &Item<'_, '_>, span: Span) { let mut err = struct_span_err!( item.tcx.sess, diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index e4a0b9cdb48..4cc42c0408f 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -495,11 +495,11 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { } } - fn visit_terminator_kind(&mut self, kind: &TerminatorKind<'tcx>, location: Location) { - trace!("visit_terminator_kind: kind={:?} location={:?}", kind, location); - self.super_terminator_kind(kind, location); + fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) { + trace!("visit_terminator: terminator={:?} location={:?}", terminator, location); + self.super_terminator(terminator, location); - match kind { + match &terminator.kind { TerminatorKind::Call { func, .. } => { let fn_ty = func.ty(*self.body, self.tcx); @@ -511,8 +511,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> { return; } _ => { - self.check_op(ops::FnCallOther); - return; + span_bug!(terminator.source_info.span, "invalid callee of type {:?}", fn_ty) } }; diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index 3ce9b875e16..9f6b1963ce7 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -641,13 +641,19 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: DefId) { } } - let mut unsafe_blocks: Vec<_> = unsafe_blocks.iter().collect(); - unsafe_blocks.sort_by_cached_key(|(hir_id, _)| tcx.hir().hir_id_to_node_id(*hir_id)); - let used_unsafe: FxHashSet<_> = - unsafe_blocks.iter().flat_map(|&&(id, used)| used.then_some(id)).collect(); - for &(block_id, is_used) in unsafe_blocks { - if !is_used { - report_unused_unsafe(tcx, &used_unsafe, block_id); + let (mut unsafe_used, mut unsafe_unused): (FxHashSet<_>, Vec<_>) = Default::default(); + for &(block_id, is_used) in unsafe_blocks.iter() { + if is_used { + unsafe_used.insert(block_id); + } else { + unsafe_unused.push(block_id); } } + // The unused unsafe blocks might not be in source order; sort them so that the unused unsafe + // error messages are properly aligned and the issue-45107 and lint-unused-unsafe tests pass. + unsafe_unused.sort_by_cached_key(|hir_id| tcx.hir().span(*hir_id)); + + for &block_id in &unsafe_unused { + report_unused_unsafe(tcx, &unsafe_used, block_id); + } } diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 5a00f206a76..cf1c70241bc 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -173,7 +173,10 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine { const GLOBAL_KIND: Option<!> = None; // no copying of globals from `tcx` to machine memory - const CHECK_ALIGN: bool = false; + #[inline(always)] + fn enforce_alignment(_memory_extra: &Self::MemoryExtra) -> bool { + false + } #[inline(always)] fn enforce_validity(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool { @@ -287,8 +290,11 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine { } #[inline(always)] - fn stack_push(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> { - Ok(()) + fn init_frame_extra( + _ecx: &mut InterpCx<'mir, 'tcx, Self>, + frame: Frame<'mir, 'tcx>, + ) -> InterpResult<'tcx, Frame<'mir, 'tcx>> { + Ok(frame) } } @@ -575,11 +581,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { return None; } - // FIXME we need to revisit this for #67176 - if rvalue.needs_subst() { - return None; - } - // Perform any special handling for specific Rvalue types. // Generally, checks here fall into one of two categories: // 1. Additional checking to provide useful lints to the user @@ -620,6 +621,11 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { _ => {} } + // FIXME we need to revisit this for #67176 + if rvalue.needs_subst() { + return None; + } + self.use_ecx(|this| { trace!("calling eval_rvalue_into_place(rvalue = {:?}, place = {:?})", rvalue, place); this.ecx.eval_rvalue_into_place(rvalue, place)?; diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 8121d4ead13..bfa13abb871 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -582,7 +582,7 @@ impl Inliner<'tcx> { let tuple_tmp_args = tuple_tys.iter().enumerate().map(|(i, ty)| { // This is e.g., `tuple_tmp.0` in our example above. let tuple_field = - Operand::Move(tcx.mk_place_field(tuple.clone(), Field::new(i), ty.expect_ty())); + Operand::Move(tcx.mk_place_field(tuple, Field::new(i), ty.expect_ty())); // Spill to a local to make e.g., `tmp0`. self.create_temp_if_necessary(tuple_field, callsite, caller_body) diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 81ea57e4c00..8db0b39a497 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -287,10 +287,8 @@ fn run_optimization_passes<'tcx>( // AddMovesForPackedDrops needs to run after drop // elaboration. &add_moves_for_packed_drops::AddMovesForPackedDrops, - // AddRetag needs to run after ElaborateDrops, and it needs - // an AllCallEdges pass right before it. Otherwise it should - // run fairly late, but before optimizations begin. - &add_call_guards::AllCallEdges, + // `AddRetag` needs to run after `ElaborateDrops`. Otherwise it should run fairly late, + // but before optimizations begin. &add_retag::AddRetag, &simplify::SimplifyCfg::new("elaborate-drops"), // No lifetime analysis based on borrowing can be done from here on out. diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index 9579fe1f405..71c2e3bf060 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -835,7 +835,11 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { if self.keep_original { rhs.clone() } else { - let unit = Rvalue::Aggregate(box AggregateKind::Tuple, vec![]); + let unit = Rvalue::Use(Operand::Constant(box Constant { + span: statement.source_info.span, + user_ty: None, + literal: ty::Const::zero_sized(self.tcx, self.tcx.types.unit), + })); mem::replace(rhs, unit) }, statement.source_info, diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs index c0da2c446d6..c4971b25655 100644 --- a/src/librustc_mir/transform/simplify.rs +++ b/src/librustc_mir/transform/simplify.rs @@ -306,49 +306,82 @@ pub struct SimplifyLocals; impl<'tcx> MirPass<'tcx> for SimplifyLocals { fn run_pass(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut BodyAndCache<'tcx>) { trace!("running SimplifyLocals on {:?}", source); - let locals = { + + // First, we're going to get a count of *actual* uses for every `Local`. + // Take a look at `DeclMarker::visit_local()` to see exactly what is ignored. + let mut used_locals = { let read_only_cache = read_only!(body); - let mut marker = DeclMarker { locals: BitSet::new_empty(body.local_decls.len()), body }; + let mut marker = DeclMarker::new(body); marker.visit_body(&read_only_cache); - // Return pointer and arguments are always live - marker.locals.insert(RETURN_PLACE); - for arg in body.args_iter() { - marker.locals.insert(arg); - } - marker.locals + marker.local_counts }; - let map = make_local_map(&mut body.local_decls, locals); - // Update references to all vars and tmps now - LocalUpdater { map, tcx }.visit_body(body); - body.local_decls.shrink_to_fit(); + let arg_count = body.arg_count; + + // Next, we're going to remove any `Local` with zero actual uses. When we remove those + // `Locals`, we're also going to subtract any uses of other `Locals` from the `used_locals` + // count. For example, if we removed `_2 = discriminant(_1)`, then we'll subtract one from + // `use_counts[_1]`. That in turn might make `_1` unused, so we loop until we hit a + // fixedpoint where there are no more unused locals. + loop { + let mut remove_statements = RemoveStatements::new(&mut used_locals, arg_count, tcx); + remove_statements.visit_body(body); + + if !remove_statements.modified { + break; + } + } + + // Finally, we'll actually do the work of shrinking `body.local_decls` and remapping the `Local`s. + let map = make_local_map(&mut body.local_decls, used_locals, arg_count); + + // Only bother running the `LocalUpdater` if we actually found locals to remove. + if map.iter().any(Option::is_none) { + // Update references to all vars and tmps now + let mut updater = LocalUpdater { map, tcx }; + updater.visit_body(body); + + body.local_decls.shrink_to_fit(); + } } } /// Construct the mapping while swapping out unused stuff out from the `vec`. fn make_local_map<V>( - vec: &mut IndexVec<Local, V>, - mask: BitSet<Local>, + local_decls: &mut IndexVec<Local, V>, + used_locals: IndexVec<Local, usize>, + arg_count: usize, ) -> IndexVec<Local, Option<Local>> { - let mut map: IndexVec<Local, Option<Local>> = IndexVec::from_elem(None, &*vec); + let mut map: IndexVec<Local, Option<Local>> = IndexVec::from_elem(None, &*local_decls); let mut used = Local::new(0); - for alive_index in mask.iter() { + for (alive_index, count) in used_locals.iter_enumerated() { + // The `RETURN_PLACE` and arguments are always live. + if alive_index.as_usize() > arg_count && *count == 0 { + continue; + } + map[alive_index] = Some(used); if alive_index != used { - vec.swap(alive_index, used); + local_decls.swap(alive_index, used); } used.increment_by(1); } - vec.truncate(used.index()); + local_decls.truncate(used.index()); map } struct DeclMarker<'a, 'tcx> { - pub locals: BitSet<Local>, + pub local_counts: IndexVec<Local, usize>, pub body: &'a Body<'tcx>, } +impl<'a, 'tcx> DeclMarker<'a, 'tcx> { + pub fn new(body: &'a Body<'tcx>) -> Self { + Self { local_counts: IndexVec::from_elem(0, &body.local_decls), body } + } +} + impl<'a, 'tcx> Visitor<'tcx> for DeclMarker<'a, 'tcx> { fn visit_local(&mut self, local: &Local, ctx: PlaceContext, location: Location) { // Ignore storage markers altogether, they get removed along with their otherwise unused @@ -368,21 +401,39 @@ impl<'a, 'tcx> Visitor<'tcx> for DeclMarker<'a, 'tcx> { if location.statement_index != block.statements.len() { let stmt = &block.statements[location.statement_index]; + fn can_skip_constant(c: &ty::Const<'tcx>) -> bool { + // Keep assignments from unevaluated constants around, since the + // evaluation may report errors, even if the use of the constant + // is dead code. + !matches!(c.val, ty::ConstKind::Unevaluated(..)) + } + + fn can_skip_operand(o: &Operand<'_>) -> bool { + match o { + Operand::Copy(_) | Operand::Move(_) => true, + Operand::Constant(c) => can_skip_constant(c.literal), + } + } + if let StatementKind::Assign(box (dest, rvalue)) = &stmt.kind { if !dest.is_indirect() && dest.local == *local { - if let Rvalue::Use(Operand::Constant(c)) = rvalue { - match c.literal.val { - // Keep assignments from unevaluated constants around, since the - // evaluation may report errors, even if the use of the constant - // is dead code. - ty::ConstKind::Unevaluated(..) => {} - _ => { - trace!("skipping store of const value {:?} to {:?}", c, dest); - return; - } + let can_skip = match rvalue { + Rvalue::Use(op) => can_skip_operand(op), + Rvalue::Discriminant(_) => true, + Rvalue::BinaryOp(_, l, r) | Rvalue::CheckedBinaryOp(_, l, r) => { + can_skip_operand(l) && can_skip_operand(r) } - } else if let Rvalue::Discriminant(d) = rvalue { - trace!("skipping store of discriminant value {:?} to {:?}", d, dest); + Rvalue::Repeat(op, c) => can_skip_operand(op) && can_skip_constant(c), + Rvalue::AddressOf(_, _) => true, + Rvalue::Len(_) => true, + Rvalue::UnaryOp(_, op) => can_skip_operand(op), + Rvalue::Aggregate(_, operands) => operands.iter().all(can_skip_operand), + + _ => false, + }; + + if can_skip { + trace!("skipping store of {:?} to {:?}", rvalue, dest); return; } } @@ -390,29 +441,106 @@ impl<'a, 'tcx> Visitor<'tcx> for DeclMarker<'a, 'tcx> { } } - self.locals.insert(*local); + self.local_counts[*local] += 1; } } -struct LocalUpdater<'tcx> { - map: IndexVec<Local, Option<Local>>, +struct StatementDeclMarker<'a, 'tcx> { + used_locals: &'a mut IndexVec<Local, usize>, + statement: &'a Statement<'tcx>, +} + +impl<'a, 'tcx> StatementDeclMarker<'a, 'tcx> { + pub fn new( + used_locals: &'a mut IndexVec<Local, usize>, + statement: &'a Statement<'tcx>, + ) -> Self { + Self { used_locals, statement } + } +} + +impl<'a, 'tcx> Visitor<'tcx> for StatementDeclMarker<'a, 'tcx> { + fn visit_local(&mut self, local: &Local, context: PlaceContext, _location: Location) { + // Skip the lvalue for assignments + if let StatementKind::Assign(box (p, _)) = self.statement.kind { + if p.local == *local && context.is_place_assignment() { + return; + } + } + + let use_count = &mut self.used_locals[*local]; + // If this is the local we're removing... + if *use_count != 0 { + *use_count -= 1; + } + } +} + +struct RemoveStatements<'a, 'tcx> { + used_locals: &'a mut IndexVec<Local, usize>, + arg_count: usize, tcx: TyCtxt<'tcx>, + modified: bool, } -impl<'tcx> MutVisitor<'tcx> for LocalUpdater<'tcx> { +impl<'a, 'tcx> RemoveStatements<'a, 'tcx> { + fn new( + used_locals: &'a mut IndexVec<Local, usize>, + arg_count: usize, + tcx: TyCtxt<'tcx>, + ) -> Self { + Self { used_locals, arg_count, tcx, modified: false } + } + + fn keep_local(&self, l: Local) -> bool { + trace!("keep_local({:?}): count: {:?}", l, self.used_locals[l]); + l.as_usize() <= self.arg_count || self.used_locals[l] != 0 + } +} + +impl<'a, 'tcx> MutVisitor<'tcx> for RemoveStatements<'a, 'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } fn visit_basic_block_data(&mut self, block: BasicBlock, data: &mut BasicBlockData<'tcx>) { // Remove unnecessary StorageLive and StorageDead annotations. - data.statements.retain(|stmt| match &stmt.kind { - StatementKind::StorageLive(l) | StatementKind::StorageDead(l) => self.map[*l].is_some(), - StatementKind::Assign(box (place, _)) => self.map[place.local].is_some(), - _ => true, + let mut i = 0usize; + data.statements.retain(|stmt| { + let keep = match &stmt.kind { + StatementKind::StorageLive(l) | StatementKind::StorageDead(l) => { + self.keep_local(*l) + } + StatementKind::Assign(box (place, _)) => self.keep_local(place.local), + _ => true, + }; + + if !keep { + trace!("removing statement {:?}", stmt); + self.modified = true; + + let mut visitor = StatementDeclMarker::new(self.used_locals, stmt); + visitor.visit_statement(stmt, Location { block, statement_index: i }); + } + + i += 1; + + keep }); + self.super_basic_block_data(block, data); } +} + +struct LocalUpdater<'tcx> { + map: IndexVec<Local, Option<Local>>, + tcx: TyCtxt<'tcx>, +} + +impl<'tcx> MutVisitor<'tcx> for LocalUpdater<'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } fn visit_local(&mut self, l: &mut Local, _: PlaceContext, _: Location) { *l = self.map[*l].unwrap(); diff --git a/src/librustc_mir/util/aggregate.rs b/src/librustc_mir/util/aggregate.rs index e77d264b7ce..1a22eee3a03 100644 --- a/src/librustc_mir/util/aggregate.rs +++ b/src/librustc_mir/util/aggregate.rs @@ -56,7 +56,7 @@ pub fn expand_aggregate<'tcx>( let offset = i as u32; assert_eq!(offset as usize, i); tcx.mk_place_elem( - lhs.clone(), + lhs, ProjectionElem::ConstantIndex { offset, // FIXME(eddyb) `min_length` doesn't appear to be used. @@ -66,7 +66,7 @@ pub fn expand_aggregate<'tcx>( ) } else { let field = Field::new(active_field_index.unwrap_or(i)); - tcx.mk_place_field(lhs.clone(), field, ty) + tcx.mk_place_field(lhs, field, ty) }; Statement { source_info, kind: StatementKind::Assign(box (lhs_field, Rvalue::Use(op))) } }) diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index e3a96ca7896..8286793b532 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -212,7 +212,7 @@ where assert_eq!(self.elaborator.param_env().reveal, Reveal::All); let field_ty = tcx.normalize_erasing_regions(self.elaborator.param_env(), f.ty(tcx, substs)); - (tcx.mk_place_field(base_place.clone(), field, field_ty), subpath) + (tcx.mk_place_field(base_place, field, field_ty), subpath) }) .collect() } @@ -340,7 +340,7 @@ where .enumerate() .map(|(i, &ty)| { ( - self.tcx().mk_place_field(self.place.clone(), Field::new(i), ty), + self.tcx().mk_place_field(self.place, Field::new(i), ty), self.elaborator.field_subpath(self.path, Field::new(i)), ) }) @@ -353,7 +353,7 @@ where fn open_drop_for_box(&mut self, adt: &'tcx ty::AdtDef, substs: SubstsRef<'tcx>) -> BasicBlock { debug!("open_drop_for_box({:?}, {:?}, {:?})", self, adt, substs); - let interior = self.tcx().mk_place_deref(self.place.clone()); + let interior = self.tcx().mk_place_deref(self.place); let interior_path = self.elaborator.deref_subpath(self.path); let succ = self.succ; // FIXME(#43234) @@ -434,7 +434,7 @@ where if let Some(variant_path) = subpath { let base_place = tcx.mk_place_elem( - self.place.clone(), + self.place, ProjectionElem::Downcast(Some(variant.ident.name), variant_index), ); let fields = self.move_paths_for_fields(base_place, variant_path, &variant, substs); @@ -622,7 +622,7 @@ where (Rvalue::Use(copy(cur.into())), Rvalue::BinaryOp(BinOp::Offset, move_(cur.into()), one)) } else { ( - Rvalue::AddressOf(Mutability::Mut, tcx.mk_place_index(self.place.clone(), cur)), + Rvalue::AddressOf(Mutability::Mut, tcx.mk_place_index(self.place, cur)), Rvalue::BinaryOp(BinOp::Add, move_(cur.into()), one), ) }; @@ -654,7 +654,7 @@ where self.elaborator.patch().patch_terminator( drop_block, TerminatorKind::Drop { - location: tcx.mk_place_deref(ptr.clone()), + location: tcx.mk_place_deref(ptr), target: loop_block, unwind: unwind.into_option(), }, @@ -682,7 +682,7 @@ where .map(|i| { ( tcx.mk_place_elem( - self.place.clone(), + self.place, ProjectionElem::ConstantIndex { offset: i, min_length: size, @@ -719,8 +719,8 @@ where switch_ty: tcx.types.usize, values: From::from(USIZE_SWITCH_ZERO), targets: vec![ - self.drop_loop_pair(ety, false, len.clone()), - self.drop_loop_pair(ety, true, len.clone()), + self.drop_loop_pair(ety, false, len), + self.drop_loop_pair(ety, true, len), ], }, }), @@ -912,7 +912,7 @@ where .map(|(i, f)| { let field = Field::new(i); let field_ty = f.ty(tcx, substs); - Operand::Move(tcx.mk_place_field(self.place.clone(), field, field_ty)) + Operand::Move(tcx.mk_place_field(self.place, field, field_ty)) }) .collect(); diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index 64221c41bff..efb84ef35f3 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -254,6 +254,7 @@ pub fn write_mir_pretty<'tcx>( Ok(()) } +/// Write out a human-readable textual representation for the given function. pub fn write_mir_fn<'tcx, F>( tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, diff --git a/src/librustc_mir_build/build/block.rs b/src/librustc_mir_build/build/block.rs index 8c41554bc85..3f94fb82890 100644 --- a/src/librustc_mir_build/build/block.rs +++ b/src/librustc_mir_build/build/block.rs @@ -2,8 +2,8 @@ use crate::build::matches::ArmHasGuard; use crate::build::ForGuard::OutsideGuard; use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder}; use crate::hair::*; -use rustc_middle::mir::*; use rustc_hir as hir; +use rustc_middle::mir::*; use rustc_span::Span; impl<'a, 'tcx> Builder<'a, 'tcx> { @@ -29,7 +29,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // This is a `break`-able block let exit_block = this.cfg.start_new_block(); let block_exit = - this.in_breakable_scope(None, exit_block, destination.clone(), |this| { + this.in_breakable_scope(None, exit_block, destination, |this| { this.ast_block_stmts(destination, block, span, stmts, expr, safety_mode) }); this.cfg.goto(unpack!(block_exit), source_info, exit_block); @@ -187,7 +187,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { if destination_ty.is_unit() { // We only want to assign an implicit `()` as the return value of the block if the // block does not diverge. (Otherwise, we may try to assign a unit to a `!`-type.) - this.cfg.push_assign_unit(block, source_info, destination); + this.cfg.push_assign_unit(block, source_info, destination, this.hir.tcx()); } } // Finally, we pop all the let scopes before exiting out from the scope of block diff --git a/src/librustc_mir_build/build/cfg.rs b/src/librustc_mir_build/build/cfg.rs index f5828c4ac1f..42e2b242d77 100644 --- a/src/librustc_mir_build/build/cfg.rs +++ b/src/librustc_mir_build/build/cfg.rs @@ -2,6 +2,7 @@ use crate::build::CFG; use rustc_middle::mir::*; +use rustc_middle::ty::{self, TyCtxt}; impl<'tcx> CFG<'tcx> { crate fn block_data(&self, blk: BasicBlock) -> &BasicBlockData<'tcx> { @@ -58,12 +59,17 @@ impl<'tcx> CFG<'tcx> { block: BasicBlock, source_info: SourceInfo, place: Place<'tcx>, + tcx: TyCtxt<'tcx>, ) { self.push_assign( block, source_info, place, - Rvalue::Aggregate(box AggregateKind::Tuple, vec![]), + Rvalue::Use(Operand::Constant(box Constant { + span: source_info.span, + user_ty: None, + literal: ty::Const::zero_sized(tcx, tcx.types.unit), + })), ); } diff --git a/src/librustc_mir_build/build/expr/as_rvalue.rs b/src/librustc_mir_build/build/expr/as_rvalue.rs index 20ef763e90c..b6f46aab416 100644 --- a/src/librustc_mir_build/build/expr/as_rvalue.rs +++ b/src/librustc_mir_build/build/expr/as_rvalue.rs @@ -225,7 +225,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } ExprKind::Assign { .. } | ExprKind::AssignOp { .. } => { block = unpack!(this.stmt_expr(block, expr, None)); - block.and(this.unit_rvalue()) + block.and(Rvalue::Use(Operand::Constant(box Constant { + span: expr_span, + user_ty: None, + literal: ty::Const::zero_sized(this.hir.tcx(), this.hir.tcx().types.unit), + }))) } ExprKind::Yield { .. } | ExprKind::Literal { .. } diff --git a/src/librustc_mir_build/build/expr/into.rs b/src/librustc_mir_build/build/expr/into.rs index 6b93755e9da..093e5a8d6a2 100644 --- a/src/librustc_mir_build/build/expr/into.rs +++ b/src/librustc_mir_build/build/expr/into.rs @@ -3,10 +3,10 @@ use crate::build::expr::category::{Category, RvalueFunc}; use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder}; use crate::hair::*; -use rustc_middle::mir::*; -use rustc_middle::ty::{self, CanonicalUserTypeAnnotation}; use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; +use rustc_middle::mir::*; +use rustc_middle::ty::{self, CanonicalUserTypeAnnotation}; use rustc_span::symbol::sym; use rustc_target::spec::abi::Abi; @@ -139,31 +139,26 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Start the loop. this.cfg.goto(block, source_info, loop_block); - this.in_breakable_scope( - Some(loop_block), - exit_block, - destination.clone(), - move |this| { - // conduct the test, if necessary - let body_block = this.cfg.start_new_block(); - let diverge_cleanup = this.diverge_cleanup(); - this.cfg.terminate( - loop_block, - source_info, - TerminatorKind::FalseUnwind { - real_target: body_block, - unwind: Some(diverge_cleanup), - }, - ); - - // The “return” value of the loop body must always be an unit. We therefore - // introduce a unit temporary as the destination for the loop body. - let tmp = this.get_unit_temp(); - // Execute the body, branching back to the test. - let body_block_end = unpack!(this.into(tmp, body_block, body)); - this.cfg.goto(body_block_end, source_info, loop_block); - }, - ); + this.in_breakable_scope(Some(loop_block), exit_block, destination, move |this| { + // conduct the test, if necessary + let body_block = this.cfg.start_new_block(); + let diverge_cleanup = this.diverge_cleanup(); + this.cfg.terminate( + loop_block, + source_info, + TerminatorKind::FalseUnwind { + real_target: body_block, + unwind: Some(diverge_cleanup), + }, + ); + + // The “return” value of the loop body must always be an unit. We therefore + // introduce a unit temporary as the destination for the loop body. + let tmp = this.get_unit_temp(); + // Execute the body, branching back to the test. + let body_block_end = unpack!(this.into(tmp, body_block, body)); + this.cfg.goto(body_block_end, source_info, loop_block); + }); exit_block.unit() } ExprKind::Call { ty, fun, args, from_hir_call } => { @@ -278,26 +273,25 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let field_names = this.hir.all_fields(adt_def, variant_index); - let fields = - if let Some(FruInfo { base, field_types }) = base { - let base = unpack!(block = this.as_place(block, base)); - - // MIR does not natively support FRU, so for each - // base-supplied field, generate an operand that - // reads it from the base. - field_names - .into_iter() - .zip(field_types.into_iter()) - .map(|(n, ty)| match fields_map.get(&n) { - Some(v) => v.clone(), - None => this.consume_by_copy_or_move( - this.hir.tcx().mk_place_field(base.clone(), n, ty), - ), - }) - .collect() - } else { - field_names.iter().filter_map(|n| fields_map.get(n).cloned()).collect() - }; + let fields = if let Some(FruInfo { base, field_types }) = base { + let base = unpack!(block = this.as_place(block, base)); + + // MIR does not natively support FRU, so for each + // base-supplied field, generate an operand that + // reads it from the base. + field_names + .into_iter() + .zip(field_types.into_iter()) + .map(|(n, ty)| match fields_map.get(&n) { + Some(v) => v.clone(), + None => this.consume_by_copy_or_move( + this.hir.tcx().mk_place_field(base, n, ty), + ), + }) + .collect() + } else { + field_names.iter().filter_map(|n| fields_map.get(n).cloned()).collect() + }; let inferred_ty = expr.ty; let user_ty = user_ty.map(|ty| { @@ -331,7 +325,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { | ExprKind::LlvmInlineAsm { .. } | ExprKind::Return { .. } => { unpack!(block = this.stmt_expr(block, expr, None)); - this.cfg.push_assign_unit(block, source_info, destination); + this.cfg.push_assign_unit(block, source_info, destination, this.hir.tcx()); block.unit() } diff --git a/src/librustc_mir_build/build/matches/mod.rs b/src/librustc_mir_build/build/matches/mod.rs index a4a9271669e..10ffc81f179 100644 --- a/src/librustc_mir_build/build/matches/mod.rs +++ b/src/librustc_mir_build/build/matches/mod.rs @@ -1903,9 +1903,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.schedule_drop_for_binding(binding.var_id, binding.span, OutsideGuard); } let rvalue = match binding.binding_mode { - BindingMode::ByValue => { - Rvalue::Use(self.consume_by_copy_or_move(binding.source.clone())) - } + BindingMode::ByValue => Rvalue::Use(self.consume_by_copy_or_move(binding.source)), BindingMode::ByRef(borrow_kind) => { Rvalue::Ref(re_erased, borrow_kind, binding.source) } diff --git a/src/librustc_mir_build/build/matches/util.rs b/src/librustc_mir_build/build/matches/util.rs index 393af108a6e..a97ddeb0600 100644 --- a/src/librustc_mir_build/build/matches/util.rs +++ b/src/librustc_mir_build/build/matches/util.rs @@ -15,11 +15,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { subpatterns .iter() .map(|fieldpat| { - let place = self.hir.tcx().mk_place_field( - place.clone(), - fieldpat.field, - fieldpat.pattern.ty, - ); + let place = + self.hir.tcx().mk_place_field(place, fieldpat.field, fieldpat.pattern.ty); MatchPair::new(place, &fieldpat.pattern) }) .collect() @@ -44,14 +41,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { match_pairs.extend(prefix.iter().enumerate().map(|(idx, subpattern)| { let elem = ProjectionElem::ConstantIndex { offset: idx as u32, min_length, from_end: false }; - let place = tcx.mk_place_elem(place.clone(), elem); + let place = tcx.mk_place_elem(*place, elem); MatchPair::new(place, subpattern) })); if let Some(subslice_pat) = opt_slice { let suffix_len = suffix.len() as u32; let subslice = tcx.mk_place_elem( - place.clone(), + *place, ProjectionElem::Subslice { from: prefix.len() as u32, to: if exact_size { min_length - suffix_len } else { suffix_len }, @@ -68,7 +65,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { min_length, from_end: !exact_size, }; - let place = tcx.mk_place_elem(place.clone(), elem); + let place = tcx.mk_place_elem(*place, elem); MatchPair::new(place, subpattern) })); } diff --git a/src/librustc_mir_build/build/misc.rs b/src/librustc_mir_build/build/misc.rs index 8f98dd9b70e..578b862b905 100644 --- a/src/librustc_mir_build/build/misc.rs +++ b/src/librustc_mir_build/build/misc.rs @@ -32,10 +32,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Operand::Constant(constant) } - crate fn unit_rvalue(&mut self) -> Rvalue<'tcx> { - Rvalue::Aggregate(box AggregateKind::Tuple, vec![]) - } - // Returns a zero literal operand for the appropriate type, works for // bool, char and integers. crate fn zero_literal(&mut self, span: Span, ty: Ty<'tcx>) -> Operand<'tcx> { diff --git a/src/librustc_mir_build/build/mod.rs b/src/librustc_mir_build/build/mod.rs index 04cb509d44e..6911c09c518 100644 --- a/src/librustc_mir_build/build/mod.rs +++ b/src/librustc_mir_build/build/mod.rs @@ -3,6 +3,7 @@ use crate::build::scope::DropKind; use crate::hair::cx::Cx; use crate::hair::{BindingMode, LintLevel, PatKind}; use rustc_attr::{self as attr, UnwindAttr}; +use rustc_errors::ErrorReported; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::lang_items; @@ -59,7 +60,7 @@ fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> BodyAndCache<'_> { tcx.infer_ctxt().enter(|infcx| { let cx = Cx::new(&infcx, id); - let body = if cx.tables().tainted_by_errors { + let body = if let Some(ErrorReported) = cx.tables().tainted_by_errors { build::construct_error(cx, body_id) } else if cx.body_owner_kind.is_fn_or_closure() { // fetch the fully liberated fn signature (that is, all bound diff --git a/src/librustc_mir_build/build/scope.rs b/src/librustc_mir_build/build/scope.rs index 3689e5cb9d8..d88cbf94513 100644 --- a/src/librustc_mir_build/build/scope.rs +++ b/src/librustc_mir_build/build/scope.rs @@ -523,7 +523,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { unpack!(block = self.into(destination, block, value)); self.block_context.pop(); } else { - self.cfg.push_assign_unit(block, source_info, destination) + self.cfg.push_assign_unit(block, source_info, destination, self.hir.tcx()) } } else { assert!(value.is_none(), "`return` and `break` should have a destination"); diff --git a/src/librustc_mir_build/hair/cx/mod.rs b/src/librustc_mir_build/hair/cx/mod.rs index 503bd26d51f..18a981dfea1 100644 --- a/src/librustc_mir_build/hair/cx/mod.rs +++ b/src/librustc_mir_build/hair/cx/mod.rs @@ -176,7 +176,7 @@ impl<'a, 'tcx> Cx<'a, 'tcx> { .tcx .associated_items(trait_def_id) .filter_by_name_unhygienic(method_name) - .find(|item| item.kind == ty::AssocKind::Method) + .find(|item| item.kind == ty::AssocKind::Fn) .expect("trait method not found"); let method_ty = self.tcx.type_of(item.def_id); diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs index 12b9b682682..da6d863f239 100644 --- a/src/librustc_parse/parser/diagnostics.rs +++ b/src/librustc_parse/parser/diagnostics.rs @@ -579,11 +579,13 @@ impl<'a> Parser<'a> { /// Keep in mind that given that `outer_op.is_comparison()` holds and comparison ops are left /// associative we can infer that we have: /// + /// ```text /// outer_op /// / \ /// inner_op r2 /// / \ /// l1 r1 + /// ``` pub(super) fn check_no_chained_comparison( &mut self, inner_op: &Expr, @@ -1054,6 +1056,39 @@ impl<'a> Parser<'a> { } } + pub(super) fn try_macro_suggestion(&mut self) -> PResult<'a, P<Expr>> { + let is_try = self.token.is_keyword(kw::Try); + let is_questionmark = self.look_ahead(1, |t| t == &token::Not); //check for ! + let is_open = self.look_ahead(2, |t| t == &token::OpenDelim(token::Paren)); //check for ( + + if is_try && is_questionmark && is_open { + let lo = self.token.span; + self.bump(); //remove try + self.bump(); //remove ! + let try_span = lo.to(self.token.span); //we take the try!( span + self.bump(); //remove ( + let is_empty = self.token == token::CloseDelim(token::Paren); //check if the block is empty + self.consume_block(token::Paren, ConsumeClosingDelim::No); //eat the block + let hi = self.token.span; + self.bump(); //remove ) + let mut err = self.struct_span_err(lo.to(hi), "use of deprecated `try` macro"); + err.note("in the 2018 edition `try` is a reserved keyword, and the `try!()` macro is deprecated"); + let prefix = if is_empty { "" } else { "alternatively, " }; + if !is_empty { + err.multipart_suggestion( + "you can use the `?` operator instead", + vec![(try_span, "".to_owned()), (hi, "?".to_owned())], + Applicability::MachineApplicable, + ); + } + err.span_suggestion(lo.shrink_to_lo(), &format!("{}you can still access the deprecated `try!()` macro using the \"raw identifier\" syntax", prefix), "r#".to_string(), Applicability::MachineApplicable); + err.emit(); + Ok(self.mk_expr_err(lo.to(hi))) + } else { + Err(self.expected_expression_found()) // The user isn't trying to invoke the try! macro + } + } + /// Recovers a situation like `for ( $pat in $expr )` /// and suggest writing `for $pat in $expr` instead. /// diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs index cbff99f8da6..986f5410e26 100644 --- a/src/librustc_parse/parser/expr.rs +++ b/src/librustc_parse/parser/expr.rs @@ -1006,7 +1006,7 @@ impl<'a> Parser<'a> { let expr = self.mk_expr(lo.to(self.prev_token.span), ExprKind::Lit(literal), attrs); self.maybe_recover_from_bad_qpath(expr, true) } - None => Err(self.expected_expression_found()), + None => self.try_macro_suggestion(), } } @@ -1846,11 +1846,9 @@ impl<'a> Parser<'a> { } fn is_try_block(&self) -> bool { - self.token.is_keyword(kw::Try) && - self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace)) && - self.token.uninterpolated_span().rust_2018() && - // Prevent `while try {} {}`, `if try {} {} else {}`, etc. - !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL) + self.token.is_keyword(kw::Try) + && self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace)) + && self.token.uninterpolated_span().rust_2018() } /// Parses an `async move? {...}` expression. diff --git a/src/librustc_parse/parser/generics.rs b/src/librustc_parse/parser/generics.rs index 3442c5081c1..f4729e306f8 100644 --- a/src/librustc_parse/parser/generics.rs +++ b/src/librustc_parse/parser/generics.rs @@ -8,7 +8,7 @@ use rustc_span::symbol::{kw, sym}; impl<'a> Parser<'a> { /// Parses bounds of a lifetime parameter `BOUND + BOUND + BOUND`, possibly with trailing `+`. /// - /// ``` + /// ```text /// BOUND = LT_BOUND (e.g., `'a`) /// ``` fn parse_lt_param_bounds(&mut self) -> GenericBounds { diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index 798eb85f36f..ae8a20f209b 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -743,7 +743,7 @@ impl<'a> Parser<'a> { /// Parses a `UseTree`. /// - /// ``` + /// ```text /// USE_TREE = [`::`] `*` | /// [`::`] `{` USE_TREE_LIST `}` | /// PATH `::` `*` | @@ -792,7 +792,7 @@ impl<'a> Parser<'a> { /// Parses a `UseTreeKind::Nested(list)`. /// - /// ``` + /// ```text /// USE_TREE_LIST = Ø | (USE_TREE `,`)* USE_TREE [`,`] /// ``` fn parse_use_tree_list(&mut self) -> PResult<'a, Vec<(UseTree, ast::NodeId)>> { diff --git a/src/librustc_passes/check_const.rs b/src/librustc_passes/check_const.rs index f68213cc9c2..f409b040c69 100644 --- a/src/librustc_passes/check_const.rs +++ b/src/librustc_passes/check_const.rs @@ -74,16 +74,16 @@ enum ConstKind { } impl ConstKind { - fn for_body(body: &hir::Body<'_>, hir_map: Map<'_>) -> Option<Self> { - let is_const_fn = |id| hir_map.fn_sig_by_hir_id(id).unwrap().header.is_const(); - - let owner = hir_map.body_owner(body.id()); - let const_kind = match hir_map.body_owner_kind(owner) { + fn for_body(body: &hir::Body<'_>, tcx: TyCtxt<'_>) -> Option<Self> { + let owner = tcx.hir().body_owner(body.id()); + let const_kind = match tcx.hir().body_owner_kind(owner) { hir::BodyOwnerKind::Const => Self::Const, hir::BodyOwnerKind::Static(Mutability::Mut) => Self::StaticMut, hir::BodyOwnerKind::Static(Mutability::Not) => Self::Static, - hir::BodyOwnerKind::Fn if is_const_fn(owner) => Self::ConstFn, + hir::BodyOwnerKind::Fn if tcx.is_const_fn_raw(tcx.hir().local_def_id(owner)) => { + Self::ConstFn + } hir::BodyOwnerKind::Fn | hir::BodyOwnerKind::Closure => return None, }; @@ -211,7 +211,7 @@ impl<'tcx> Visitor<'tcx> for CheckConstVisitor<'tcx> { } fn visit_body(&mut self, body: &'tcx hir::Body<'tcx>) { - let kind = ConstKind::for_body(body, self.tcx.hir()); + let kind = ConstKind::for_body(body, self.tcx); self.recurse_into(kind, |this| intravisit::walk_body(this, body)); } diff --git a/src/librustc_passes/hir_id_validator.rs b/src/librustc_passes/hir_id_validator.rs index f5611654fc0..1e31b7c74b6 100644 --- a/src/librustc_passes/hir_id_validator.rs +++ b/src/librustc_passes/hir_id_validator.rs @@ -143,16 +143,6 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirIdValidator<'a, 'hir> { fn visit_id(&mut self, hir_id: HirId) { let owner = self.owner.expect("no owner"); - if hir_id == hir::DUMMY_HIR_ID { - self.error(|| { - format!( - "HirIdValidator: HirId {:?} is invalid", - self.hir_map.node_to_string(hir_id) - ) - }); - return; - } - if owner != hir_id.owner { self.error(|| { format!( diff --git a/src/librustc_passes/stability.rs b/src/librustc_passes/stability.rs index ad81aa30685..2e48fd9d659 100644 --- a/src/librustc_passes/stability.rs +++ b/src/librustc_passes/stability.rs @@ -610,7 +610,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) { // Warn if the user enables a lib feature multiple times. duplicate_feature_err(tcx.sess, *span, *feature); } - remaining_lib_features.insert(feature, span.clone()); + remaining_lib_features.insert(feature, *span); } // `stdbuild` has special handling for `libc`, so we need to // recognise the feature when building std. diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index a6d880667ad..51e1588c71c 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -928,7 +928,12 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { let macro_module_def_id = ty::DefIdTree::parent(self.tcx, self.tcx.hir().local_def_id(md.hir_id)).unwrap(); - let mut module_id = match self.tcx.hir().as_local_hir_id(macro_module_def_id) { + // FIXME(#71104) Should really be using just `as_local_hir_id` but + // some `DefId` do not seem to have a corresponding HirId. + let hir_id = macro_module_def_id + .as_local() + .and_then(|def_id| self.tcx.hir().opt_local_def_id_to_hir_id(def_id)); + let mut module_id = match hir_id { Some(module_id) if self.tcx.hir().is_hir_id_module(module_id) => module_id, // `module_id` doesn't correspond to a `mod`, return early (#63164, #65252). _ => return, @@ -1012,7 +1017,7 @@ impl DefIdVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'_, 'tcx> { struct NamePrivacyVisitor<'a, 'tcx> { tcx: TyCtxt<'tcx>, tables: &'a ty::TypeckTables<'tcx>, - current_item: hir::HirId, + current_item: Option<hir::HirId>, empty_tables: &'a ty::TypeckTables<'tcx>, } @@ -1028,7 +1033,7 @@ impl<'a, 'tcx> NamePrivacyVisitor<'a, 'tcx> { ) { // definition of the field let ident = Ident::new(kw::Invalid, use_ctxt); - let current_hir = self.current_item; + let current_hir = self.current_item.unwrap(); let def_id = self.tcx.adjust_ident_and_get_scope(ident, def.did, current_hir).1; if !def.is_enum() && !field.vis.is_accessible_from(def_id, self.tcx) { let label = if in_update_syntax { @@ -1074,7 +1079,7 @@ impl<'a, 'tcx> Visitor<'tcx> for NamePrivacyVisitor<'a, 'tcx> { } fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { - let orig_current_item = mem::replace(&mut self.current_item, item.hir_id); + let orig_current_item = mem::replace(&mut self.current_item, Some(item.hir_id)); let orig_tables = mem::replace(&mut self.tables, item_tables(self.tcx, item.hir_id, self.empty_tables)); intravisit::walk_item(self, item); @@ -1648,7 +1653,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { found_pub_static = true; intravisit::walk_impl_item(self, impl_item); } - AssocItemKind::Method { has_self: false } => { + AssocItemKind::Fn { has_self: false } => { found_pub_static = true; intravisit::walk_impl_item(self, impl_item); } @@ -1927,7 +1932,7 @@ impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> { let mut check = self.check(hir_id, vis); let (check_ty, is_assoc_ty) = match assoc_item_kind { - AssocItemKind::Const | AssocItemKind::Method { .. } => (true, false), + AssocItemKind::Const | AssocItemKind::Fn { .. } => (true, false), AssocItemKind::Type => (defaultness.has_value(), true), // `ty()` for opaque types is the underlying type, // it's not a part of interface, so we skip it. @@ -2059,7 +2064,7 @@ fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: DefId) { let mut visitor = NamePrivacyVisitor { tcx, tables: &empty_tables, - current_item: hir::DUMMY_HIR_ID, + current_item: None, empty_tables: &empty_tables, }; let (module, span, hir_id) = tcx.hir().get_module(module_def_id); diff --git a/src/librustc_query_system/dep_graph/query.rs b/src/librustc_query_system/dep_graph/query.rs index 4a4283b2a0c..fb313d2658f 100644 --- a/src/librustc_query_system/dep_graph/query.rs +++ b/src/librustc_query_system/dep_graph/query.rs @@ -15,7 +15,7 @@ impl<K: DepKind> DepGraphQuery<K> { let mut graph = Graph::with_capacity(nodes.len(), edges.len()); let mut indices = FxHashMap::default(); for node in nodes { - indices.insert(node.clone(), graph.add_node(node.clone())); + indices.insert(*node, graph.add_node(*node)); } for &(ref source, ref target) in edges { diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 0ad33f1a120..7e5415d000e 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -921,7 +921,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { Res::Def(DefKind::AssocFn, def_id) => { if cstore .associated_item_cloned_untracked(def_id, self.r.session) - .method_has_self_argument + .fn_has_self_parameter { self.r.has_self.insert(def_id); } diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index b51760cee1e..88ec4585b00 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -1031,7 +1031,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { /// Suggest a missing `self::` if that resolves to an correct module. /// - /// ``` + /// ```text /// | /// LL | use foo::Bar; /// | ^^^ did you mean `self::foo`? @@ -1083,7 +1083,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { /// Suggests a missing `super::` if that resolves to an correct module. /// - /// ``` + /// ```text /// | /// LL | use foo::Bar; /// | ^^^ did you mean `super::foo`? @@ -1103,7 +1103,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { /// Suggests a missing external crate name if that resolves to an correct module. /// - /// ``` + /// ```text /// | /// LL | use foobar::Baz; /// | ^^^^^^ did you mean `baz::foobar`? diff --git a/src/librustc_resolve/late/lifetimes.rs b/src/librustc_resolve/late/lifetimes.rs index 71ff9e5cbed..5b6a50f88db 100644 --- a/src/librustc_resolve/late/lifetimes.rs +++ b/src/librustc_resolve/late/lifetimes.rs @@ -643,13 +643,13 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { if param_name.name == kw::UnderscoreLifetime { // Pick the elided lifetime "definition" if one exists // and use it to make an elision scope. - self.lifetime_uses.insert(def_id.clone(), LifetimeUseSet::Many); + self.lifetime_uses.insert(def_id, LifetimeUseSet::Many); elision = Some(reg); } else { lifetimes.insert(name, reg); } } else { - self.lifetime_uses.insert(def_id.clone(), LifetimeUseSet::Many); + self.lifetime_uses.insert(def_id, LifetimeUseSet::Many); lifetimes.insert(name, reg); } } @@ -2117,7 +2117,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { }; let has_self = match assoc_item_kind { - Some(hir::AssocItemKind::Method { has_self }) => has_self, + Some(hir::AssocItemKind::Fn { has_self }) => has_self, _ => false, }; @@ -2704,14 +2704,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } fn insert_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime, def: Region) { - if lifetime_ref.hir_id == hir::DUMMY_HIR_ID { - span_bug!( - lifetime_ref.span, - "lifetime reference not renumbered, \ - probably a bug in rustc_ast::fold" - ); - } - debug!( "insert_lifetime: {} resolved to {:?} span={:?}", self.tcx.hir().node_to_string(lifetime_ref.hir_id), diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 5b93c73e07c..ba2541bc6c3 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -225,11 +225,14 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { collector.visit_pat(&arg.pat); for (id, ident, ..) in collector.collected_idents { - let hir_id = self.tcx.hir().node_id_to_hir_id(id); - let typ = match self.save_ctxt.tables.node_type_opt(hir_id) { - Some(s) => s.to_string(), - None => continue, - }; + // FIXME(#71104) Should really be using just `node_id_to_hir_id` but + // some `NodeId` do not seem to have a corresponding HirId. + let hir_id = self.tcx.hir().opt_node_id_to_hir_id(id); + let typ = + match hir_id.and_then(|hir_id| self.save_ctxt.tables.node_type_opt(hir_id)) { + Some(s) => s.to_string(), + None => continue, + }; if !self.span.filter_generated(ident.span) { let id = id_from_node_id(id, &self.save_ctxt); let span = self.span_from_span(ident.span); diff --git a/src/librustc_session/config.rs b/src/librustc_session/config.rs index aaf30c583e2..ba2a4d1d56f 100644 --- a/src/librustc_session/config.rs +++ b/src/librustc_session/config.rs @@ -1655,7 +1655,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { let output_types = parse_output_types(&debugging_opts, matches, error_format); let mut cg = build_codegen_options(matches, error_format); - let (disable_thinlto, codegen_units) = should_override_cgus_and_disable_thinlto( + let (disable_thinlto, mut codegen_units) = should_override_cgus_and_disable_thinlto( &output_types, matches, error_format, @@ -1672,6 +1672,16 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { "can't instrument with gcov profiling when compiling incrementally", ); } + if debugging_opts.profile { + match codegen_units { + Some(1) => {} + None => codegen_units = Some(1), + Some(_) => early_error( + error_format, + "can't instrument with gcov profiling with multiple codegen units", + ), + } + } if cg.profile_generate.enabled() && cg.profile_use.is_some() { early_error( diff --git a/src/librustc_session/options.rs b/src/librustc_session/options.rs index 8cd6ca86f46..94e65093e71 100644 --- a/src/librustc_session/options.rs +++ b/src/librustc_session/options.rs @@ -890,6 +890,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "extra arguments to prepend to the linker invocation (space separated)"), profile: bool = (false, parse_bool, [TRACKED], "insert profiling code"), + no_profiler_runtime: bool = (false, parse_bool, [TRACKED], + "don't automatically inject the profiler_builtins crate"), relro_level: Option<RelroLevel> = (None, parse_relro_level, [TRACKED], "choose which RELRO level to use"), nll_facts: bool = (false, parse_bool, [UNTRACKED], diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs index 4c963ac84dc..1575e6fd533 100644 --- a/src/librustc_span/symbol.rs +++ b/src/librustc_span/symbol.rs @@ -348,6 +348,7 @@ symbols! { generators, generic_associated_types, generic_param_attrs, + get_context, global_allocator, global_asm, globs, @@ -547,8 +548,8 @@ symbols! { plugin, plugin_registrar, plugins, + poll, Poll, - poll_with_context, powerpc_target_feature, precise_pointer_size_matching, pref_align_of, diff --git a/src/librustc_target/abi/call/mips64.rs b/src/librustc_target/abi/call/mips64.rs index 81de6306788..917dd104d14 100644 --- a/src/librustc_target/abi/call/mips64.rs +++ b/src/librustc_target/abi/call/mips64.rs @@ -88,6 +88,7 @@ where let mut prefix_index = 0; match arg.layout.fields { + abi::FieldsShape::Primitive => unreachable!(), abi::FieldsShape::Array { .. } => { // Arrays are passed indirectly arg.make_indirect(); diff --git a/src/librustc_target/abi/call/mod.rs b/src/librustc_target/abi/call/mod.rs index b6bfa70005b..0303312d057 100644 --- a/src/librustc_target/abi/call/mod.rs +++ b/src/librustc_target/abi/call/mod.rs @@ -308,13 +308,16 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { } Abi::ScalarPair(..) | Abi::Aggregate { .. } => { - // Helper for computing `homogenous_aggregate`, allowing a custom + // Helper for computing `homogeneous_aggregate`, allowing a custom // starting offset (used below for handling variants). let from_fields_at = |layout: Self, start: Size| -> Result<(HomogeneousAggregate, Size), Heterogeneous> { let is_union = match layout.fields { + FieldsShape::Primitive => { + unreachable!("aggregates can't have `FieldsShape::Primitive`") + } FieldsShape::Array { count, .. } => { assert_eq!(start, Size::ZERO); diff --git a/src/librustc_target/abi/call/riscv.rs b/src/librustc_target/abi/call/riscv.rs index 0eb8816e434..2e10bed3bd4 100644 --- a/src/librustc_target/abi/call/riscv.rs +++ b/src/librustc_target/abi/call/riscv.rs @@ -87,6 +87,9 @@ where }, Abi::Vector { .. } | Abi::Uninhabited => return Err(CannotUseFpConv), Abi::ScalarPair(..) | Abi::Aggregate { .. } => match arg_layout.fields { + FieldsShape::Primitive => { + unreachable!("aggregates can't have `FieldsShape::Primitive`") + } FieldsShape::Union(_) => { if !arg_layout.is_zst() { return Err(CannotUseFpConv); diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs index 4c25363a657..dcf181cb59f 100644 --- a/src/librustc_target/abi/mod.rs +++ b/src/librustc_target/abi/mod.rs @@ -4,6 +4,7 @@ pub use Primitive::*; use crate::spec::Target; use std::convert::{TryFrom, TryInto}; +use std::num::NonZeroUsize; use std::ops::{Add, AddAssign, Deref, Mul, Range, RangeInclusive, Sub}; use rustc_index::vec::{Idx, IndexVec}; @@ -619,10 +620,11 @@ impl Scalar { /// Describes how the fields of a type are located in memory. #[derive(PartialEq, Eq, Hash, Debug, HashStable_Generic)] pub enum FieldsShape { + /// Scalar primitives and `!`, which never have fields. + Primitive, + /// All fields start at no offset. The `usize` is the field count. - /// - /// In the case of primitives the number of fields is `0`. - Union(usize), + Union(NonZeroUsize), /// Array/vector-like placement, with all fields of identical types. Array { stride: Size, count: u64 }, @@ -660,7 +662,8 @@ pub enum FieldsShape { impl FieldsShape { pub fn count(&self) -> usize { match *self { - FieldsShape::Union(count) => count, + FieldsShape::Primitive => 0, + FieldsShape::Union(count) => count.get(), FieldsShape::Array { count, .. } => { let usize_count = count as usize; assert_eq!(usize_count as u64, count); @@ -672,8 +675,16 @@ impl FieldsShape { pub fn offset(&self, i: usize) -> Size { match *self { + FieldsShape::Primitive => { + unreachable!("FieldsShape::offset: `Primitive`s have no fields") + } FieldsShape::Union(count) => { - assert!(i < count, "tried to access field {} of union with {} fields", i, count); + assert!( + i < count.get(), + "tried to access field {} of union with {} fields", + i, + count + ); Size::ZERO } FieldsShape::Array { stride, count } => { @@ -687,6 +698,9 @@ impl FieldsShape { pub fn memory_index(&self, i: usize) -> usize { match *self { + FieldsShape::Primitive => { + unreachable!("FieldsShape::memory_index: `Primitive`s have no fields") + } FieldsShape::Union(_) | FieldsShape::Array { .. } => i, FieldsShape::Arbitrary { ref memory_index, .. } => { let r = memory_index[i]; @@ -718,7 +732,7 @@ impl FieldsShape { } (0..self.count()).map(move |i| match *self { - FieldsShape::Union(_) | FieldsShape::Array { .. } => i, + FieldsShape::Primitive | FieldsShape::Union(_) | FieldsShape::Array { .. } => i, FieldsShape::Arbitrary { .. } => { if use_small { inverse_small[i] as usize @@ -887,7 +901,6 @@ impl Niche { #[derive(PartialEq, Eq, Hash, Debug, HashStable_Generic)] pub struct Layout { /// Says where the fields are located within the layout. - /// Primitives and uninhabited enums appear as unions without fields. pub fields: FieldsShape, /// Encodes information about multi-variant layouts. @@ -923,7 +936,7 @@ impl Layout { let align = scalar.value.align(cx); Layout { variants: Variants::Single { index: VariantIdx::new(0) }, - fields: FieldsShape::Union(0), + fields: FieldsShape::Primitive, abi: Abi::Scalar(scalar), largest_niche, size, diff --git a/src/librustc_target/spec/armebv7r_none_eabi.rs b/src/librustc_target/spec/armebv7r_none_eabi.rs index 3a5957892b5..ebe901e4f27 100644 --- a/src/librustc_target/spec/armebv7r_none_eabi.rs +++ b/src/librustc_target/spec/armebv7r_none_eabi.rs @@ -1,7 +1,6 @@ // Targets the Big endian Cortex-R4/R5 processor (ARMv7-R) use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions, TargetResult}; -use std::default::Default; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_target/spec/armebv7r_none_eabihf.rs b/src/librustc_target/spec/armebv7r_none_eabihf.rs index 9f95a1a6f44..8652d1051ad 100644 --- a/src/librustc_target/spec/armebv7r_none_eabihf.rs +++ b/src/librustc_target/spec/armebv7r_none_eabihf.rs @@ -1,7 +1,6 @@ // Targets the Cortex-R4F/R5F processor (ARMv7-R) use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions, TargetResult}; -use std::default::Default; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_target/spec/armv7r_none_eabi.rs b/src/librustc_target/spec/armv7r_none_eabi.rs index 517368e6a23..b7fcda63db0 100644 --- a/src/librustc_target/spec/armv7r_none_eabi.rs +++ b/src/librustc_target/spec/armv7r_none_eabi.rs @@ -1,7 +1,6 @@ // Targets the Little-endian Cortex-R4/R5 processor (ARMv7-R) use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions, TargetResult}; -use std::default::Default; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_target/spec/armv7r_none_eabihf.rs b/src/librustc_target/spec/armv7r_none_eabihf.rs index 6363469d929..340090fd43b 100644 --- a/src/librustc_target/spec/armv7r_none_eabihf.rs +++ b/src/librustc_target/spec/armv7r_none_eabihf.rs @@ -1,7 +1,6 @@ // Targets the Little-endian Cortex-R4F/R5F processor (ARMv7-R) use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions, TargetResult}; -use std::default::Default; pub fn target() -> TargetResult { Ok(Target { diff --git a/src/librustc_target/spec/dragonfly_base.rs b/src/librustc_target/spec/dragonfly_base.rs index e26d0ae50b2..c7062e1ca51 100644 --- a/src/librustc_target/spec/dragonfly_base.rs +++ b/src/librustc_target/spec/dragonfly_base.rs @@ -1,5 +1,4 @@ use crate::spec::{LinkArgs, LinkerFlavor, RelroLevel, TargetOptions}; -use std::default::Default; pub fn opts() -> TargetOptions { let mut args = LinkArgs::new(); diff --git a/src/librustc_target/spec/freebsd_base.rs b/src/librustc_target/spec/freebsd_base.rs index fc252b6d43d..d2a087ab62f 100644 --- a/src/librustc_target/spec/freebsd_base.rs +++ b/src/librustc_target/spec/freebsd_base.rs @@ -1,5 +1,4 @@ use crate::spec::{LinkArgs, LinkerFlavor, RelroLevel, TargetOptions}; -use std::default::Default; pub fn opts() -> TargetOptions { let mut args = LinkArgs::new(); diff --git a/src/librustc_target/spec/fuchsia_base.rs b/src/librustc_target/spec/fuchsia_base.rs index 046388e9be8..4060b126cdd 100644 --- a/src/librustc_target/spec/fuchsia_base.rs +++ b/src/librustc_target/spec/fuchsia_base.rs @@ -1,5 +1,4 @@ use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, TargetOptions}; -use std::default::Default; pub fn opts() -> TargetOptions { let mut pre_link_args = LinkArgs::new(); diff --git a/src/librustc_target/spec/haiku_base.rs b/src/librustc_target/spec/haiku_base.rs index 1ddab7be180..3d7ae6c302d 100644 --- a/src/librustc_target/spec/haiku_base.rs +++ b/src/librustc_target/spec/haiku_base.rs @@ -1,5 +1,4 @@ use crate::spec::{RelroLevel, TargetOptions}; -use std::default::Default; pub fn opts() -> TargetOptions { TargetOptions { diff --git a/src/librustc_target/spec/hermit_base.rs b/src/librustc_target/spec/hermit_base.rs index 3f9dad689fd..b9f94023e7a 100644 --- a/src/librustc_target/spec/hermit_base.rs +++ b/src/librustc_target/spec/hermit_base.rs @@ -1,5 +1,4 @@ use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, PanicStrategy, TargetOptions}; -use std::default::Default; pub fn opts() -> TargetOptions { let mut pre_link_args = LinkArgs::new(); diff --git a/src/librustc_target/spec/hermit_kernel_base.rs b/src/librustc_target/spec/hermit_kernel_base.rs index 650219c21ac..1f9b195e2e6 100644 --- a/src/librustc_target/spec/hermit_kernel_base.rs +++ b/src/librustc_target/spec/hermit_kernel_base.rs @@ -1,5 +1,4 @@ use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, PanicStrategy, TargetOptions}; -use std::default::Default; pub fn opts() -> TargetOptions { let mut pre_link_args = LinkArgs::new(); diff --git a/src/librustc_target/spec/i686_pc_windows_gnu.rs b/src/librustc_target/spec/i686_pc_windows_gnu.rs index 2091902d7ce..d12afe5a40b 100644 --- a/src/librustc_target/spec/i686_pc_windows_gnu.rs +++ b/src/librustc_target/spec/i686_pc_windows_gnu.rs @@ -1,7 +1,7 @@ use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { - let mut base = super::windows_base::opts(); + let mut base = super::windows_gnu_base::opts(); base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); base.eliminate_frame_pointer = false; // Required for backtraces diff --git a/src/librustc_target/spec/i686_pc_windows_msvc.rs b/src/librustc_target/spec/i686_pc_windows_msvc.rs index ffb66afc761..9d0922b8ce5 100644 --- a/src/librustc_target/spec/i686_pc_windows_msvc.rs +++ b/src/librustc_target/spec/i686_pc_windows_msvc.rs @@ -1,18 +1,24 @@ -use crate::spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::windows_msvc_base::opts(); base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); - // Mark all dynamic libraries and executables as compatible with the larger 4GiB address - // space available to x86 Windows binaries on x86_64. - base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap().push("/LARGEADDRESSAWARE".to_string()); - - // Ensure the linker will only produce an image if it can also produce a table of - // the image's safe exception handlers. - // https://docs.microsoft.com/en-us/cpp/build/reference/safeseh-image-has-safe-exception-handlers - base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap().push("/SAFESEH".to_string()); + let pre_link_args_msvc = vec![ + // Mark all dynamic libraries and executables as compatible with the larger 4GiB address + // space available to x86 Windows binaries on x86_64. + "/LARGEADDRESSAWARE".to_string(), + // Ensure the linker will only produce an image if it can also produce a table of + // the image's safe exception handlers. + // https://docs.microsoft.com/en-us/cpp/build/reference/safeseh-image-has-safe-exception-handlers + "/SAFESEH".to_string(), + ]; + base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap().extend(pre_link_args_msvc.clone()); + base.pre_link_args + .get_mut(&LinkerFlavor::Lld(LldFlavor::Link)) + .unwrap() + .extend(pre_link_args_msvc); Ok(Target { llvm_target: "i686-pc-windows-msvc".to_string(), diff --git a/src/librustc_target/spec/i686_unknown_uefi.rs b/src/librustc_target/spec/i686_unknown_uefi.rs index e299f92fdeb..221d5f0785c 100644 --- a/src/librustc_target/spec/i686_unknown_uefi.rs +++ b/src/librustc_target/spec/i686_unknown_uefi.rs @@ -8,7 +8,7 @@ use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetResult}; pub fn target() -> TargetResult { - let mut base = super::uefi_base::opts(); + let mut base = super::uefi_msvc_base::opts(); base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); @@ -23,11 +23,6 @@ pub fn target() -> TargetResult { // arguments, thus giving you access to full MMX/SSE acceleration. base.features = "-mmx,-sse,+soft-float".to_string(); - // UEFI mirrors the calling-conventions used on windows. In case of i686 this means small - // structs will be returned as int. This shouldn't matter much, since the restrictions placed - // by the UEFI specifications forbid any ABI to return structures. - base.abi_return_struct_as_int = true; - // Use -GNU here, because of the reason below: // Background and Problem: // If we use i686-unknown-windows, the LLVM IA32 MSVC generates compiler intrinsic diff --git a/src/librustc_target/spec/i686_uwp_windows_gnu.rs b/src/librustc_target/spec/i686_uwp_windows_gnu.rs index 93f396de0a0..4e582fb8c63 100644 --- a/src/librustc_target/spec/i686_uwp_windows_gnu.rs +++ b/src/librustc_target/spec/i686_uwp_windows_gnu.rs @@ -1,7 +1,7 @@ use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { - let mut base = super::windows_uwp_base::opts(); + let mut base = super::windows_uwp_gnu_base::opts(); base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); base.eliminate_frame_pointer = false; // Required for backtraces diff --git a/src/librustc_target/spec/illumos_base.rs b/src/librustc_target/spec/illumos_base.rs new file mode 100644 index 00000000000..35ac346fb3f --- /dev/null +++ b/src/librustc_target/spec/illumos_base.rs @@ -0,0 +1,48 @@ +use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions}; +use std::default::Default; + +pub fn opts() -> TargetOptions { + let mut late_link_args = LinkArgs::new(); + late_link_args.insert( + LinkerFlavor::Gcc, + vec![ + // LLVM will insert calls to the stack protector functions + // "__stack_chk_fail" and "__stack_chk_guard" into code in native + // object files. Some platforms include these symbols directly in + // libc, but at least historically these have been provided in + // libssp.so on illumos and Solaris systems. + "-lssp".to_string(), + ], + ); + + TargetOptions { + dynamic_linking: true, + executables: true, + has_rpath: true, + target_family: Some("unix".to_string()), + is_like_solaris: true, + limit_rdylib_exports: false, // Linker doesn't support this + eliminate_frame_pointer: false, + late_link_args, + + // While we support ELF TLS, rust requires a way to register + // cleanup handlers (in C, this would be something along the lines of: + // void register_callback(void (*fn)(void *), void *arg); + // (see src/libstd/sys/unix/fast_thread_local.rs) that is currently + // missing in illumos. For now at least, we must fallback to using + // pthread_{get,set}specific. + //has_elf_tls: true, + + // FIXME: Currently, rust is invoking cc to link, which ends up + // causing these to get included twice. We should eventually transition + // to having rustc invoke ld directly, in which case these will need to + // be uncommented. + // + // We want XPG6 behavior from libc and libm. See standards(5) + //pre_link_objects_exe: vec![ + // "/usr/lib/amd64/values-Xc.o".to_string(), + // "/usr/lib/amd64/values-xpg6.o".to_string(), + //], + ..Default::default() + } +} diff --git a/src/librustc_target/spec/l4re_base.rs b/src/librustc_target/spec/l4re_base.rs index b712dcae899..5caad10161d 100644 --- a/src/librustc_target/spec/l4re_base.rs +++ b/src/librustc_target/spec/l4re_base.rs @@ -1,5 +1,4 @@ use crate::spec::{LinkArgs, LinkerFlavor, PanicStrategy, TargetOptions}; -use std::default::Default; //use std::process::Command; // Use GCC to locate code for crt* libraries from the host, not from L4Re. Note diff --git a/src/librustc_target/spec/linux_base.rs b/src/librustc_target/spec/linux_base.rs index a5d7f8e07c4..52892fc3592 100644 --- a/src/librustc_target/spec/linux_base.rs +++ b/src/librustc_target/spec/linux_base.rs @@ -1,5 +1,4 @@ use crate::spec::{LinkArgs, LinkerFlavor, RelroLevel, TargetOptions}; -use std::default::Default; pub fn opts() -> TargetOptions { let mut args = LinkArgs::new(); diff --git a/src/librustc_target/spec/linux_kernel_base.rs b/src/librustc_target/spec/linux_kernel_base.rs index fae44836fa8..4a900d1b02c 100644 --- a/src/librustc_target/spec/linux_kernel_base.rs +++ b/src/librustc_target/spec/linux_kernel_base.rs @@ -1,5 +1,4 @@ use crate::spec::{LinkArgs, LinkerFlavor, PanicStrategy, RelroLevel, TargetOptions}; -use std::default::Default; pub fn opts() -> TargetOptions { let mut pre_link_args = LinkArgs::new(); diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 1bc2bf12fad..8f3097ad423 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -37,7 +37,6 @@ use crate::spec::abi::{lookup as lookup_abi, Abi}; use rustc_serialize::json::{Json, ToJson}; use std::collections::BTreeMap; -use std::default::Default; use std::path::{Path, PathBuf}; use std::str::FromStr; use std::{fmt, io}; @@ -56,22 +55,24 @@ mod fuchsia_base; mod haiku_base; mod hermit_base; mod hermit_kernel_base; +mod illumos_base; mod l4re_base; mod linux_base; mod linux_kernel_base; mod linux_musl_base; +mod msvc_base; mod netbsd_base; mod openbsd_base; mod redox_base; mod riscv_base; mod solaris_base; mod thumb_base; -mod uefi_base; +mod uefi_msvc_base; mod vxworks_base; mod wasm32_base; -mod windows_base; +mod windows_gnu_base; mod windows_msvc_base; -mod windows_uwp_base; +mod windows_uwp_gnu_base; mod windows_uwp_msvc_base; #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] @@ -309,23 +310,14 @@ macro_rules! supported_targets { } #[cfg(test)] - mod test_json_encode_decode { - use rustc_serialize::json::ToJson; - use super::Target; - $(use super::$module;)+ + mod tests { + mod tests_impl; + // Cannot put this into a separate file without duplication, make an exception. $( - #[test] // `#[test]` - this is hard to put into a separate file, make an exception + #[test] // `#[test]` fn $module() { - // Grab the TargetResult struct. If we successfully retrieved - // a Target, then the test JSON encoding/decoding can run for this - // Target on this testing platform (i.e., checking the iOS targets - // only on a Mac test platform). - let _ = $module::target().map(|original| { - let as_json = original.to_json(); - let parsed = Target::from_json(as_json).unwrap(); - assert_eq!(original, parsed); - }); + tests_impl::test_target(super::$module::target()); } )+ } @@ -447,6 +439,8 @@ supported_targets! { ("x86_64-sun-solaris", "x86_64-pc-solaris", x86_64_sun_solaris), ("sparcv9-sun-solaris", sparcv9_sun_solaris), + ("x86_64-unknown-illumos", x86_64_unknown_illumos), + ("x86_64-pc-windows-gnu", x86_64_pc_windows_gnu), ("i686-pc-windows-gnu", i686_pc_windows_gnu), ("i686-uwp-windows-gnu", i686_uwp_windows_gnu), @@ -538,7 +532,8 @@ pub struct Target { pub arch: String, /// [Data layout](http://llvm.org/docs/LangRef.html#data-layout) to pass to LLVM. pub data_layout: String, - /// Linker flavor + /// Default linker flavor used if `-C linker-flavor` or `-C linker` are not passed + /// on the command line. pub linker_flavor: LinkerFlavor, /// Optional settings with defaults. pub options: TargetOptions, @@ -566,7 +561,8 @@ pub struct TargetOptions { /// Linker to invoke pub linker: Option<String>, - /// LLD flavor + /// LLD flavor used if `lld` (or `rust-lld`) is specified as a linker + /// without clarifying its flavor in any way. pub lld_flavor: LldFlavor, /// Linker arguments that are passed *before* any user-defined libraries. diff --git a/src/librustc_target/spec/msvc_base.rs b/src/librustc_target/spec/msvc_base.rs new file mode 100644 index 00000000000..817a322a9e4 --- /dev/null +++ b/src/librustc_target/spec/msvc_base.rs @@ -0,0 +1,35 @@ +use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, TargetOptions}; + +pub fn opts() -> TargetOptions { + let pre_link_args_msvc = vec![ + // Suppress the verbose logo and authorship debugging output, which would needlessly + // clog any log files. + "/NOLOGO".to_string(), + // Tell the compiler that non-code sections can be marked as non-executable, + // including stack pages. + // UEFI is fully compatible to non-executable data pages. + // In fact, firmware might enforce this, so we better let the linker know about this, + // so it will fail if the compiler ever tries placing code on the stack + // (e.g., trampoline constructs and alike). + "/NXCOMPAT".to_string(), + ]; + let mut pre_link_args = LinkArgs::new(); + pre_link_args.insert(LinkerFlavor::Msvc, pre_link_args_msvc.clone()); + pre_link_args.insert(LinkerFlavor::Lld(LldFlavor::Link), pre_link_args_msvc); + + TargetOptions { + executables: true, + is_like_windows: true, + is_like_msvc: true, + // set VSLANG to 1033 can prevent link.exe from using + // language packs, and avoid generating Non-UTF-8 error + // messages if a link error occurred. + link_env: vec![("VSLANG".to_string(), "1033".to_string())], + lld_flavor: LldFlavor::Link, + pre_link_args, + abi_return_struct_as_int: true, + emit_debug_gdb_scripts: false, + + ..Default::default() + } +} diff --git a/src/librustc_target/spec/netbsd_base.rs b/src/librustc_target/spec/netbsd_base.rs index eb359b92046..95c4749f9c7 100644 --- a/src/librustc_target/spec/netbsd_base.rs +++ b/src/librustc_target/spec/netbsd_base.rs @@ -1,5 +1,4 @@ use crate::spec::{LinkArgs, LinkerFlavor, RelroLevel, TargetOptions}; -use std::default::Default; pub fn opts() -> TargetOptions { let mut args = LinkArgs::new(); diff --git a/src/librustc_target/spec/openbsd_base.rs b/src/librustc_target/spec/openbsd_base.rs index b66c56e1a7a..cadd14df693 100644 --- a/src/librustc_target/spec/openbsd_base.rs +++ b/src/librustc_target/spec/openbsd_base.rs @@ -1,5 +1,4 @@ use crate::spec::{LinkArgs, LinkerFlavor, RelroLevel, TargetOptions}; -use std::default::Default; pub fn opts() -> TargetOptions { let mut args = LinkArgs::new(); diff --git a/src/librustc_target/spec/redox_base.rs b/src/librustc_target/spec/redox_base.rs index 6398fa91f02..18cafe654d1 100644 --- a/src/librustc_target/spec/redox_base.rs +++ b/src/librustc_target/spec/redox_base.rs @@ -1,5 +1,4 @@ use crate::spec::{LinkArgs, LinkerFlavor, RelroLevel, TargetOptions}; -use std::default::Default; pub fn opts() -> TargetOptions { let mut args = LinkArgs::new(); diff --git a/src/librustc_target/spec/solaris_base.rs b/src/librustc_target/spec/solaris_base.rs index 98a2a0fbc9c..8d3a3563f41 100644 --- a/src/librustc_target/spec/solaris_base.rs +++ b/src/librustc_target/spec/solaris_base.rs @@ -1,5 +1,4 @@ use crate::spec::TargetOptions; -use std::default::Default; pub fn opts() -> TargetOptions { TargetOptions { diff --git a/src/librustc_target/spec/tests/tests_impl.rs b/src/librustc_target/spec/tests/tests_impl.rs new file mode 100644 index 00000000000..4cf186bdd7c --- /dev/null +++ b/src/librustc_target/spec/tests/tests_impl.rs @@ -0,0 +1,43 @@ +use super::super::*; + +pub(super) fn test_target(target: TargetResult) { + // Grab the TargetResult struct. If we successfully retrieved + // a Target, then the test JSON encoding/decoding can run for this + // Target on this testing platform (i.e., checking the iOS targets + // only on a Mac test platform). + if let Ok(original) = target { + original.check_consistency(); + let as_json = original.to_json(); + let parsed = Target::from_json(as_json).unwrap(); + assert_eq!(original, parsed); + } +} + +impl Target { + fn check_consistency(&self) { + // Check that LLD with the given flavor is treated identically to the linker it emulates. + // If you target really needs to deviate from the rules below, whitelist it + // and document the reasons. + assert_eq!( + self.linker_flavor == LinkerFlavor::Msvc + || self.linker_flavor == LinkerFlavor::Lld(LldFlavor::Link), + self.options.lld_flavor == LldFlavor::Link, + ); + for args in &[ + &self.options.pre_link_args, + &self.options.pre_link_args_crt, + &self.options.late_link_args, + &self.options.late_link_args_dynamic, + &self.options.late_link_args_static, + &self.options.post_link_args, + ] { + assert_eq!( + args.get(&LinkerFlavor::Msvc), + args.get(&LinkerFlavor::Lld(LldFlavor::Link)), + ); + if args.contains_key(&LinkerFlavor::Msvc) { + assert_eq!(self.options.lld_flavor, LldFlavor::Link); + } + } + } +} diff --git a/src/librustc_target/spec/thumb_base.rs b/src/librustc_target/spec/thumb_base.rs index 99ab996be95..eca095b5942 100644 --- a/src/librustc_target/spec/thumb_base.rs +++ b/src/librustc_target/spec/thumb_base.rs @@ -28,7 +28,6 @@ // build scripts / gcc flags. use crate::spec::{PanicStrategy, TargetOptions}; -use std::default::Default; pub fn opts() -> TargetOptions { // See rust-lang/rfcs#1645 for a discussion about these defaults diff --git a/src/librustc_target/spec/thumbv7a_pc_windows_msvc.rs b/src/librustc_target/spec/thumbv7a_pc_windows_msvc.rs index ab0f7791e2c..21d62d252e0 100644 --- a/src/librustc_target/spec/thumbv7a_pc_windows_msvc.rs +++ b/src/librustc_target/spec/thumbv7a_pc_windows_msvc.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, PanicStrategy, Target, TargetOptions, TargetResult}; +use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { let mut base = super::windows_msvc_base::opts(); @@ -10,7 +10,12 @@ pub fn target() -> TargetResult { // should be smart enough to insert branch islands only // where necessary, but this is not the observed behavior. // Disabling the LBR optimization works around the issue. - base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap().push("/OPT:NOLBR".to_string()); + let pre_link_args_msvc = "/OPT:NOLBR".to_string(); + base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap().push(pre_link_args_msvc.clone()); + base.pre_link_args + .get_mut(&LinkerFlavor::Lld(LldFlavor::Link)) + .unwrap() + .push(pre_link_args_msvc); // FIXME(jordanrh): use PanicStrategy::Unwind when SEH is // implemented for windows/arm in LLVM diff --git a/src/librustc_target/spec/uefi_base.rs b/src/librustc_target/spec/uefi_base.rs deleted file mode 100644 index d09da9478fb..00000000000 --- a/src/librustc_target/spec/uefi_base.rs +++ /dev/null @@ -1,67 +0,0 @@ -// This defines a base target-configuration for native UEFI systems. The UEFI specification has -// quite detailed sections on the ABI of all the supported target architectures. In almost all -// cases it simply follows what Microsoft Windows does. Hence, whenever in doubt, see the MSDN -// documentation. -// UEFI uses COFF/PE32+ format for binaries. All binaries must be statically linked. No dynamic -// linker is supported. As native to COFF, binaries are position-dependent, but will be relocated -// by the loader if the pre-chosen memory location is already in use. -// UEFI forbids running code on anything but the boot-CPU. No interrupts are allowed other than -// the timer-interrupt. Device-drivers are required to use polling-based models. Furthermore, all -// code runs in the same environment, no process separation is supported. - -use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, PanicStrategy, TargetOptions}; -use std::default::Default; - -pub fn opts() -> TargetOptions { - let mut pre_link_args = LinkArgs::new(); - - pre_link_args.insert( - LinkerFlavor::Lld(LldFlavor::Link), - vec![ - // Suppress the verbose logo and authorship debugging output, which would needlessly - // clog any log files. - "/NOLOGO".to_string(), - // UEFI is fully compatible to non-executable data pages. Tell the compiler that - // non-code sections can be marked as non-executable, including stack pages. In fact, - // firmware might enforce this, so we better let the linker know about this, so it - // will fail if the compiler ever tries placing code on the stack (e.g., trampoline - // constructs and alike). - "/NXCOMPAT".to_string(), - // There is no runtime for UEFI targets, prevent them from being linked. UEFI targets - // must be freestanding. - "/nodefaultlib".to_string(), - // Non-standard subsystems have no default entry-point in PE+ files. We have to define - // one. "efi_main" seems to be a common choice amongst other implementations and the - // spec. - "/entry:efi_main".to_string(), - // COFF images have a "Subsystem" field in their header, which defines what kind of - // program it is. UEFI has 3 fields reserved, which are EFI_APPLICATION, - // EFI_BOOT_SERVICE_DRIVER, and EFI_RUNTIME_DRIVER. We default to EFI_APPLICATION, - // which is very likely the most common option. Individual projects can override this - // with custom linker flags. - // The subsystem-type only has minor effects on the application. It defines the memory - // regions the application is loaded into (runtime-drivers need to be put into - // reserved areas), as well as whether a return from the entry-point is treated as - // exit (default for applications). - "/subsystem:efi_application".to_string(), - ], - ); - - TargetOptions { - dynamic_linking: false, - executables: true, - disable_redzone: true, - exe_suffix: ".efi".to_string(), - allows_weak_linkage: false, - panic_strategy: PanicStrategy::Abort, - stack_probes: true, - singlethread: true, - emit_debug_gdb_scripts: false, - - linker: Some("rust-lld".to_string()), - lld_flavor: LldFlavor::Link, - pre_link_args, - - ..Default::default() - } -} diff --git a/src/librustc_target/spec/uefi_msvc_base.rs b/src/librustc_target/spec/uefi_msvc_base.rs new file mode 100644 index 00000000000..3f7c78c8e7d --- /dev/null +++ b/src/librustc_target/spec/uefi_msvc_base.rs @@ -0,0 +1,58 @@ +// This defines a base target-configuration for native UEFI systems. The UEFI specification has +// quite detailed sections on the ABI of all the supported target architectures. In almost all +// cases it simply follows what Microsoft Windows does. Hence, whenever in doubt, see the MSDN +// documentation. +// UEFI uses COFF/PE32+ format for binaries. All binaries must be statically linked. No dynamic +// linker is supported. As native to COFF, binaries are position-dependent, but will be relocated +// by the loader if the pre-chosen memory location is already in use. +// UEFI forbids running code on anything but the boot-CPU. No interrupts are allowed other than +// the timer-interrupt. Device-drivers are required to use polling-based models. Furthermore, all +// code runs in the same environment, no process separation is supported. + +use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, TargetOptions}; + +pub fn opts() -> TargetOptions { + let mut base = super::msvc_base::opts(); + + let pre_link_args_msvc = vec![ + // Non-standard subsystems have no default entry-point in PE+ files. We have to define + // one. "efi_main" seems to be a common choice amongst other implementations and the + // spec. + "/entry:efi_main".to_string(), + // COFF images have a "Subsystem" field in their header, which defines what kind of + // program it is. UEFI has 3 fields reserved, which are EFI_APPLICATION, + // EFI_BOOT_SERVICE_DRIVER, and EFI_RUNTIME_DRIVER. We default to EFI_APPLICATION, + // which is very likely the most common option. Individual projects can override this + // with custom linker flags. + // The subsystem-type only has minor effects on the application. It defines the memory + // regions the application is loaded into (runtime-drivers need to be put into + // reserved areas), as well as whether a return from the entry-point is treated as + // exit (default for applications). + "/subsystem:efi_application".to_string(), + ]; + base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap().extend(pre_link_args_msvc.clone()); + base.pre_link_args + .get_mut(&LinkerFlavor::Lld(LldFlavor::Link)) + .unwrap() + .extend(pre_link_args_msvc); + + TargetOptions { + disable_redzone: true, + exe_suffix: ".efi".to_string(), + allows_weak_linkage: false, + panic_strategy: PanicStrategy::Abort, + stack_probes: true, + singlethread: true, + linker: Some("rust-lld".to_string()), + // FIXME: This should likely be `true` inherited from `msvc_base` + // because UEFI follows Windows ABI and uses PE/COFF. + // The `false` is probably causing ABI bugs right now. + is_like_windows: false, + // FIXME: This should likely be `true` inherited from `msvc_base` + // because UEFI follows Windows ABI and uses PE/COFF. + // The `false` is probably causing ABI bugs right now. + is_like_msvc: false, + + ..base + } +} diff --git a/src/librustc_target/spec/vxworks_base.rs b/src/librustc_target/spec/vxworks_base.rs index 1763c9139b1..1b25c51278d 100644 --- a/src/librustc_target/spec/vxworks_base.rs +++ b/src/librustc_target/spec/vxworks_base.rs @@ -1,5 +1,4 @@ use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions}; -use std::default::Default; pub fn opts() -> TargetOptions { let mut args_crt = LinkArgs::new(); diff --git a/src/librustc_target/spec/windows_base.rs b/src/librustc_target/spec/windows_gnu_base.rs index 097ee09f1ea..33ecb1d0d48 100644 --- a/src/librustc_target/spec/windows_base.rs +++ b/src/librustc_target/spec/windows_gnu_base.rs @@ -1,5 +1,4 @@ use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions}; -use std::default::Default; pub fn opts() -> TargetOptions { let mut pre_link_args = LinkArgs::new(); diff --git a/src/librustc_target/spec/windows_msvc_base.rs b/src/librustc_target/spec/windows_msvc_base.rs index 52b166df939..77171f8672e 100644 --- a/src/librustc_target/spec/windows_msvc_base.rs +++ b/src/librustc_target/spec/windows_msvc_base.rs @@ -1,36 +1,30 @@ -use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, TargetOptions}; -use std::default::Default; +use crate::spec::TargetOptions; pub fn opts() -> TargetOptions { - let pre_args = vec!["/NOLOGO".to_string(), "/NXCOMPAT".to_string()]; - let mut args = LinkArgs::new(); - args.insert(LinkerFlavor::Msvc, pre_args.clone()); - args.insert(LinkerFlavor::Lld(LldFlavor::Link), pre_args); + let base = super::msvc_base::opts(); TargetOptions { - function_sections: true, dynamic_linking: true, - executables: true, dll_prefix: String::new(), dll_suffix: ".dll".to_string(), exe_suffix: ".exe".to_string(), staticlib_prefix: String::new(), staticlib_suffix: ".lib".to_string(), target_family: Some("windows".to_string()), - is_like_windows: true, - is_like_msvc: true, - // set VSLANG to 1033 can prevent link.exe from using - // language packs, and avoid generating Non-UTF-8 error - // messages if a link error occurred. - link_env: vec![("VSLANG".to_string(), "1033".to_string())], - lld_flavor: LldFlavor::Link, - pre_link_args: args, crt_static_allows_dylibs: true, crt_static_respected: true, - abi_return_struct_as_int: true, - emit_debug_gdb_scripts: false, requires_uwtable: true, + // Currently we don't pass the /NODEFAULTLIB flag to the linker on MSVC + // as there's been trouble in the past of linking the C++ standard + // library required by LLVM. This likely needs to happen one day, but + // in general Windows is also a more controlled environment than + // Unix, so it's not necessarily as critical that this be implemented. + // + // Note that there are also some licensing worries about statically + // linking some libraries which require a specific agreement, so it may + // not ever be possible for us to pass this flag. + no_default_libraries: false, - ..Default::default() + ..base } } diff --git a/src/librustc_target/spec/windows_uwp_base.rs b/src/librustc_target/spec/windows_uwp_gnu_base.rs index f19bd10dc0b..dd3b60344be 100644 --- a/src/librustc_target/spec/windows_uwp_base.rs +++ b/src/librustc_target/spec/windows_uwp_gnu_base.rs @@ -1,7 +1,9 @@ use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions}; -use std::default::Default; pub fn opts() -> TargetOptions { + let base = super::windows_gnu_base::opts(); + + // FIXME: Consider adding `-nostdlib` and inheriting from `windows_gnu_base`. let mut pre_link_args = LinkArgs::new(); pre_link_args.insert( LinkerFlavor::Gcc, @@ -14,7 +16,10 @@ pub fn opts() -> TargetOptions { ], ); + // FIXME: This should be updated for the exception machinery changes from #67502. let mut late_link_args = LinkArgs::new(); + let late_link_args_dynamic = LinkArgs::new(); + let late_link_args_static = LinkArgs::new(); late_link_args.insert( LinkerFlavor::Gcc, vec![ @@ -33,31 +38,17 @@ pub fn opts() -> TargetOptions { ); TargetOptions { - // FIXME(#13846) this should be enabled for windows - function_sections: false, - linker: Some("gcc".to_string()), - dynamic_linking: true, executables: false, - dll_prefix: String::new(), - dll_suffix: ".dll".to_string(), - exe_suffix: ".exe".to_string(), - staticlib_prefix: "lib".to_string(), - staticlib_suffix: ".a".to_string(), - target_family: Some("windows".to_string()), - is_like_windows: true, - allows_weak_linkage: false, + limit_rdylib_exports: false, pre_link_args, - pre_link_objects_exe: vec![ - "rsbegin.o".to_string(), // Rust compiler runtime initialization, see rsbegin.rs - ], + // FIXME: Consider adding `-nostdlib` and inheriting from `windows_gnu_base`. + pre_link_objects_exe: vec!["rsbegin.o".to_string()], + // FIXME: Consider adding `-nostdlib` and inheriting from `windows_gnu_base`. pre_link_objects_dll: vec!["rsbegin.o".to_string()], late_link_args, - post_link_objects: vec!["rsend.o".to_string()], - abi_return_struct_as_int: true, - emit_debug_gdb_scripts: false, - requires_uwtable: true, - limit_rdylib_exports: false, + late_link_args_dynamic, + late_link_args_static, - ..Default::default() + ..base } } diff --git a/src/librustc_target/spec/windows_uwp_msvc_base.rs b/src/librustc_target/spec/windows_uwp_msvc_base.rs index 3d639b6b628..04ffa1a0add 100644 --- a/src/librustc_target/spec/windows_uwp_msvc_base.rs +++ b/src/librustc_target/spec/windows_uwp_msvc_base.rs @@ -1,37 +1,14 @@ -use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions}; -use std::default::Default; +use crate::spec::{LinkerFlavor, LldFlavor, TargetOptions}; pub fn opts() -> TargetOptions { - let mut args = LinkArgs::new(); - args.insert( - LinkerFlavor::Msvc, - vec![ - "/NOLOGO".to_string(), - "/NXCOMPAT".to_string(), - "/APPCONTAINER".to_string(), - "mincore.lib".to_string(), - ], - ); + let mut opts = super::windows_msvc_base::opts(); - TargetOptions { - function_sections: true, - dynamic_linking: true, - executables: true, - dll_prefix: String::new(), - dll_suffix: ".dll".to_string(), - exe_suffix: ".exe".to_string(), - staticlib_prefix: String::new(), - staticlib_suffix: ".lib".to_string(), - target_family: Some("windows".to_string()), - is_like_windows: true, - is_like_msvc: true, - pre_link_args: args, - crt_static_allows_dylibs: true, - crt_static_respected: true, - abi_return_struct_as_int: true, - emit_debug_gdb_scripts: false, - requires_uwtable: true, + let pre_link_args_msvc = vec!["/APPCONTAINER".to_string(), "mincore.lib".to_string()]; + opts.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap().extend(pre_link_args_msvc.clone()); + opts.pre_link_args + .get_mut(&LinkerFlavor::Lld(LldFlavor::Link)) + .unwrap() + .extend(pre_link_args_msvc); - ..Default::default() - } + opts } diff --git a/src/librustc_target/spec/x86_64_pc_windows_gnu.rs b/src/librustc_target/spec/x86_64_pc_windows_gnu.rs index 3d3acc682de..eb97fa56814 100644 --- a/src/librustc_target/spec/x86_64_pc_windows_gnu.rs +++ b/src/librustc_target/spec/x86_64_pc_windows_gnu.rs @@ -1,7 +1,7 @@ use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { - let mut base = super::windows_base::opts(); + let mut base = super::windows_gnu_base::opts(); base.cpu = "x86-64".to_string(); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); base.max_atomic_width = Some(64); diff --git a/src/librustc_target/spec/x86_64_unknown_illumos.rs b/src/librustc_target/spec/x86_64_unknown_illumos.rs new file mode 100644 index 00000000000..8d461f67397 --- /dev/null +++ b/src/librustc_target/spec/x86_64_unknown_illumos.rs @@ -0,0 +1,24 @@ +use crate::spec::{LinkerFlavor, Target, TargetResult}; + +pub fn target() -> TargetResult { + let mut base = super::illumos_base::opts(); + base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string(), "-std=c99".to_string()]); + base.cpu = "x86-64".to_string(); + base.max_atomic_width = Some(64); + + Ok(Target { + // LLVM does not currently have a separate illumos target, + // so we still pass Solaris to it + llvm_target: "x86_64-pc-solaris".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-i64:64-f80:128-n8:16:32:64-S128".to_string(), + arch: "x86_64".to_string(), + target_os: "illumos".to_string(), + target_env: String::new(), + target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, + options: base, + }) +} diff --git a/src/librustc_target/spec/x86_64_unknown_uefi.rs b/src/librustc_target/spec/x86_64_unknown_uefi.rs index 7660b68aae6..12edc29330a 100644 --- a/src/librustc_target/spec/x86_64_unknown_uefi.rs +++ b/src/librustc_target/spec/x86_64_unknown_uefi.rs @@ -8,7 +8,7 @@ use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetResult}; pub fn target() -> TargetResult { - let mut base = super::uefi_base::opts(); + let mut base = super::uefi_msvc_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); @@ -28,11 +28,6 @@ pub fn target() -> TargetResult { // places no locality-restrictions, so it fits well here. base.code_model = Some("large".to_string()); - // UEFI mirrors the calling-conventions used on windows. In case of x86-64 this means small - // structs will be returned as int. This shouldn't matter much, since the restrictions placed - // by the UEFI specifications forbid any ABI to return structures. - base.abi_return_struct_as_int = true; - Ok(Target { llvm_target: "x86_64-unknown-windows".to_string(), target_endian: "little".to_string(), diff --git a/src/librustc_target/spec/x86_64_uwp_windows_gnu.rs b/src/librustc_target/spec/x86_64_uwp_windows_gnu.rs index 48366e24a39..ad6002f6b89 100644 --- a/src/librustc_target/spec/x86_64_uwp_windows_gnu.rs +++ b/src/librustc_target/spec/x86_64_uwp_windows_gnu.rs @@ -1,7 +1,7 @@ use crate::spec::{LinkerFlavor, Target, TargetResult}; pub fn target() -> TargetResult { - let mut base = super::windows_uwp_base::opts(); + let mut base = super::windows_uwp_gnu_base::opts(); base.cpu = "x86-64".to_string(); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); base.max_atomic_width = Some(64); diff --git a/src/librustc_trait_selection/opaque_types.rs b/src/librustc_trait_selection/opaque_types.rs index 0cb26e08228..f67b8b87ced 100644 --- a/src/librustc_trait_selection/opaque_types.rs +++ b/src/librustc_trait_selection/opaque_types.rs @@ -972,7 +972,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> { ) .emit(); - self.tcx().consts.err + self.tcx().mk_const(ty::Const { val: ty::ConstKind::Error, ty: ct.ty }) } } } diff --git a/src/librustc_trait_selection/traits/error_reporting/mod.rs b/src/librustc_trait_selection/traits/error_reporting/mod.rs index fef7adf0224..8a9017960fb 100644 --- a/src/librustc_trait_selection/traits/error_reporting/mod.rs +++ b/src/librustc_trait_selection/traits/error_reporting/mod.rs @@ -12,7 +12,7 @@ use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCod use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use crate::infer::{self, InferCtxt, TyCtxtInferExt}; use rustc_data_structures::fx::FxHashMap; -use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder}; +use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorReported}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::{Node, QPath, TyKind, WhereBoundPredicate, WherePredicate}; @@ -126,7 +126,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { .borrow_mut() .entry(span) .or_default() - .push(error.obligation.predicate.clone()); + .push(error.obligation.predicate); } // We do this in 2 passes because we want to display errors in order, though @@ -292,7 +292,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { )), Some( "the question mark operation (`?`) implicitly performs a \ - conversion on the error value using the `From` trait" + conversion on the error value using the `From` trait" .to_owned(), ), ) @@ -312,6 +312,27 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { )) ); + let should_convert_option_to_result = + format!("{}", trait_ref.print_only_trait_path()) + .starts_with("std::convert::From<std::option::NoneError"); + let should_convert_result_to_option = format!("{}", trait_ref) + .starts_with("<std::option::NoneError as std::convert::From<"); + if is_try && is_from && should_convert_option_to_result { + err.span_suggestion_verbose( + span.shrink_to_lo(), + "consider converting the `Option<T>` into a `Result<T, _>` using `Option::ok_or` or `Option::ok_or_else`", + ".ok_or_else(|| /* error value */)".to_string(), + Applicability::HasPlaceholders, + ); + } else if is_try && is_from && should_convert_result_to_option { + err.span_suggestion_verbose( + span.shrink_to_lo(), + "consider converting the `Result<T, _>` into an `Option<T>` using `Result::ok`", + ".ok()".to_string(), + Applicability::MachineApplicable, + ); + } + let explanation = if obligation.cause.code == ObligationCauseCode::MainFunctionType { "consider using `()`, or a `Result`".to_owned() @@ -653,8 +674,17 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { } // Already reported in the query. - ConstEvalFailure(ErrorHandled::Reported) => { - self.tcx.sess.delay_span_bug(span, "constant in type had an ignored error"); + ConstEvalFailure(ErrorHandled::Reported(ErrorReported)) => { + // FIXME(eddyb) remove this once `ErrorReported` becomes a proof token. + self.tcx.sess.delay_span_bug(span, "`ErrorReported` without an error"); + return; + } + + // Already reported in the query, but only as a lint. + // This shouldn't actually happen for constants used in types, modulo + // bugs. The `delay_span_bug` here ensures it won't be ignored. + ConstEvalFailure(ErrorHandled::Linted) => { + self.tcx.sess.delay_span_bug(span, "constant in type had error reported as lint"); return; } @@ -1388,7 +1418,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { (self.tcx.sess.source_map().span_to_snippet(span), &obligation.cause.code) { let generics = self.tcx.generics_of(*def_id); - if generics.params.iter().filter(|p| p.name.as_str() != "Self").next().is_some() + if generics.params.iter().any(|p| p.name.as_str() != "Self") && !snippet.ends_with('>') { // FIXME: To avoid spurious suggestions in functions where type arguments @@ -1817,7 +1847,7 @@ pub fn suggest_constraining_type_param( // Account for `fn foo<T>(t: T) where T: Foo,` so we don't suggest two trailing commas. let mut trailing_comma = false; if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(where_clause_span) { - trailing_comma = snippet.ends_with(","); + trailing_comma = snippet.ends_with(','); } let where_clause_span = if trailing_comma { let hi = where_clause_span.hi(); diff --git a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs index 14029f29151..ed69061d618 100644 --- a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs +++ b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs @@ -10,7 +10,7 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; -use rustc_hir::Node; +use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Node}; use rustc_middle::ty::TypeckTables; use rustc_middle::ty::{ self, AdtKind, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness, @@ -127,13 +127,14 @@ pub trait InferCtxtExt<'tcx> { scope_span: &Option<Span>, expr: Option<hir::HirId>, snippet: String, - first_generator: DefId, - last_generator: Option<DefId>, + inner_generator_body: Option<&hir::Body<'_>>, + outer_generator: Option<DefId>, trait_ref: ty::TraitRef<'_>, target_ty: Ty<'tcx>, tables: &ty::TypeckTables<'_>, obligation: &PredicateObligation<'tcx>, next_code: Option<&ObligationCauseCode<'tcx>>, + from_awaited_ty: Option<Span>, ); fn note_obligation_cause_code<T>( @@ -1029,7 +1030,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { err.note(&format!( "{}s cannot be accessed directly on a `trait`, they can only be \ accessed through a specific `impl`", - assoc_item.kind.suggestion_descr(), + assoc_item.kind.as_def_kind().descr(def_id) )); err.span_suggestion( span, @@ -1044,7 +1045,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { /// Adds an async-await specific note to the diagnostic when the future does not implement /// an auto trait because of a captured type. /// - /// ```ignore (diagnostic) + /// ```text /// note: future does not implement `Qux` as this value is used across an await /// --> $DIR/issue-64130-3-other.rs:17:5 /// | @@ -1059,7 +1060,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { /// When the diagnostic does not implement `Send` or `Sync` specifically, then the diagnostic /// is "replaced" with a different message and a more specific error. /// - /// ```ignore (diagnostic) + /// ```text /// error: future cannot be sent between threads safely /// --> $DIR/issue-64130-2-send.rs:21:5 /// | @@ -1094,6 +1095,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { obligation.predicate, obligation.cause.span ); let source_map = self.tcx.sess.source_map(); + let hir = self.tcx.hir(); // Attempt to detect an async-await error by looking at the obligation causes, looking // for a generator to be present. @@ -1118,8 +1120,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // - `BindingObligation` with `impl_send (Send requirement) // // The first obligation in the chain is the most useful and has the generator that captured - // the type. The last generator has information about where the bound was introduced. At - // least one generator should be present for this diagnostic to be modified. + // the type. The last generator (`outer_generator` below) has information about where the + // bound was introduced. At least one generator should be present for this diagnostic to be + // modified. let (mut trait_ref, mut target_ty) = match obligation.predicate { ty::Predicate::Trait(p, _) => { (Some(p.skip_binder().trait_ref), Some(p.skip_binder().self_ty())) @@ -1127,7 +1130,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { _ => (None, None), }; let mut generator = None; - let mut last_generator = None; + let mut outer_generator = None; let mut next_code = Some(&obligation.cause.code); while let Some(code) = next_code { debug!("maybe_note_obligation_cause_for_async_await: code={:?}", code); @@ -1144,7 +1147,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { match ty.kind { ty::Generator(did, ..) => { generator = generator.or(Some(did)); - last_generator = Some(did); + outer_generator = Some(did); } ty::GeneratorWitness(..) => {} _ if generator.is_none() => { @@ -1176,7 +1179,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let span = self.tcx.def_span(generator_did); // Do not ICE on closure typeck (#66868). - if self.tcx.hir().as_local_hir_id(generator_did).is_none() { + if hir.as_local_hir_id(generator_did).is_none() { return false; } @@ -1202,37 +1205,63 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { } }; + let generator_body = hir + .as_local_hir_id(generator_did) + .and_then(|hir_id| hir.maybe_body_owned_by(hir_id)) + .map(|body_id| hir.body(body_id)); + let mut visitor = AwaitsVisitor::default(); + if let Some(body) = generator_body { + visitor.visit_body(body); + } + debug!("maybe_note_obligation_cause_for_async_await: awaits = {:?}", visitor.awaits); + // Look for a type inside the generator interior that matches the target type to get // a span. let target_ty_erased = self.tcx.erase_regions(&target_ty); + let ty_matches = |ty| -> bool { + // Careful: the regions for types that appear in the + // generator interior are not generally known, so we + // want to erase them when comparing (and anyway, + // `Send` and other bounds are generally unaffected by + // the choice of region). When erasing regions, we + // also have to erase late-bound regions. This is + // because the types that appear in the generator + // interior generally contain "bound regions" to + // represent regions that are part of the suspended + // generator frame. Bound regions are preserved by + // `erase_regions` and so we must also call + // `erase_late_bound_regions`. + let ty_erased = self.tcx.erase_late_bound_regions(&ty::Binder::bind(ty)); + let ty_erased = self.tcx.erase_regions(&ty_erased); + let eq = ty::TyS::same_type(ty_erased, target_ty_erased); + debug!( + "maybe_note_obligation_cause_for_async_await: ty_erased={:?} \ + target_ty_erased={:?} eq={:?}", + ty_erased, target_ty_erased, eq + ); + eq + }; let target_span = tables .generator_interior_types .iter() - .find(|ty::GeneratorInteriorTypeCause { ty, .. }| { - // Careful: the regions for types that appear in the - // generator interior are not generally known, so we - // want to erase them when comparing (and anyway, - // `Send` and other bounds are generally unaffected by - // the choice of region). When erasing regions, we - // also have to erase late-bound regions. This is - // because the types that appear in the generator - // interior generally contain "bound regions" to - // represent regions that are part of the suspended - // generator frame. Bound regions are preserved by - // `erase_regions` and so we must also call - // `erase_late_bound_regions`. - let ty_erased = self.tcx.erase_late_bound_regions(&ty::Binder::bind(*ty)); - let ty_erased = self.tcx.erase_regions(&ty_erased); - let eq = ty::TyS::same_type(ty_erased, target_ty_erased); - debug!( - "maybe_note_obligation_cause_for_async_await: ty_erased={:?} \ - target_ty_erased={:?} eq={:?}", - ty_erased, target_ty_erased, eq - ); - eq - }) - .map(|ty::GeneratorInteriorTypeCause { span, scope_span, expr, .. }| { - (span, source_map.span_to_snippet(*span), scope_span, expr) + .find(|ty::GeneratorInteriorTypeCause { ty, .. }| ty_matches(ty)) + .map(|cause| { + // Check to see if any awaited expressions have the target type. + let from_awaited_ty = visitor + .awaits + .into_iter() + .map(|id| hir.expect_expr(id)) + .find(|await_expr| { + let ty = tables.expr_ty_adjusted(&await_expr); + debug!( + "maybe_note_obligation_cause_for_async_await: await_expr={:?}", + await_expr + ); + ty_matches(ty) + }) + .map(|expr| expr.span); + let ty::GeneratorInteriorTypeCause { span, scope_span, expr, .. } = cause; + (span, source_map.span_to_snippet(*span), scope_span, expr, from_awaited_ty) }); debug!( @@ -1240,20 +1269,21 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { generator_interior_types={:?} target_span={:?}", target_ty, tables.generator_interior_types, target_span ); - if let Some((target_span, Ok(snippet), scope_span, expr)) = target_span { + if let Some((target_span, Ok(snippet), scope_span, expr, from_awaited_ty)) = target_span { self.note_obligation_cause_for_async_await( err, *target_span, scope_span, *expr, snippet, - generator_did, - last_generator, + generator_body, + outer_generator, trait_ref, target_ty, tables, obligation, next_code, + from_awaited_ty, ); true } else { @@ -1270,35 +1300,27 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { scope_span: &Option<Span>, expr: Option<hir::HirId>, snippet: String, - first_generator: DefId, - last_generator: Option<DefId>, + inner_generator_body: Option<&hir::Body<'_>>, + outer_generator: Option<DefId>, trait_ref: ty::TraitRef<'_>, target_ty: Ty<'tcx>, tables: &ty::TypeckTables<'_>, obligation: &PredicateObligation<'tcx>, next_code: Option<&ObligationCauseCode<'tcx>>, + from_awaited_ty: Option<Span>, ) { let source_map = self.tcx.sess.source_map(); - let is_async_fn = self - .tcx - .parent(first_generator) - .map(|parent_did| self.tcx.asyncness(parent_did)) - .map(|parent_asyncness| parent_asyncness == hir::IsAsync::Async) - .unwrap_or(false); - let is_async_move = self - .tcx - .hir() - .as_local_hir_id(first_generator) - .and_then(|hir_id| self.tcx.hir().maybe_body_owned_by(hir_id)) - .map(|body_id| self.tcx.hir().body(body_id)) + let is_async = inner_generator_body .and_then(|body| body.generator_kind()) .map(|generator_kind| match generator_kind { hir::GeneratorKind::Async(..) => true, _ => false, }) .unwrap_or(false); - let await_or_yield = if is_async_fn || is_async_move { "await" } else { "yield" }; + let (await_or_yield, an_await_or_yield) = + if is_async { ("await", "an await") } else { ("yield", "a yield") }; + let future_or_generator = if is_async { "future" } else { "generator" }; // Special case the primary error message when send or sync is the trait that was // not implemented. @@ -1311,22 +1333,34 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { err.clear_code(); err.set_primary_message(format!( - "future cannot be {} between threads safely", - trait_verb + "{} cannot be {} between threads safely", + future_or_generator, trait_verb )); let original_span = err.span.primary_span().unwrap(); let mut span = MultiSpan::from_span(original_span); - let message = if let Some(name) = last_generator - .and_then(|generator_did| self.tcx.parent(generator_did)) - .and_then(|parent_did| hir.as_local_hir_id(parent_did)) - .and_then(|parent_hir_id| hir.opt_name(parent_hir_id)) - { - format!("future returned by `{}` is not {}", name, trait_name) - } else { - format!("future is not {}", trait_name) - }; + let message = outer_generator + .and_then(|generator_did| { + Some(match self.tcx.generator_kind(generator_did).unwrap() { + GeneratorKind::Gen => format!("generator is not {}", trait_name), + GeneratorKind::Async(AsyncGeneratorKind::Fn) => self + .tcx + .parent(generator_did) + .and_then(|parent_did| hir.as_local_hir_id(parent_did)) + .and_then(|parent_hir_id| hir.opt_name(parent_hir_id)) + .map(|name| { + format!("future returned by `{}` is not {}", name, trait_name) + })?, + GeneratorKind::Async(AsyncGeneratorKind::Block) => { + format!("future created by async block is not {}", trait_name) + } + GeneratorKind::Async(AsyncGeneratorKind::Closure) => { + format!("future created by async closure is not {}", trait_name) + } + }) + }) + .unwrap_or_else(|| format!("{} is not {}", future_or_generator, trait_name)); span.push_span_label(original_span, message); err.set_span(span); @@ -1336,31 +1370,56 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { format!("does not implement `{}`", trait_ref.print_only_trait_path()) }; - // Look at the last interior type to get a span for the `.await`. - let await_span = tables.generator_interior_types.iter().map(|t| t.span).last().unwrap(); - let mut span = MultiSpan::from_span(await_span); - span.push_span_label( - await_span, - format!("{} occurs here, with `{}` maybe used later", await_or_yield, snippet), - ); + if let Some(await_span) = from_awaited_ty { + // The type causing this obligation is one being awaited at await_span. + let mut span = MultiSpan::from_span(await_span); - span.push_span_label(target_span, format!("has type `{}`", target_ty)); + span.push_span_label( + await_span, + format!("await occurs here on type `{}`, which {}", target_ty, trait_explanation), + ); - // If available, use the scope span to annotate the drop location. - if let Some(scope_span) = scope_span { + err.span_note( + span, + &format!( + "future {not_trait} as it awaits another future which {not_trait}", + not_trait = trait_explanation + ), + ); + } else { + // Look at the last interior type to get a span for the `.await`. + debug!( + "note_obligation_cause_for_async_await generator_interior_types: {:#?}", + tables.generator_interior_types + ); + let await_span = tables.generator_interior_types.iter().map(|t| t.span).last().unwrap(); + let mut span = MultiSpan::from_span(await_span); span.push_span_label( - source_map.end_point(*scope_span), - format!("`{}` is later dropped here", snippet), + await_span, + format!("{} occurs here, with `{}` maybe used later", await_or_yield, snippet), ); - } - err.span_note( - span, - &format!( - "future {} as this value is used across an {}", - trait_explanation, await_or_yield, - ), - ); + span.push_span_label( + target_span, + format!("has type `{}` which {}", target_ty, trait_explanation), + ); + + // If available, use the scope span to annotate the drop location. + if let Some(scope_span) = scope_span { + span.push_span_label( + source_map.end_point(*scope_span), + format!("`{}` is later dropped here", snippet), + ); + } + + err.span_note( + span, + &format!( + "{} {} as this value is used across {}", + future_or_generator, trait_explanation, an_await_or_yield + ), + ); + } if let Some(expr_id) = expr { let expr = hir.expect_expr(expr_id); @@ -1705,6 +1764,27 @@ impl<'v> Visitor<'v> for ReturnsVisitor<'v> { } } +/// Collect all the awaited expressions within the input expression. +#[derive(Default)] +struct AwaitsVisitor { + awaits: Vec<hir::HirId>, +} + +impl<'v> Visitor<'v> for AwaitsVisitor { + type Map = hir::intravisit::ErasedMap<'v>; + + fn nested_visit_map(&mut self) -> hir::intravisit::NestedVisitorMap<Self::Map> { + hir::intravisit::NestedVisitorMap::None + } + + fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) { + if let hir::ExprKind::Yield(_, hir::YieldSource::Await { expr: Some(id) }) = ex.kind { + self.awaits.push(id) + } + hir::intravisit::walk_expr(self, ex) + } +} + pub trait NextTypeParamName { fn next_type_param_name(&self, name: Option<&str>) -> String; } diff --git a/src/librustc_trait_selection/traits/fulfill.rs b/src/librustc_trait_selection/traits/fulfill.rs index 49a4b96f8b7..300acf95c99 100644 --- a/src/librustc_trait_selection/traits/fulfill.rs +++ b/src/librustc_trait_selection/traits/fulfill.rs @@ -314,7 +314,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { match obligation.predicate { ty::Predicate::Trait(ref data, _) => { - let trait_obligation = obligation.with(data.clone()); + let trait_obligation = obligation.with(*data); if data.is_global() { // no type variables present, can use evaluation for better caching. @@ -420,7 +420,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { } ty::Predicate::Projection(ref data) => { - let project_obligation = obligation.with(data.clone()); + let project_obligation = obligation.with(*data); match project::poly_project_and_unify_type(self.selcx, &project_obligation) { Ok(None) => { let tcx = self.selcx.tcx(); diff --git a/src/librustc_trait_selection/traits/mod.rs b/src/librustc_trait_selection/traits/mod.rs index f5f4a51eb54..f8fc155f582 100644 --- a/src/librustc_trait_selection/traits/mod.rs +++ b/src/librustc_trait_selection/traits/mod.rs @@ -475,7 +475,7 @@ fn vtable_methods<'tcx>( let trait_methods = tcx .associated_items(trait_ref.def_id()) .in_definition_order() - .filter(|item| item.kind == ty::AssocKind::Method); + .filter(|item| item.kind == ty::AssocKind::Fn); // Now list each method's DefId and InternalSubsts (for within its trait). // If the method can never be called from this object, produce None. diff --git a/src/librustc_trait_selection/traits/object_safety.rs b/src/librustc_trait_selection/traits/object_safety.rs index 2389b36f842..d9fba1fd783 100644 --- a/src/librustc_trait_selection/traits/object_safety.rs +++ b/src/librustc_trait_selection/traits/object_safety.rs @@ -86,7 +86,7 @@ fn object_safety_violations_for_trait( let mut violations: Vec<_> = tcx .associated_items(trait_def_id) .in_definition_order() - .filter(|item| item.kind == ty::AssocKind::Method) + .filter(|item| item.kind == ty::AssocKind::Fn) .filter_map(|item| { object_safety_violation_for_method(tcx, trait_def_id, &item) .map(|(code, span)| ObjectSafetyViolation::Method(item.ident.name, code, span)) @@ -362,7 +362,7 @@ fn virtual_call_violation_for_method<'tcx>( method: &ty::AssocItem, ) -> Option<MethodViolationCode> { // The method's first parameter must be named `self` - if !method.method_has_self_argument { + if !method.fn_has_self_parameter { // We'll attempt to provide a structured suggestion for `Self: Sized`. let sugg = tcx.hir().get_if_local(method.def_id).as_ref().and_then(|node| node.generics()).map( diff --git a/src/librustc_trait_selection/traits/query/normalize.rs b/src/librustc_trait_selection/traits/query/normalize.rs index 28d59b41e56..0da26abc330 100644 --- a/src/librustc_trait_selection/traits/query/normalize.rs +++ b/src/librustc_trait_selection/traits/query/normalize.rs @@ -59,11 +59,22 @@ impl<'cx, 'tcx> AtExt<'tcx> for At<'cx, 'tcx> { anon_depth: 0, }; - let value1 = value.fold_with(&mut normalizer); + let result = value.fold_with(&mut normalizer); + debug!( + "normalize::<{}>: result={:?} with {} obligations", + ::std::any::type_name::<T>(), + result, + normalizer.obligations.len(), + ); + debug!( + "normalize::<{}>: obligations={:?}", + ::std::any::type_name::<T>(), + normalizer.obligations, + ); if normalizer.error { Err(NoSolution) } else { - Ok(Normalized { value: value1, obligations: normalizer.obligations }) + Ok(Normalized { value: result, obligations: normalizer.obligations }) } } } diff --git a/src/librustc_trait_selection/traits/select.rs b/src/librustc_trait_selection/traits/select.rs index 0a85999c60d..41847a9218c 100644 --- a/src/librustc_trait_selection/traits/select.rs +++ b/src/librustc_trait_selection/traits/select.rs @@ -413,7 +413,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { match obligation.predicate { ty::Predicate::Trait(ref t, _) => { debug_assert!(!t.has_escaping_bound_vars()); - let obligation = obligation.with(t.clone()); + let obligation = obligation.with(*t); self.evaluate_trait_predicate_recursively(previous_stack, obligation) } @@ -460,7 +460,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } ty::Predicate::Projection(ref data) => { - let project_obligation = obligation.with(data.clone()); + let project_obligation = obligation.with(*data); match project::poly_project_and_unify_type(self, &project_obligation) { Ok(Some(mut subobligations)) => { self.add_depth(subobligations.iter_mut(), obligation.recursion_depth); @@ -910,7 +910,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // separately rather than using `stack.fresh_trait_ref` -- // this is because we want the unbound variables to be // replaced with fresh types starting from index 0. - let cache_fresh_trait_pred = self.infcx.freshen(stack.obligation.predicate.clone()); + let cache_fresh_trait_pred = self.infcx.freshen(stack.obligation.predicate); debug!( "candidate_from_obligation(cache_fresh_trait_pred={:?}, obligation={:?})", cache_fresh_trait_pred, stack @@ -1448,8 +1448,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self.infcx.probe(|_| { self.match_projection( obligation, - bound.clone(), - placeholder_trait_predicate.trait_ref.clone(), + *bound, + placeholder_trait_predicate.trait_ref, &placeholder_map, snapshot, ) @@ -1468,7 +1468,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let result = self.match_projection( obligation, bound, - placeholder_trait_predicate.trait_ref.clone(), + placeholder_trait_predicate.trait_ref, &placeholder_map, snapshot, ); @@ -1520,7 +1520,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // Keep only those bounds which may apply, and propagate overflow if it occurs. let mut param_candidates = vec![]; for bound in matching_bounds { - let wc = self.evaluate_where_clause(stack, bound.clone())?; + let wc = self.evaluate_where_clause(stack, bound)?; if wc.may_apply() { param_candidates.push(ParamCandidate(bound)); } @@ -2496,7 +2496,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // where-clause trait-ref could be unified with the obligation // trait-ref. Repeat that unification now without any // transactional boundary; it should not fail. - match self.match_where_clause_trait_ref(obligation, param.clone()) { + match self.match_where_clause_trait_ref(obligation, param) { Ok(obligations) => obligations, Err(()) => { bug!( diff --git a/src/librustc_trait_selection/traits/util.rs b/src/librustc_trait_selection/traits/util.rs index 725c41c1e2c..ffece42ec30 100644 --- a/src/librustc_trait_selection/traits/util.rs +++ b/src/librustc_trait_selection/traits/util.rs @@ -293,7 +293,7 @@ pub fn count_own_vtable_entries(tcx: TyCtxt<'tcx>, trait_ref: ty::PolyTraitRef<' // Count number of methods and add them to the total offset. // Skip over associated types and constants. for trait_item in tcx.associated_items(trait_ref.def_id()).in_definition_order() { - if trait_item.kind == ty::AssocKind::Method { + if trait_item.kind == ty::AssocKind::Fn { entries += 1; } } @@ -315,10 +315,10 @@ pub fn get_vtable_index_of_object_method<N>( for trait_item in tcx.associated_items(object.upcast_trait_ref.def_id()).in_definition_order() { if trait_item.def_id == method_def_id { // The item with the ID we were given really ought to be a method. - assert_eq!(trait_item.kind, ty::AssocKind::Method); + assert_eq!(trait_item.kind, ty::AssocKind::Fn); return entries; } - if trait_item.kind == ty::AssocKind::Method { + if trait_item.kind == ty::AssocKind::Fn { entries += 1; } } diff --git a/src/librustc_traits/implied_outlives_bounds.rs b/src/librustc_traits/implied_outlives_bounds.rs index 33ecbe72a8c..6db2e557fea 100644 --- a/src/librustc_traits/implied_outlives_bounds.rs +++ b/src/librustc_traits/implied_outlives_bounds.rs @@ -62,7 +62,7 @@ fn compute_implied_outlives_bounds<'tcx>( // unresolved inference variables here anyway, but there might be // during typeck under some circumstances.) let obligations = - wf::obligations(infcx, param_env, hir::DUMMY_HIR_ID, ty, DUMMY_SP).unwrap_or(vec![]); + wf::obligations(infcx, param_env, hir::CRATE_HIR_ID, ty, DUMMY_SP).unwrap_or(vec![]); // N.B., all of these predicates *ought* to be easily proven // true. In fact, their correctness is (mostly) implied by diff --git a/src/librustc_ty/ty.rs b/src/librustc_ty/ty.rs index aefe61f60b8..43ff39f92f7 100644 --- a/src/librustc_ty/ty.rs +++ b/src/librustc_ty/ty.rs @@ -85,7 +85,7 @@ fn associated_item_from_trait_item_ref( let def_id = tcx.hir().local_def_id(trait_item_ref.id.hir_id); let (kind, has_self) = match trait_item_ref.kind { hir::AssocItemKind::Const => (ty::AssocKind::Const, false), - hir::AssocItemKind::Method { has_self } => (ty::AssocKind::Method, has_self), + hir::AssocItemKind::Fn { has_self } => (ty::AssocKind::Fn, has_self), hir::AssocItemKind::Type => (ty::AssocKind::Type, false), hir::AssocItemKind::OpaqueTy => bug!("only impls can have opaque types"), }; @@ -98,7 +98,7 @@ fn associated_item_from_trait_item_ref( defaultness: trait_item_ref.defaultness, def_id, container: ty::TraitContainer(parent_def_id), - method_has_self_argument: has_self, + fn_has_self_parameter: has_self, } } @@ -110,7 +110,7 @@ fn associated_item_from_impl_item_ref( let def_id = tcx.hir().local_def_id(impl_item_ref.id.hir_id); let (kind, has_self) = match impl_item_ref.kind { hir::AssocItemKind::Const => (ty::AssocKind::Const, false), - hir::AssocItemKind::Method { has_self } => (ty::AssocKind::Method, has_self), + hir::AssocItemKind::Fn { has_self } => (ty::AssocKind::Fn, has_self), hir::AssocItemKind::Type => (ty::AssocKind::Type, false), hir::AssocItemKind::OpaqueTy => (ty::AssocKind::OpaqueTy, false), }; @@ -123,7 +123,7 @@ fn associated_item_from_impl_item_ref( defaultness: impl_item_ref.defaultness, def_id, container: ty::ImplContainer(parent_def_id), - method_has_self_argument: has_self, + fn_has_self_parameter: has_self, } } @@ -265,7 +265,7 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { let unnormalized_env = ty::ParamEnv::new(tcx.intern_predicates(&predicates), traits::Reveal::UserFacing, None); - let body_id = tcx.hir().as_local_hir_id(def_id).map_or(hir::DUMMY_HIR_ID, |id| { + let body_id = tcx.hir().as_local_hir_id(def_id).map_or(hir::CRATE_HIR_ID, |id| { tcx.hir().maybe_body_owned_by(id).map_or(id, |body| body.hir_id) }); let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id); diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 87e5baa57e9..895042f3ab1 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -826,14 +826,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } } GenericParamDefKind::Const => { + let ty = tcx.at(span).type_of(param.def_id); // FIXME(const_generics:defaults) if infer_args { // No const parameters were provided, we can infer all. - let ty = tcx.at(span).type_of(param.def_id); self.ct_infer(ty, Some(param), span).into() } else { // We've already errored above about the mismatch. - tcx.consts.err.into() + tcx.mk_const(ty::Const { val: ty::ConstKind::Error, ty }).into() } } } @@ -1250,7 +1250,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { /// This helper takes a *converted* parameter type (`param_ty`) /// and an *unconverted* list of bounds: /// - /// ``` + /// ```text /// fn foo<T: Debug> /// ^ ^^^^^ `ast_bounds` parameter, in HIR form /// | @@ -2992,7 +2992,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { /// representations). These lists of bounds occur in many places in /// Rust's syntax: /// -/// ``` +/// ```text /// trait Foo: Bar + Baz { } /// ^^^^^^^^^ supertrait list bounding the `Self` type parameter /// diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 24db25a1f34..82c8a5543eb 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -516,7 +516,7 @@ fn compare_self_type<'tcx>( }) }; - match (trait_m.method_has_self_argument, impl_m.method_has_self_argument) { + match (trait_m.fn_has_self_parameter, impl_m.fn_has_self_parameter) { (false, false) | (true, true) => {} (false, true) => { @@ -1163,7 +1163,7 @@ fn compare_type_predicate_entailment( fn assoc_item_kind_str(impl_item: &ty::AssocItem) -> &'static str { match impl_item.kind { ty::AssocKind::Const => "const", - ty::AssocKind::Method => "method", + ty::AssocKind::Fn => "method", ty::AssocKind::Type | ty::AssocKind::OpaqueTy => "type", } } diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 369bb183bcd..be45ada866f 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -217,14 +217,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: Span, expected: Ty<'tcx>, checked_ty: Ty<'tcx>, + hir_id: hir::HirId, ) -> Vec<AssocItem> { - let mut methods = self.probe_for_return_type( - span, - probe::Mode::MethodCall, - expected, - checked_ty, - hir::DUMMY_HIR_ID, - ); + let mut methods = + self.probe_for_return_type(span, probe::Mode::MethodCall, expected, checked_ty, hir_id); methods.retain(|m| { self.has_no_input_arg(m) && self @@ -250,9 +246,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // This function checks if the method isn't static and takes other arguments than `self`. fn has_no_input_arg(&self, method: &AssocItem) -> bool { match method.kind { - ty::AssocKind::Method => { - self.tcx.fn_sig(method.def_id).inputs().skip_binder().len() == 1 - } + ty::AssocKind::Fn => self.tcx.fn_sig(method.def_id).inputs().skip_binder().len() == 1, _ => false, } } @@ -753,8 +747,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match (&expected_ty.kind, &checked_ty.kind) { (&ty::Int(ref exp), &ty::Int(ref found)) => { - let is_fallible = match (found.bit_width(), exp.bit_width()) { - (Some(found), Some(exp)) if found > exp => true, + let is_fallible = match (exp.bit_width(), found.bit_width()) { + (Some(exp), Some(found)) if exp < found => true, + (None, Some(8 | 16)) => false, (None, _) | (_, None) => true, _ => false, }; @@ -762,8 +757,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { true } (&ty::Uint(ref exp), &ty::Uint(ref found)) => { - let is_fallible = match (found.bit_width(), exp.bit_width()) { - (Some(found), Some(exp)) if found > exp => true, + let is_fallible = match (exp.bit_width(), found.bit_width()) { + (Some(exp), Some(found)) if exp < found => true, + (None, Some(8 | 16)) => false, (None, _) | (_, None) => true, _ => false, }; diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index 57e2349bb2e..dbda735aa99 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -975,18 +975,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected: Expectation<'tcx>, expr: &'tcx hir::Expr<'tcx>, ) -> Ty<'tcx> { - let uty = expected.to_option(self).and_then(|uty| match uty.kind { - ty::Array(ty, _) | ty::Slice(ty) => Some(ty), - _ => None, - }); - let element_ty = if !args.is_empty() { - let coerce_to = uty.unwrap_or_else(|| { - self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span: expr.span, + let coerce_to = expected + .to_option(self) + .and_then(|uty| match uty.kind { + ty::Array(ty, _) | ty::Slice(ty) => Some(ty), + _ => None, }) - }); + .unwrap_or_else(|| { + self.next_ty_var(TypeVariableOrigin { + kind: TypeVariableOriginKind::TypeInference, + span: expr.span, + }) + }); let mut coerce = CoerceMany::with_coercion_sites(coerce_to, args); assert_eq!(self.diverges.get(), Diverges::Maybe); for e in args { @@ -1797,7 +1798,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // we know that the yield type must be `()`; however, the context won't contain this // information. Hence, we check the source of the yield expression here and check its // value's type against `()` (this check should always hold). - None if src == &hir::YieldSource::Await => { + None if src.is_await() => { self.check_expr_coercable_to_type(&value, self.tcx.mk_unit()); self.tcx.mk_unit() } diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 210ba92e811..3f81689cdc9 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -209,7 +209,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { "impl {:?} is not an inherent impl", impl_def_id ); - self.impl_self_ty(self.span, impl_def_id).substs + self.fresh_substs_for_item(self.span, impl_def_id) } probe::ObjectPick => { diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index deaff19de08..c4f53332cb6 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -171,11 +171,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// /// Given a method call like `foo.bar::<T1,...Tn>(...)`: /// - /// * `fcx`: the surrounding `FnCtxt` (!) - /// * `span`: the span for the method call - /// * `method_name`: the name of the method being called (`bar`) + /// * `self`: the surrounding `FnCtxt` (!) /// * `self_ty`: the (unadjusted) type of the self expression (`foo`) - /// * `supplied_method_types`: the explicit method type parameters, if any (`T1..Tn`) + /// * `segment`: the name and generic arguments of the method (`bar::<T1, ...Tn>`) + /// * `span`: the span for the method call + /// * `call_expr`: the complete method call: (`foo.bar::<T1,...Tn>(...)`) /// * `self_expr`: the self expression (`foo`) pub fn lookup_method( &self, @@ -467,7 +467,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - let def_kind = pick.item.def_kind(); + let def_kind = pick.item.kind.as_def_kind(); debug!("resolve_ufcs: def_kind={:?}, def_id={:?}", def_kind, pick.item.def_id); tcx.check_stability(pick.item.def_id, Some(expr_id), span); Ok((def_kind, pick.item.def_id)) diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 7e7d84c1996..3f159fe5e30 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -452,7 +452,7 @@ fn method_autoderef_steps<'tcx>( tcx.infer_ctxt().enter_with_canonical(DUMMY_SP, &goal, |ref infcx, goal, inference_vars| { let ParamEnvAnd { param_env, value: self_ty } = goal; - let mut autoderef = Autoderef::new(infcx, param_env, hir::DUMMY_HIR_ID, DUMMY_SP, self_ty) + let mut autoderef = Autoderef::new(infcx, param_env, hir::CRATE_HIR_ID, DUMMY_SP, self_ty) .include_raw_pointers() .silence_errors(); let mut reached_raw_pointer = false; @@ -570,7 +570,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { self.extension_candidates.push(candidate); } } else if self.private_candidate.is_none() { - self.private_candidate = Some((candidate.item.def_kind(), candidate.item.def_id)); + self.private_candidate = + Some((candidate.item.kind.as_def_kind(), candidate.item.def_id)); } } @@ -648,11 +649,16 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } ty::RawPtr(ty::TypeAndMut { ty: _, mutbl }) => { - let lang_def_id = match mutbl { - hir::Mutability::Not => lang_items.const_ptr_impl(), - hir::Mutability::Mut => lang_items.mut_ptr_impl(), + let (lang_def_id1, lang_def_id2) = match mutbl { + hir::Mutability::Not => { + (lang_items.const_ptr_impl(), lang_items.const_slice_ptr_impl()) + } + hir::Mutability::Mut => { + (lang_items.mut_ptr_impl(), lang_items.mut_slice_ptr_impl()) + } }; - self.assemble_inherent_impl_for_primitive(lang_def_id); + self.assemble_inherent_impl_for_primitive(lang_def_id1); + self.assemble_inherent_impl_for_primitive(lang_def_id2); } ty::Int(i) => { let lang_def_id = match i { @@ -859,9 +865,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { &mut self, expr_hir_id: hir::HirId, ) -> Result<(), MethodError<'tcx>> { - if expr_hir_id == hir::DUMMY_HIR_ID { - return Ok(()); - } let mut duplicates = FxHashSet::default(); let opt_applicable_traits = self.tcx.in_scope_traits(expr_hir_id); if let Some(applicable_traits) = opt_applicable_traits { @@ -896,7 +899,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { expected: Ty<'tcx>, ) -> bool { match method.kind { - ty::AssocKind::Method => { + ty::AssocKind::Fn => { let fty = self.tcx.fn_sig(method.def_id); self.probe(|_| { let substs = self.fresh_substs_for_item(self.span, method.def_id); @@ -1128,8 +1131,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { ) -> Option<PickResult<'tcx>> { let tcx = self.tcx; - // In general, during probing we erase regions. See - // `impl_self_ty()` for an explanation. + // In general, during probing we erase regions. let region = tcx.lifetimes.re_erased; let autoref_ty = tcx.mk_ref(region, ty::TypeAndMut { ty: self_ty, mutbl }); @@ -1513,7 +1515,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { ); pcx.allow_similar_names = true; pcx.assemble_inherent_candidates(); - pcx.assemble_extension_candidates_for_traits_in_scope(hir::DUMMY_HIR_ID)?; let method_names = pcx.candidate_method_names(); pcx.allow_similar_names = false; @@ -1523,10 +1524,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { pcx.reset(); pcx.method_name = Some(method_name); pcx.assemble_inherent_candidates(); - pcx.assemble_extension_candidates_for_traits_in_scope(hir::DUMMY_HIR_ID) - .map_or(None, |_| { - pcx.pick_core().and_then(|pick| pick.ok()).map(|pick| pick.item) - }) + pcx.pick_core().and_then(|pick| pick.ok()).map(|pick| pick.item) }) .collect(); @@ -1554,10 +1552,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // In Path mode (i.e., resolving a value like `T::next`), consider any // associated value (i.e., methods, constants) but not types. match self.mode { - Mode::MethodCall => item.method_has_self_argument, + Mode::MethodCall => item.fn_has_self_parameter, Mode::Path => match item.kind { ty::AssocKind::OpaqueTy | ty::AssocKind::Type => false, - ty::AssocKind::Method | ty::AssocKind::Const => true, + ty::AssocKind::Fn | ty::AssocKind::Const => true, }, } // FIXME -- check for types that deref to `Self`, @@ -1578,7 +1576,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { impl_ty: Ty<'tcx>, substs: SubstsRef<'tcx>, ) -> (Ty<'tcx>, Option<Ty<'tcx>>) { - if item.kind == ty::AssocKind::Method && self.mode == Mode::MethodCall { + if item.kind == ty::AssocKind::Fn && self.mode == Mode::MethodCall { let sig = self.xform_method_sig(item.def_id, substs); (sig.inputs()[0], Some(sig.output())) } else { @@ -1614,8 +1612,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } else { match param.kind { GenericParamDefKind::Lifetime => { - // In general, during probe we erase regions. See - // `impl_self_ty()` for an explanation. + // In general, during probe we erase regions. self.tcx.lifetimes.re_erased.into() } GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => { diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index f075d1e74d4..edde9b1a1a1 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -117,7 +117,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .span_if_local(item.def_id) .or_else(|| self.tcx.hir().span_if_local(impl_did)); - let impl_ty = self.impl_self_ty(span, impl_did).ty; + let impl_ty = self.tcx.at(span).type_of(impl_did); let insertion = match self.tcx.impl_trait_ref(impl_did) { None => String::new(), @@ -162,7 +162,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::AssocKind::Const | ty::AssocKind::Type | ty::AssocKind::OpaqueTy => rcvr_ty, - ty::AssocKind::Method => self + ty::AssocKind::Fn => self .tcx .fn_sig(item.def_id) .inputs() @@ -179,6 +179,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { path, ty, item.kind, + item.def_id, sugg_span, idx, self.tcx.sess.source_map(), @@ -220,6 +221,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { path, rcvr_ty, item.kind, + item.def_id, sugg_span, idx, self.tcx.sess.source_map(), @@ -537,7 +539,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // When the "method" is resolved through dereferencing, we really want the // original type that has the associated function for accurate suggestions. // (#61411) - let ty = self.impl_self_ty(span, *impl_did).ty; + let ty = tcx.at(span).type_of(*impl_did); match (&ty.peel_refs().kind, &actual.peel_refs().kind) { (ty::Adt(def, _), ty::Adt(def_actual, _)) if def == def_actual => { // Use `actual` as it will have more `substs` filled in. @@ -764,7 +766,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_label(span, msg); } } else if let Some(lev_candidate) = lev_candidate { - let def_kind = lev_candidate.def_kind(); + let def_kind = lev_candidate.kind.as_def_kind(); err.span_suggestion( span, &format!( @@ -957,7 +959,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && self .associated_item(info.def_id, item_name, Namespace::ValueNS) .filter(|item| { - if let ty::AssocKind::Method = item.kind { + if let ty::AssocKind::Fn = item.kind { let id = self.tcx.hir().as_local_hir_id(item.def_id); if let Some(hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Fn(fn_sig, method), @@ -1387,12 +1389,13 @@ fn print_disambiguation_help( trait_name: String, rcvr_ty: Ty<'_>, kind: ty::AssocKind, + def_id: DefId, span: Span, candidate: Option<usize>, source_map: &source_map::SourceMap, ) { let mut applicability = Applicability::MachineApplicable; - let sugg_args = if let (ty::AssocKind::Method, Some(args)) = (kind, args) { + let sugg_args = if let (ty::AssocKind::Fn, Some(args)) = (kind, args) { format!( "({}{})", if rcvr_ty.is_region_ptr() { @@ -1416,7 +1419,7 @@ fn print_disambiguation_help( span, &format!( "disambiguate the {} for {}", - kind.suggestion_descr(), + kind.as_def_kind().descr(def_id), if let Some(candidate) = candidate { format!("candidate #{}", candidate) } else { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 4b5953b5e95..ca6bd21fefd 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -154,7 +154,6 @@ use std::slice; use crate::require_c_abi_if_c_variadic; use crate::util::common::indenter; -use crate::TypeAndSubsts; use self::autoderef::Autoderef; use self::callee::DeferredCallResolution; @@ -839,7 +838,11 @@ fn has_typeck_tables(tcx: TyCtxt<'_>, def_id: DefId) -> bool { return tcx.has_typeck_tables(outer_def_id); } - if let Some(id) = tcx.hir().as_local_hir_id(def_id) { + // FIXME(#71104) Should really be using just `as_local_hir_id` but + // some `LocalDefId` do not seem to have a corresponding HirId. + if let Some(id) = + def_id.as_local().and_then(|def_id| tcx.hir().opt_local_def_id_to_hir_id(def_id)) + { primary_body_of(tcx, id).is_some() } else { false @@ -1904,7 +1907,7 @@ fn check_specialization_validity<'tcx>( ) { let kind = match impl_item.kind { hir::ImplItemKind::Const(..) => ty::AssocKind::Const, - hir::ImplItemKind::Fn(..) => ty::AssocKind::Method, + hir::ImplItemKind::Fn(..) => ty::AssocKind::Fn, hir::ImplItemKind::OpaqueTy(..) => ty::AssocKind::OpaqueTy, hir::ImplItemKind::TyAlias(_) => ty::AssocKind::Type, }; @@ -2050,7 +2053,7 @@ fn check_impl_items_against_trait<'tcx>( } hir::ImplItemKind::Fn(..) => { let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id); - if ty_trait_item.kind == ty::AssocKind::Method { + if ty_trait_item.kind == ty::AssocKind::Fn { compare_impl_method( tcx, &ty_impl_item, @@ -2296,7 +2299,7 @@ fn fn_sig_suggestion( /// structured suggestion. fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String { match assoc.kind { - ty::AssocKind::Method => { + ty::AssocKind::Fn => { // We skip the binder here because the binder would deanonymize all // late-bound regions, and we don't want method signatures to show up // `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound @@ -3312,8 +3315,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } pub fn to_const(&self, ast_c: &hir::AnonConst) -> &'tcx ty::Const<'tcx> { - let c = self.tcx.hir().local_def_id(ast_c.hir_id).expect_local(); - ty::Const::from_anon_const(self.tcx, c) + let const_def_id = self.tcx.hir().local_def_id(ast_c.hir_id).expect_local(); + let c = ty::Const::from_anon_const(self.tcx, const_def_id); + + // HACK(eddyb) emulate what a `WellFormedConst` obligation would do. + // This code should be replaced with the proper WF handling ASAP. + if let ty::ConstKind::Unevaluated(def_id, substs, promoted) = c.val { + assert!(promoted.is_none()); + + // HACK(eddyb) let's hope these are always empty. + // let obligations = self.nominal_obligations(def_id, substs); + // self.out.extend(obligations); + + let cause = traits::ObligationCause::new( + self.tcx.def_span(const_def_id.to_def_id()), + self.body_id, + traits::MiscObligation, + ); + self.register_predicate(traits::Obligation::new( + cause, + self.param_env, + ty::Predicate::ConstEvaluatable(def_id, substs), + )); + } + + c } // If the type given by the user has free regions, save it for later, since @@ -4251,24 +4277,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - // Determine the `Self` type, using fresh variables for all variables - // declared on the impl declaration e.g., `impl<A,B> for Vec<(A,B)>` - // would return `($0, $1)` where `$0` and `$1` are freshly instantiated type - // variables. - pub fn impl_self_ty( - &self, - span: Span, // (potential) receiver for this impl - did: DefId, - ) -> TypeAndSubsts<'tcx> { - let ity = self.tcx.type_of(did); - debug!("impl_self_ty: ity={:?}", ity); - - let substs = self.fresh_substs_for_item(span, did); - let substd_ty = self.instantiate_type_scheme(span, &substs, &ity); - - TypeAndSubsts { substs, ty: substd_ty } - } - /// Unifies the output type with the expected type early, for more coercions /// and forward type information on the input expressions. fn expected_inputs_for_expected_output( @@ -5000,7 +5008,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else if !self.check_for_cast(err, expr, found, expected) { let is_struct_pat_shorthand_field = self.is_hir_id_from_struct_pattern_shorthand_field(expr.hir_id, expr.span); - let methods = self.get_conversion_methods(expr.span, expected, found); + let methods = self.get_conversion_methods(expr.span, expected, found, expr.hir_id); if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) { let mut suggestions = iter::repeat(&expr_text) .zip(methods.iter()) diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 5bfad558b6b..32004744ff9 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -294,7 +294,7 @@ fn check_associated_item( let ty = fcx.normalize_associated_types_in(span, &ty); fcx.register_wf_obligation(ty, span, code.clone()); } - ty::AssocKind::Method => { + ty::AssocKind::Fn => { let sig = fcx.tcx.fn_sig(item.def_id); let sig = fcx.normalize_associated_types_in(span, &sig); let hir_sig = sig_if_method.expect("bad signature for method"); @@ -335,7 +335,7 @@ fn for_id(tcx: TyCtxt<'_>, id: hir::HirId, span: Span) -> CheckWfFcxBuilder<'_> inherited: Inherited::build(tcx, def_id), id, span, - param_env: tcx.param_env(def_id.to_def_id()), + param_env: tcx.param_env(def_id), } } @@ -985,7 +985,7 @@ fn check_method_receiver<'fcx, 'tcx>( // Check that the method has a valid receiver type, given the type `Self`. debug!("check_method_receiver({:?}, self_ty={:?})", method, self_ty); - if !method.method_has_self_argument { + if !method.fn_has_self_parameter { return; } diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 146fc04bc27..7b66743b098 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -5,6 +5,7 @@ use crate::check::FnCtxt; use rustc_data_structures::sync::Lrc; +use rustc_errors::ErrorReported; use rustc_hir as hir; use rustc_hir::def_id::DefIdSet; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; @@ -75,7 +76,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { wbcx.tables.upvar_list = mem::replace(&mut self.tables.borrow_mut().upvar_list, Default::default()); - wbcx.tables.tainted_by_errors = self.is_tainted_by_errors(); + if self.is_tainted_by_errors() { + // FIXME(eddyb) keep track of `ErrorReported` from where the error was emitted. + wbcx.tables.tainted_by_errors = Some(ErrorReported); + } debug!("writeback: tables for {:?} are {:#?}", item_def_id, wbcx.tables); @@ -373,7 +377,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { ); }; - self.tables.user_provided_types_mut().insert(hir_id, c_ty.clone()); + self.tables.user_provided_types_mut().insert(hir_id, *c_ty); if let ty::UserType::TypeOf(_, user_substs) = c_ty.value { if self.rustc_dump_user_substs { @@ -411,7 +415,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { ); }; - self.tables.user_provided_sigs.insert(def_id, c_sig.clone()); + self.tables.user_provided_sigs.insert(def_id, *c_sig); } } @@ -562,7 +566,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { for (&local_id, fn_sig) in fcx_tables.liberated_fn_sigs().iter() { let hir_id = hir::HirId { owner: common_hir_owner, local_id }; let fn_sig = self.resolve(fn_sig, &hir_id); - self.tables.liberated_fn_sigs_mut().insert(hir_id, fn_sig.clone()); + self.tables.liberated_fn_sigs_mut().insert(hir_id, fn_sig); } } @@ -578,14 +582,24 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { } } - fn resolve<T>(&self, x: &T, span: &dyn Locatable) -> T + fn resolve<T>(&mut self, x: &T, span: &dyn Locatable) -> T where T: TypeFoldable<'tcx>, { - let x = x.fold_with(&mut Resolver::new(self.fcx, span, self.body)); + let mut resolver = Resolver::new(self.fcx, span, self.body); + let x = x.fold_with(&mut resolver); if cfg!(debug_assertions) && x.needs_infer() { span_bug!(span.to_span(self.fcx.tcx), "writeback: `{:?}` has inference variables", x); } + + // We may have introduced e.g. `ty::Error`, if inference failed, make sure + // to mark the `TypeckTables` as tainted in that case, so that downstream + // users of the tables don't produce extra errors, or worse, ICEs. + if resolver.replaced_with_error { + // FIXME(eddyb) keep track of `ErrorReported` from where the error was emitted. + self.tables.tainted_by_errors = Some(ErrorReported); + } + x } } @@ -613,6 +627,9 @@ struct Resolver<'cx, 'tcx> { infcx: &'cx InferCtxt<'cx, 'tcx>, span: &'cx dyn Locatable, body: &'tcx hir::Body<'tcx>, + + /// Set to `true` if any `Ty` or `ty::Const` had to be replaced with an `Error`. + replaced_with_error: bool, } impl<'cx, 'tcx> Resolver<'cx, 'tcx> { @@ -621,7 +638,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> { span: &'cx dyn Locatable, body: &'tcx hir::Body<'tcx>, ) -> Resolver<'cx, 'tcx> { - Resolver { tcx: fcx.tcx, infcx: fcx, span, body } + Resolver { tcx: fcx.tcx, infcx: fcx, span, body, replaced_with_error: false } } fn report_error(&self, t: Ty<'tcx>) { @@ -644,6 +661,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> { Err(_) => { debug!("Resolver::fold_ty: input type `{:?}` not fully resolvable", t); self.report_error(t); + self.replaced_with_error = true; self.tcx().types.err } } @@ -661,7 +679,8 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> { debug!("Resolver::fold_const: input const `{:?}` not fully resolvable", ct); // FIXME: we'd like to use `self.report_error`, but it doesn't yet // accept a &'tcx ty::Const. - self.tcx().consts.err + self.replaced_with_error = true; + self.tcx().mk_const(ty::Const { val: ty::ConstKind::Error, ty: ct.ty }) } } } diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs index 9ace9f424b7..2e841734770 100644 --- a/src/librustc_typeck/coherence/inherent_impls.rs +++ b/src/librustc_typeck/coherence/inherent_impls.rs @@ -112,6 +112,30 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> { item.span, ); } + ty::RawPtr(ty::TypeAndMut { ty: inner, mutbl: hir::Mutability::Not }) + if matches!(inner.kind, ty::Slice(_)) => + { + self.check_primitive_impl( + def_id, + lang_items.const_slice_ptr_impl(), + None, + "const_slice_ptr", + "*const [T]", + item.span, + ); + } + ty::RawPtr(ty::TypeAndMut { ty: inner, mutbl: hir::Mutability::Mut }) + if matches!(inner.kind, ty::Slice(_)) => + { + self.check_primitive_impl( + def_id, + lang_items.mut_slice_ptr_impl(), + None, + "mut_slice_ptr", + "*mut [T]", + item.span, + ); + } ty::RawPtr(ty::TypeAndMut { ty: _, mutbl: hir::Mutability::Not }) => { self.check_primitive_impl( def_id, diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 8ae779a4783..7794f62efb7 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -316,13 +316,13 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> { fn ct_infer( &self, - _: Ty<'tcx>, + ty: Ty<'tcx>, _: Option<&ty::GenericParamDef>, span: Span, ) -> &'tcx Const<'tcx> { bad_placeholder_type(self.tcx(), vec![span]).emit(); - self.tcx().consts.err + self.tcx().mk_const(ty::Const { val: ty::ConstKind::Error, ty }) } fn projected_ty_from_poly_trait_ref( @@ -1170,14 +1170,28 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::Generics { } // FIXME(#43408) enable this always when we get lazy normalization. Node::AnonConst(_) => { + let parent_id = tcx.hir().get_parent_item(hir_id); + let parent_def_id = tcx.hir().local_def_id(parent_id); + // HACK(eddyb) this provides the correct generics when // `feature(const_generics)` is enabled, so that const expressions // used with const generics, e.g. `Foo<{N+1}>`, can work at all. if tcx.features().const_generics { - let parent_id = tcx.hir().get_parent_item(hir_id); - Some(tcx.hir().local_def_id(parent_id)) + Some(parent_def_id) } else { - None + let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id)); + match parent_node { + // HACK(eddyb) this provides the correct generics for repeat + // expressions' count (i.e. `N` in `[x; N]`), as they shouldn't + // be able to cause query cycle errors. + Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. }) + if constant.hir_id == hir_id => + { + Some(parent_def_id) + } + + _ => None, + } } } Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure(..), .. }) => { @@ -2023,7 +2037,8 @@ fn associated_item_predicates( } ty::GenericParamDefKind::Const => { unimplemented_error("const"); - tcx.consts.err.into() + tcx.mk_const(ty::Const { val: ty::ConstKind::Error, ty: tcx.type_of(param.def_id) }) + .into() } } }; @@ -2583,7 +2598,7 @@ fn should_inherit_track_caller(tcx: TyCtxt<'_>, def_id: DefId) -> bool { .associated_items(trait_def_id) .filter_by_name_unhygienic(impl_item.ident.name) .find(move |trait_item| { - trait_item.kind == ty::AssocKind::Method + trait_item.kind == ty::AssocKind::Fn && tcx.hygienic_eq(impl_item.ident, trait_item.ident, trait_def_id) }) { diff --git a/src/librustc_typeck/collect/type_of.rs b/src/librustc_typeck/collect/type_of.rs index 985f66694b6..e17b736058f 100644 --- a/src/librustc_typeck/collect/type_of.rs +++ b/src/librustc_typeck/collect/type_of.rs @@ -1,5 +1,5 @@ use rustc_data_structures::fx::FxHashSet; -use rustc_errors::{struct_span_err, Applicability, StashKey}; +use rustc_errors::{struct_span_err, Applicability, ErrorReported, StashKey}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; @@ -125,7 +125,9 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { owner, def_id, ), ); - if tcx.typeck_tables_of(owner).tainted_by_errors { + if let Some(ErrorReported) = + tcx.typeck_tables_of(owner).tainted_by_errors + { // Some error in the // owner fn prevented us from populating // the `concrete_opaque_types` table. diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs index 0635ad5babc..319f3238513 100644 --- a/src/librustc_typeck/impl_wf_check.rs +++ b/src/librustc_typeck/impl_wf_check.rs @@ -147,7 +147,7 @@ fn enforce_impl_params_are_constrained( let predicates = tcx.predicates_of(def_id).instantiate_identity(tcx); cgp::parameters_for(&predicates, true) } - ty::AssocKind::Method | ty::AssocKind::Const => Vec::new(), + ty::AssocKind::Fn | ty::AssocKind::Const => Vec::new(), } }) .collect(); diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 69d0b3723b0..df8290fd018 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -97,7 +97,6 @@ use rustc_infer::infer::{InferOk, TyCtxtInferExt}; use rustc_infer::traits::TraitEngineExt as _; use rustc_middle::middle; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::util; use rustc_session::config::EntryFnType; @@ -111,10 +110,6 @@ use rustc_trait_selection::traits::{ use std::iter; use astconv::{AstConv, Bounds}; -pub struct TypeAndSubsts<'tcx> { - substs: SubstsRef<'tcx>, - ty: Ty<'tcx>, -} fn require_c_abi_if_c_variadic(tcx: TyCtxt<'_>, decl: &hir::FnDecl<'_>, abi: Abi, span: Span) { if decl.c_variadic && !(abi == Abi::C || abi == Abi::Cdecl) { diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index eb8aec708a6..144c1699a3c 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -509,7 +509,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { continue; } - let mut for_generics = self.extract_for_generics(tcx, orig_p.clone()); + let mut for_generics = self.extract_for_generics(tcx, orig_p); assert!(bounds.len() == 1); let mut b = bounds.pop().expect("bounds were empty"); diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 775d600fc3d..57d499e38a7 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -360,6 +360,7 @@ impl<'a> fmt::Display for Html<'a> { "fuchsia" => "Fuchsia", "haiku" => "Haiku", "hermit" => "HermitCore", + "illumos" => "illumos", "ios" => "iOS", "l4re" => "L4Re", "linux" => "Linux", diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index a82015dea5f..e9af0ee5c23 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -47,7 +47,7 @@ pub fn try_inline( } let mut ret = Vec::new(); - let attrs_clone = attrs.clone(); + let attrs_clone = attrs; let inner = match res { Res::Def(DefKind::Trait, did) => { @@ -292,7 +292,7 @@ pub fn build_impls(cx: &DocContext<'_>, did: DefId, attrs: Option<Attrs<'_>>) -> let mut impls = Vec::new(); for &did in tcx.inherent_impls(did).iter() { - build_impl(cx, did, attrs.clone(), &mut impls); + build_impl(cx, did, attrs, &mut impls); } impls diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 59297df8e48..ad9d54c345c 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -375,18 +375,18 @@ impl<'tcx> Clean<Option<Vec<GenericBound>>> for InternalSubsts<'tcx> { impl Clean<Lifetime> for hir::Lifetime { fn clean(&self, cx: &DocContext<'_>) -> Lifetime { - if self.hir_id != hir::DUMMY_HIR_ID { - let def = cx.tcx.named_region(self.hir_id); - match def { - Some(rl::Region::EarlyBound(_, node_id, _)) - | Some(rl::Region::LateBound(_, node_id, _)) - | Some(rl::Region::Free(_, node_id)) => { - if let Some(lt) = cx.lt_substs.borrow().get(&node_id).cloned() { - return lt; - } + let def = cx.tcx.named_region(self.hir_id); + match def { + Some( + rl::Region::EarlyBound(_, node_id, _) + | rl::Region::LateBound(_, node_id, _) + | rl::Region::Free(_, node_id), + ) => { + if let Some(lt) = cx.lt_substs.borrow().get(&node_id).cloned() { + return lt; } - _ => {} } + _ => {} } Lifetime(self.name.ident().to_string()) } @@ -1174,14 +1174,14 @@ impl Clean<Item> for ty::AssocItem { }; AssocConstItem(ty.clean(cx), default) } - ty::AssocKind::Method => { + ty::AssocKind::Fn => { let generics = (cx.tcx.generics_of(self.def_id), cx.tcx.explicit_predicates_of(self.def_id)) .clean(cx); let sig = cx.tcx.fn_sig(self.def_id); let mut decl = (self.def_id, sig).clean(cx); - if self.method_has_self_argument { + if self.fn_has_self_parameter { let self_ty = match self.container { ty::ImplContainer(def_id) => cx.tcx.type_of(def_id), ty::TraitContainer(_) => cx.tcx.types.self_param, diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 9e96015d306..24817170e36 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -208,10 +208,10 @@ pub fn get_real_types( if !adds.is_empty() { res.extend(adds); } else if !ty.is_full_generic() { - if let Some(did) = ty.def_id() { - if let Some(kind) = cx.tcx.def_kind(did).clean(cx) { - res.insert((ty, kind)); - } + if let Some(kind) = + ty.def_id().and_then(|did| cx.tcx.def_kind(did).clean(cx)) + { + res.insert((ty, kind)); } } } @@ -226,20 +226,18 @@ pub fn get_real_types( if !adds.is_empty() { res.extend(adds); } else if !ty.is_full_generic() { - if let Some(did) = ty.def_id() { - if let Some(kind) = cx.tcx.def_kind(did).clean(cx) { - res.insert((ty.clone(), kind)); - } + if let Some(kind) = + ty.def_id().and_then(|did| cx.tcx.def_kind(did).clean(cx)) + { + res.insert((ty.clone(), kind)); } } } } } } else { - if let Some(did) = arg.def_id() { - if let Some(kind) = cx.tcx.def_kind(did).clean(cx) { - res.insert((arg.clone(), kind)); - } + if let Some(kind) = arg.def_id().and_then(|did| cx.tcx.def_kind(did).clean(cx)) { + res.insert((arg.clone(), kind)); } if let Some(gens) = arg.generics() { for gen in gens.iter() { @@ -248,10 +246,10 @@ pub fn get_real_types( if !adds.is_empty() { res.extend(adds); } - } else if let Some(did) = gen.def_id() { - if let Some(kind) = cx.tcx.def_kind(did).clean(cx) { - res.insert((gen.clone(), kind)); - } + } else if let Some(kind) = + gen.def_id().and_then(|did| cx.tcx.def_kind(did).clean(cx)) + { + res.insert((gen.clone(), kind)); } } } @@ -277,10 +275,8 @@ pub fn get_all_types( if !args.is_empty() { all_types.extend(args); } else { - if let Some(did) = arg.type_.def_id() { - if let Some(kind) = cx.tcx.def_kind(did).clean(cx) { - all_types.insert((arg.type_.clone(), kind)); - } + if let Some(kind) = arg.type_.def_id().and_then(|did| cx.tcx.def_kind(did).clean(cx)) { + all_types.insert((arg.type_.clone(), kind)); } } } @@ -289,10 +285,10 @@ pub fn get_all_types( FnRetTy::Return(ref return_type) => { let mut ret = get_real_types(generics, &return_type, cx, 0); if ret.is_empty() { - if let Some(did) = return_type.def_id() { - if let Some(kind) = cx.tcx.def_kind(did).clean(cx) { - ret.insert((return_type.clone(), kind)); - } + if let Some(kind) = + return_type.def_id().and_then(|did| cx.tcx.def_kind(did).clean(cx)) + { + ret.insert((return_type.clone(), kind)); } } ret.into_iter().collect() @@ -580,11 +576,7 @@ pub fn print_const_expr(cx: &DocContext<'_>, body: hir::BodyId) -> String { /// Given a type Path, resolve it to a Type using the TyCtxt pub fn resolve_type(cx: &DocContext<'_>, path: Path, id: hir::HirId) -> Type { - if id == hir::DUMMY_HIR_ID { - debug!("resolve_type({:?})", path); - } else { - debug!("resolve_type({:?},{:?})", path, id); - } + debug!("resolve_type({:?},{:?})", path, id); let is_generic = match path.res { Res::PrimTy(p) => return Primitive(PrimitiveType::from(p)), @@ -594,7 +586,7 @@ pub fn resolve_type(cx: &DocContext<'_>, path: Path, id: hir::HirId) -> Type { Res::Def(DefKind::TyParam, _) if path.segments.len() == 1 => { return Generic(format!("{:#}", path.print())); } - Res::SelfTy(..) | Res::Def(DefKind::TyParam, _) | Res::Def(DefKind::AssocTy, _) => true, + Res::SelfTy(..) | Res::Def(DefKind::TyParam | DefKind::AssocTy, _) => true, _ => false, }; let did = register_res(&*cx, path.res); diff --git a/src/librustdoc/docfs.rs b/src/librustdoc/docfs.rs index 9c9a00295c3..7ebb200abfe 100644 --- a/src/librustdoc/docfs.rs +++ b/src/librustdoc/docfs.rs @@ -16,12 +16,12 @@ use std::sync::mpsc::{channel, Receiver, Sender}; use std::sync::Arc; macro_rules! try_err { - ($e:expr, $file:expr) => {{ + ($e:expr, $file:expr) => { match $e { Ok(e) => e, Err(e) => return Err(E::new(e, $file)), } - }}; + }; } pub trait PathError { diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 02f1947c99e..c4bc73770a7 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -235,9 +235,7 @@ impl<'a> Classifier<'a> { // If this '&' or '*' token is followed by a non-whitespace token, assume that it's the // reference or dereference operator or a reference or pointer type, instead of the // bit-and or multiplication operator. - token::BinOp(token::And) | token::BinOp(token::Star) - if self.peek()? != &token::Whitespace => - { + token::BinOp(token::And | token::Star) if self.peek()? != &token::Whitespace => { Class::RefKeyWord } @@ -275,9 +273,7 @@ impl<'a> Classifier<'a> { | token::ModSep | token::LArrow | token::OpenDelim(_) - | token::CloseDelim(token::Brace) - | token::CloseDelim(token::Paren) - | token::CloseDelim(token::NoDelim) => Class::None, + | token::CloseDelim(token::Brace | token::Paren | token::NoDelim) => Class::None, token::Question => Class::QuestionMark, diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 9fe3e35d197..941e3a5fa98 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -850,7 +850,7 @@ pub fn plain_summary_line(md: &str) -> String { Event::Start(Tag::Heading(_)) => (None, 1), Event::Code(code) => (Some(format!("`{}`", code)), 0), Event::Text(ref s) if self.is_in > 0 => (Some(s.as_ref().to_owned()), 0), - Event::End(Tag::Paragraph) | Event::End(Tag::Heading(_)) => (None, -1), + Event::End(Tag::Paragraph | Tag::Heading(_)) => (None, -1), _ => (None, 0), }; if is_in > 0 || (is_in < 0 && self.is_in > 0) { @@ -909,7 +909,7 @@ pub fn markdown_links(md: &str) -> Vec<(String, Option<Range<usize>>)> { debug!("found link: {}", dest); links.push(match dest { CowStr::Borrowed(s) => (s.to_owned(), locate(s)), - s @ CowStr::Boxed(..) | s @ CowStr::Inlined(..) => (s.into_string(), None), + s @ (CowStr::Boxed(..) | CowStr::Inlined(..)) => (s.into_string(), None), }); } } diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index d9f6f7b466a..f3c5c12810b 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -294,10 +294,13 @@ impl DocFolder for Cache { // for where the type was defined. On the other // hand, `paths` always has the right // information if present. - Some(&(ref fqp, ItemType::Trait)) - | Some(&(ref fqp, ItemType::Struct)) - | Some(&(ref fqp, ItemType::Union)) - | Some(&(ref fqp, ItemType::Enum)) => Some(&fqp[..fqp.len() - 1]), + Some(&( + ref fqp, + ItemType::Trait + | ItemType::Struct + | ItemType::Union + | ItemType::Enum, + )) => Some(&fqp[..fqp.len() - 1]), Some(..) => Some(&*self.stack), None => None, }; @@ -697,11 +700,11 @@ fn get_generics(clean_type: &clean::Type) -> Option<Vec<Generic>> { let r = types .iter() .filter_map(|t| { - if let Some(name) = get_index_type_name(t, false) { - Some(Generic { name: name.to_ascii_lowercase(), defid: t.def_id(), idx: None }) - } else { - None - } + get_index_type_name(t, false).map(|name| Generic { + name: name.to_ascii_lowercase(), + defid: t.def_id(), + idx: None, + }) }) .collect::<Vec<_>>(); if r.is_empty() { None } else { Some(r) } diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index d091cc0c096..ab524751723 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -184,6 +184,25 @@ nav.sub { overflow: auto; } +/* Improve the scrollbar display on firefox */ +* { + scrollbar-width: initial; +} +.sidebar { + scrollbar-width: thin; +} + +/* Improve the scrollbar display on webkit-based browsers */ +::-webkit-scrollbar { + width: 12px; +} +.sidebar::-webkit-scrollbar { + width: 8px; +} +::-webkit-scrollbar-track { + -webkit-box-shadow: inset 0; +} + .sidebar .block > ul > li { margin-right: -10px; } diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css index ff32a0fa09e..a2986c7b927 100644 --- a/src/librustdoc/html/static/themes/dark.css +++ b/src/librustdoc/html/static/themes/dark.css @@ -32,6 +32,28 @@ pre { background-color: #505050; } +/* Improve the scrollbar display on firefox */ +* { + scrollbar-color: rgb(64, 65, 67) #717171; +} +.sidebar { + scrollbar-color: rgba(32,34,37,.6) transparent; +} + +/* Improve the scrollbar display on webkit-based browsers */ +::-webkit-scrollbar-track { + background-color: #717171; +} +::-webkit-scrollbar-thumb { + background-color: rgba(32, 34, 37, .6); +} +.sidebar::-webkit-scrollbar-track { + background-color: #717171; +} +.sidebar::-webkit-scrollbar-thumb { + background-color: rgba(32, 34, 37, .6); +} + .sidebar .current { background-color: #333; } diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css index 2b2819f7126..be173d8eb46 100644 --- a/src/librustdoc/html/static/themes/light.css +++ b/src/librustdoc/html/static/themes/light.css @@ -34,6 +34,29 @@ pre { background-color: #F1F1F1; } +/* Improve the scrollbar display on firefox */ +* { + scrollbar-color: rgba(36, 37, 39, 0.6) #e6e6e6; +} + +.sidebar { + scrollbar-color: rgba(36, 37, 39, 0.6) #d9d9d9; +} + +/* Improve the scrollbar display on webkit-based browsers */ +::-webkit-scrollbar-track { + background-color: #ecebeb; +} +::-webkit-scrollbar-thumb { + background-color: rgba(36, 37, 39, 0.6); +} +.sidebar::-webkit-scrollbar-track { + background-color: #dcdcdc; +} +.sidebar::-webkit-scrollbar-thumb { + background-color: rgba(36, 37, 39, 0.6); +} + .sidebar .current { background-color: #fff; } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index b0d5a8e58e1..5fb7b7bf959 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -7,6 +7,7 @@ #![feature(box_syntax)] #![feature(in_band_lifetimes)] #![feature(nll)] +#![feature(or_patterns)] #![feature(test)] #![feature(vec_remove_item)] #![feature(ptr_offset_from)] diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index a6b24d49a83..8bfd42ac56a 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -149,7 +149,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { // In case this is a trait item, skip the // early return and try looking for the trait. let value = match res { - Res::Def(DefKind::AssocFn, _) | Res::Def(DefKind::AssocConst, _) => true, + Res::Def(DefKind::AssocFn | DefKind::AssocConst, _) => true, Res::Def(DefKind::AssocTy, _) => false, Res::Def(DefKind::Variant, _) => { return handle_variant(cx, res, extra_fragment); @@ -209,7 +209,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { .filter_by_name_unhygienic(item_name) .next() .and_then(|item| match item.kind { - ty::AssocKind::Method => Some("method"), + ty::AssocKind::Fn => Some("method"), _ => None, }) .map(|out| (prim, Some(format!("{}#{}.{}", path, out, item_name)))) @@ -226,10 +226,10 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { } let ty_res = ty_res.map_id(|_| panic!("unexpected node_id")); match ty_res { - Res::Def(DefKind::Struct, did) - | Res::Def(DefKind::Union, did) - | Res::Def(DefKind::Enum, did) - | Res::Def(DefKind::TyAlias, did) => { + Res::Def( + DefKind::Struct | DefKind::Union | DefKind::Enum | DefKind::TyAlias, + did, + ) => { let item = cx .tcx .inherent_impls(did) @@ -238,12 +238,12 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { .find(|item| item.ident.name == item_name); if let Some(item) = item { let out = match item.kind { - ty::AssocKind::Method if ns == ValueNS => "method", + ty::AssocKind::Fn if ns == ValueNS => "method", ty::AssocKind::Const if ns == ValueNS => "associatedconstant", _ => return self.variant_field(path_str, current_item, module_id), }; if extra_fragment.is_some() { - Err(ErrorKind::AnchorFailure(if item.kind == ty::AssocKind::Method { + Err(ErrorKind::AnchorFailure(if item.kind == ty::AssocKind::Fn { "methods cannot be followed by anchors" } else { "associated constants cannot be followed by anchors" @@ -298,14 +298,15 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { .map(|item| cx.tcx.associated_item(*item)) .find(|item| item.ident.name == item_name); if let Some(item) = item { - let kind = match item.kind { - ty::AssocKind::Const if ns == ValueNS => "associatedconstant", - ty::AssocKind::Type if ns == TypeNS => "associatedtype", - ty::AssocKind::Method if ns == ValueNS => { - if item.defaultness.has_value() { "method" } else { "tymethod" } - } - _ => return self.variant_field(path_str, current_item, module_id), - }; + let kind = + match item.kind { + ty::AssocKind::Const if ns == ValueNS => "associatedconstant", + ty::AssocKind::Type if ns == TypeNS => "associatedtype", + ty::AssocKind::Fn if ns == ValueNS => { + if item.defaultness.has_value() { "method" } else { "tymethod" } + } + _ => return self.variant_field(path_str, current_item, module_id), + }; if extra_fragment.is_some() { Err(ErrorKind::AnchorFailure(if item.kind == ty::AssocKind::Const { @@ -813,7 +814,7 @@ fn ambiguity_error( for (res, ns) in candidates { let (action, mut suggestion) = match res { - Res::Def(DefKind::AssocFn, _) | Res::Def(DefKind::Fn, _) => { + Res::Def(DefKind::AssocFn | DefKind::Fn, _) => { ("add parentheses", format!("{}()", path_str)) } Res::Def(DefKind::Macro(..), _) => { diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index da0e97f1075..c80967a4b33 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -62,6 +62,8 @@ pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate { lang_items.slice_u8_alloc_impl(), lang_items.const_ptr_impl(), lang_items.mut_ptr_impl(), + lang_items.const_slice_ptr_impl(), + lang_items.mut_slice_ptr_impl(), ]; for def_id in primitive_impls.iter().filter_map(|&def_id| def_id) { diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 7841d5eef58..afc1501d7b6 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -263,7 +263,12 @@ fn run_test( if no_run && !compile_fail { compiler.arg("--emit=metadata"); } - compiler.arg("--target").arg(target.to_string()); + compiler.arg("--target").arg(match target { + TargetTriple::TargetTriple(s) => s, + TargetTriple::TargetPath(path) => { + path.to_str().expect("target path must be valid unicode").to_string() + } + }); compiler.arg("-"); compiler.stdin(Stdio::piped()); @@ -312,8 +317,8 @@ fn run_test( if let Some(tool) = runtool { cmd = Command::new(tool); - cmd.arg(output_file); cmd.args(runtool_args); + cmd.arg(output_file); } else { cmd = Command::new(output_file); } @@ -678,7 +683,7 @@ impl Tester for Collector { let name = self.generate_name(line, &filename); let cratename = self.cratename.to_string(); let opts = self.opts.clone(); - let edition = config.edition.unwrap_or(self.options.edition.clone()); + let edition = config.edition.unwrap_or(self.options.edition); let options = self.options.clone(); let runtool = self.options.runtool.clone(); let runtool_args = self.options.runtool_args.clone(); diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index bf4c4487927..b7a3b13cf04 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -309,14 +309,15 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { let attrs = clean::inline::load_attrs(self.cx, res_did); let self_is_hidden = attrs.lists(sym::doc).has_word(sym::hidden); match res { - Res::Def(DefKind::Trait, did) - | Res::Def(DefKind::Struct, did) - | Res::Def(DefKind::Union, did) - | Res::Def(DefKind::Enum, did) - | Res::Def(DefKind::ForeignTy, did) - | Res::Def(DefKind::TyAlias, did) - if !self_is_hidden => - { + Res::Def( + DefKind::Trait + | DefKind::Struct + | DefKind::Union + | DefKind::Enum + | DefKind::ForeignTy + | DefKind::TyAlias, + did, + ) if !self_is_hidden => { self.cx.renderinfo.get_mut().access_levels.map.insert(did, AccessLevel::Public); } Res::Def(DefKind::Mod, did) => { diff --git a/src/libstd/build.rs b/src/libstd/build.rs index 8db7bc12cd3..743a1778fbd 100644 --- a/src/libstd/build.rs +++ b/src/libstd/build.rs @@ -25,6 +25,14 @@ fn main() { println!("cargo:rustc-link-lib=posix4"); println!("cargo:rustc-link-lib=pthread"); println!("cargo:rustc-link-lib=resolv"); + } else if target.contains("illumos") { + println!("cargo:rustc-link-lib=socket"); + println!("cargo:rustc-link-lib=posix4"); + println!("cargo:rustc-link-lib=pthread"); + println!("cargo:rustc-link-lib=resolv"); + println!("cargo:rustc-link-lib=nsl"); + // Use libumem for the (malloc-compatible) allocator + println!("cargo:rustc-link-lib=umem"); } else if target.contains("apple-darwin") { println!("cargo:rustc-link-lib=System"); diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs index e8b9e9cb1f2..cc6663bebd3 100644 --- a/src/libstd/collections/mod.rs +++ b/src/libstd/collections/mod.rs @@ -110,10 +110,10 @@ //! //! For Sets, all operations have the cost of the equivalent Map operation. //! -//! | | get | insert | remove | predecessor | append | -//! |--------------|-----------|----------|----------|-------------|--------| -//! | [`HashMap`] | O(1)~ | O(1)~* | O(1)~ | N/A | N/A | -//! | [`BTreeMap`] | O(log n) | O(log n) | O(log n) | O(log n) | O(n+m) | +//! | | get | insert | remove | predecessor | append | +//! |--------------|-----------|-----------|-----------|-------------|--------| +//! | [`HashMap`] | O(1)~ | O(1)~* | O(1)~ | N/A | N/A | +//! | [`BTreeMap`] | O(log(n)) | O(log(n)) | O(log(n)) | O(log(n)) | O(n+m) | //! //! # Correct and Efficient Usage of Collections //! diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs index ff222fc8539..5cf9cb73d4b 100644 --- a/src/libstd/f64.rs +++ b/src/libstd/f64.rs @@ -919,7 +919,7 @@ impl f64 { // because of their non-standard behavior (e.g., log(-n) returns -Inf instead // of expected NaN). fn log_wrapper<F: Fn(f64) -> f64>(self, log_fn: F) -> f64 { - if !cfg!(target_os = "solaris") { + if !cfg!(any(target_os = "solaris", target_os = "illumos")) { log_fn(self) } else { if self.is_finite() { diff --git a/src/libstd/ffi/mod.rs b/src/libstd/ffi/mod.rs index 72f7367c9dc..5aca7b7476a 100644 --- a/src/libstd/ffi/mod.rs +++ b/src/libstd/ffi/mod.rs @@ -43,8 +43,8 @@ //! terminator, so the buffer length is really `len+1` characters. //! Rust strings don't have a nul terminator; their length is always //! stored and does not need to be calculated. While in Rust -//! accessing a string's length is a O(1) operation (because the -//! length is stored); in C it is an O(length) operation because the +//! accessing a string's length is a `O(1)` operation (because the +//! length is stored); in C it is an `O(length)` operation because the //! length needs to be computed by scanning the string for the nul //! terminator. //! diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index a9a519f0a3a..59d845c619b 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -285,6 +285,7 @@ #![feature(never_type)] #![feature(nll)] #![feature(optin_builtin_traits)] +#![feature(or_patterns)] #![feature(panic_info_message)] #![feature(panic_internals)] #![feature(panic_unwind)] diff --git a/src/libstd/os/illumos/fs.rs b/src/libstd/os/illumos/fs.rs new file mode 100644 index 00000000000..2abbf1fa9fa --- /dev/null +++ b/src/libstd/os/illumos/fs.rs @@ -0,0 +1,118 @@ +#![stable(feature = "metadata_ext", since = "1.1.0")] + +use libc; + +use crate::fs::Metadata; +use crate::sys_common::AsInner; + +#[allow(deprecated)] +use crate::os::illumos::raw; + +/// OS-specific extensions to [`fs::Metadata`]. +/// +/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html +#[stable(feature = "metadata_ext", since = "1.1.0")] +pub trait MetadataExt { + /// Gain a reference to the underlying `stat` structure which contains + /// the raw information returned by the OS. + /// + /// The contents of the returned `stat` are **not** consistent across + /// Unix platforms. The `os::unix::fs::MetadataExt` trait contains the + /// cross-Unix abstractions contained within the raw stat. + #[stable(feature = "metadata_ext", since = "1.1.0")] + #[rustc_deprecated( + since = "1.8.0", + reason = "deprecated in favor of the accessor methods of this trait" + )] + #[allow(deprecated)] + fn as_raw_stat(&self) -> &raw::stat; + + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_dev(&self) -> u64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_ino(&self) -> u64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_mode(&self) -> u32; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_nlink(&self) -> u64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_uid(&self) -> u32; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_gid(&self) -> u32; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_rdev(&self) -> u64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_size(&self) -> u64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_atime(&self) -> i64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_atime_nsec(&self) -> i64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_mtime(&self) -> i64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_mtime_nsec(&self) -> i64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_ctime(&self) -> i64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_ctime_nsec(&self) -> i64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_blksize(&self) -> u64; + #[stable(feature = "metadata_ext2", since = "1.8.0")] + fn st_blocks(&self) -> u64; +} + +#[stable(feature = "metadata_ext", since = "1.1.0")] +impl MetadataExt for Metadata { + #[allow(deprecated)] + fn as_raw_stat(&self) -> &raw::stat { + unsafe { &*(self.as_inner().as_inner() as *const libc::stat as *const raw::stat) } + } + fn st_dev(&self) -> u64 { + self.as_inner().as_inner().st_dev as u64 + } + fn st_ino(&self) -> u64 { + self.as_inner().as_inner().st_ino as u64 + } + fn st_mode(&self) -> u32 { + self.as_inner().as_inner().st_mode as u32 + } + fn st_nlink(&self) -> u64 { + self.as_inner().as_inner().st_nlink as u64 + } + fn st_uid(&self) -> u32 { + self.as_inner().as_inner().st_uid as u32 + } + fn st_gid(&self) -> u32 { + self.as_inner().as_inner().st_gid as u32 + } + fn st_rdev(&self) -> u64 { + self.as_inner().as_inner().st_rdev as u64 + } + fn st_size(&self) -> u64 { + self.as_inner().as_inner().st_size as u64 + } + fn st_atime(&self) -> i64 { + self.as_inner().as_inner().st_atime as i64 + } + fn st_atime_nsec(&self) -> i64 { + self.as_inner().as_inner().st_atime_nsec as i64 + } + fn st_mtime(&self) -> i64 { + self.as_inner().as_inner().st_mtime as i64 + } + fn st_mtime_nsec(&self) -> i64 { + self.as_inner().as_inner().st_mtime_nsec as i64 + } + fn st_ctime(&self) -> i64 { + self.as_inner().as_inner().st_ctime as i64 + } + fn st_ctime_nsec(&self) -> i64 { + self.as_inner().as_inner().st_ctime_nsec as i64 + } + fn st_blksize(&self) -> u64 { + self.as_inner().as_inner().st_blksize as u64 + } + fn st_blocks(&self) -> u64 { + self.as_inner().as_inner().st_blocks as u64 + } +} diff --git a/src/libstd/os/illumos/mod.rs b/src/libstd/os/illumos/mod.rs new file mode 100644 index 00000000000..e61926f8935 --- /dev/null +++ b/src/libstd/os/illumos/mod.rs @@ -0,0 +1,6 @@ +//! illumos-specific definitions + +#![stable(feature = "raw_ext", since = "1.1.0")] + +pub mod fs; +pub mod raw; diff --git a/src/libstd/os/illumos/raw.rs b/src/libstd/os/illumos/raw.rs new file mode 100644 index 00000000000..88c832ae7c7 --- /dev/null +++ b/src/libstd/os/illumos/raw.rs @@ -0,0 +1,74 @@ +//! illumos-specific raw type definitions + +#![stable(feature = "raw_ext", since = "1.1.0")] +#![rustc_deprecated( + since = "1.8.0", + reason = "these type aliases are no longer supported by the standard library, the `libc` \ + crate on crates.io should be used instead for the correct definitions" +)] +#![allow(deprecated)] + +use crate::os::raw::c_long; +use crate::os::unix::raw::{gid_t, uid_t}; + +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type blkcnt_t = u64; +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type blksize_t = u64; +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type dev_t = u64; +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type fflags_t = u32; +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type ino_t = u64; +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type mode_t = u32; +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type nlink_t = u64; +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type off_t = u64; +#[stable(feature = "raw_ext", since = "1.1.0")] +pub type time_t = i64; + +#[stable(feature = "pthread_t", since = "1.8.0")] +pub type pthread_t = u32; + +#[repr(C)] +#[derive(Clone)] +#[stable(feature = "raw_ext", since = "1.1.0")] +pub struct stat { + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_dev: dev_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_ino: ino_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_mode: mode_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_nlink: nlink_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_uid: uid_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_gid: gid_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_rdev: dev_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_size: off_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_atime: time_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_atime_nsec: c_long, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_mtime: time_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_mtime_nsec: c_long, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_ctime: time_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_ctime_nsec: c_long, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_blksize: blksize_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub st_blocks: blkcnt_t, + #[stable(feature = "raw_ext", since = "1.1.0")] + pub __unused: [u8; 16], +} diff --git a/src/libstd/os/mod.rs b/src/libstd/os/mod.rs index 0fa4a1d2353..fd6ee088e96 100644 --- a/src/libstd/os/mod.rs +++ b/src/libstd/os/mod.rs @@ -52,6 +52,8 @@ pub mod freebsd; pub mod fuchsia; #[cfg(target_os = "haiku")] pub mod haiku; +#[cfg(target_os = "illumos")] +pub mod illumos; #[cfg(target_os = "ios")] pub mod ios; #[cfg(target_os = "macos")] diff --git a/src/libstd/sync/mpsc/oneshot.rs b/src/libstd/sync/mpsc/oneshot.rs index 5b41525e06a..75f5621fa12 100644 --- a/src/libstd/sync/mpsc/oneshot.rs +++ b/src/libstd/sync/mpsc/oneshot.rs @@ -260,7 +260,7 @@ impl<T> Packet<T> { let state = match self.state.load(Ordering::SeqCst) { // Each of these states means that no further activity will happen // with regard to abortion selection - s @ EMPTY | s @ DATA | s @ DISCONNECTED => s, + s @ (EMPTY | DATA | DISCONNECTED) => s, // If we've got a blocked thread, then use an atomic to gain ownership // of it (may fail) diff --git a/src/libstd/sync/mpsc/stream.rs b/src/libstd/sync/mpsc/stream.rs index f33493ee0c9..26b4faebd86 100644 --- a/src/libstd/sync/mpsc/stream.rs +++ b/src/libstd/sync/mpsc/stream.rs @@ -205,7 +205,7 @@ impl<T> Packet<T> { // Messages which actually popped from the queue shouldn't count as // a steal, so offset the decrement here (we already have our // "steal" factored into the channel count above). - data @ Ok(..) | data @ Err(Upgraded(..)) => unsafe { + data @ (Ok(..) | Err(Upgraded(..))) => unsafe { *self.queue.consumer_addition().steals.get() -= 1; data }, diff --git a/src/libstd/sys/unix/alloc.rs b/src/libstd/sys/unix/alloc.rs index 77417e41331..8e193935460 100644 --- a/src/libstd/sys/unix/alloc.rs +++ b/src/libstd/sys/unix/alloc.rs @@ -52,7 +52,12 @@ unsafe impl GlobalAlloc for System { } } -#[cfg(any(target_os = "android", target_os = "redox", target_os = "solaris"))] +#[cfg(any( + target_os = "android", + target_os = "illumos", + target_os = "redox", + target_os = "solaris" +))] #[inline] unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { // On android we currently target API level 9 which unfortunately @@ -75,7 +80,12 @@ unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { libc::memalign(layout.align(), layout.size()) as *mut u8 } -#[cfg(not(any(target_os = "android", target_os = "redox", target_os = "solaris")))] +#[cfg(not(any( + target_os = "android", + target_os = "illumos", + target_os = "redox", + target_os = "solaris" +)))] #[inline] unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { let mut out = ptr::null_mut(); diff --git a/src/libstd/sys/unix/args.rs b/src/libstd/sys/unix/args.rs index 09acc3f6e3e..4c3e8542d57 100644 --- a/src/libstd/sys/unix/args.rs +++ b/src/libstd/sys/unix/args.rs @@ -65,6 +65,7 @@ impl DoubleEndedIterator for Args { target_os = "netbsd", target_os = "openbsd", target_os = "solaris", + target_os = "illumos", target_os = "emscripten", target_os = "haiku", target_os = "l4re", diff --git a/src/libstd/sys/unix/env.rs b/src/libstd/sys/unix/env.rs index 984bcfa4509..7f5e9b04dba 100644 --- a/src/libstd/sys/unix/env.rs +++ b/src/libstd/sys/unix/env.rs @@ -97,6 +97,17 @@ pub mod os { pub const EXE_EXTENSION: &str = ""; } +#[cfg(target_os = "illumos")] +pub mod os { + pub const FAMILY: &str = "unix"; + pub const OS: &str = "illumos"; + pub const DLL_PREFIX: &str = "lib"; + pub const DLL_SUFFIX: &str = ".so"; + pub const DLL_EXTENSION: &str = "so"; + pub const EXE_SUFFIX: &str = ""; + pub const EXE_EXTENSION: &str = ""; +} + #[cfg(target_os = "haiku")] pub mod os { pub const FAMILY: &str = "unix"; diff --git a/src/libstd/sys/unix/fd.rs b/src/libstd/sys/unix/fd.rs index 8a99836912a..1bba56e334a 100644 --- a/src/libstd/sys/unix/fd.rs +++ b/src/libstd/sys/unix/fd.rs @@ -153,6 +153,7 @@ impl FileDesc { #[cfg(not(any( target_env = "newlib", target_os = "solaris", + target_os = "illumos", target_os = "emscripten", target_os = "fuchsia", target_os = "l4re", @@ -169,6 +170,7 @@ impl FileDesc { #[cfg(any( target_env = "newlib", target_os = "solaris", + target_os = "illumos", target_os = "emscripten", target_os = "fuchsia", target_os = "l4re", diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs index ab2a871b92d..a233aa47dff 100644 --- a/src/libstd/sys/unix/fs.rs +++ b/src/libstd/sys/unix/fs.rs @@ -22,6 +22,7 @@ use libc::fstatat64; target_os = "linux", target_os = "emscripten", target_os = "solaris", + target_os = "illumos", target_os = "l4re", target_os = "fuchsia", target_os = "redox" @@ -200,7 +201,12 @@ pub struct DirEntry { // on Solaris and Fuchsia because a) it uses a zero-length // array to store the name, b) its lifetime between readdir // calls is not guaranteed. - #[cfg(any(target_os = "solaris", target_os = "fuchsia", target_os = "redox"))] + #[cfg(any( + target_os = "solaris", + target_os = "illumos", + target_os = "fuchsia", + target_os = "redox" + ))] name: Box<[u8]>, } @@ -403,7 +409,12 @@ impl fmt::Debug for ReadDir { impl Iterator for ReadDir { type Item = io::Result<DirEntry>; - #[cfg(any(target_os = "solaris", target_os = "fuchsia", target_os = "redox"))] + #[cfg(any( + target_os = "solaris", + target_os = "fuchsia", + target_os = "redox", + target_os = "illumos" + ))] fn next(&mut self) -> Option<io::Result<DirEntry>> { use crate::slice; @@ -441,7 +452,12 @@ impl Iterator for ReadDir { } } - #[cfg(not(any(target_os = "solaris", target_os = "fuchsia", target_os = "redox")))] + #[cfg(not(any( + target_os = "solaris", + target_os = "fuchsia", + target_os = "redox", + target_os = "illumos" + )))] fn next(&mut self) -> Option<io::Result<DirEntry>> { if self.end_of_stream { return None; @@ -514,12 +530,12 @@ impl DirEntry { lstat(&self.path()) } - #[cfg(any(target_os = "solaris", target_os = "haiku"))] + #[cfg(any(target_os = "solaris", target_os = "illumos", target_os = "haiku"))] pub fn file_type(&self) -> io::Result<FileType> { lstat(&self.path()).map(|m| m.file_type()) } - #[cfg(not(any(target_os = "solaris", target_os = "haiku")))] + #[cfg(not(any(target_os = "solaris", target_os = "illumos", target_os = "haiku")))] pub fn file_type(&self) -> io::Result<FileType> { match self.entry.d_type { libc::DT_CHR => Ok(FileType { mode: libc::S_IFCHR }), @@ -540,6 +556,7 @@ impl DirEntry { target_os = "emscripten", target_os = "android", target_os = "solaris", + target_os = "illumos", target_os = "haiku", target_os = "l4re", target_os = "fuchsia", @@ -586,7 +603,12 @@ impl DirEntry { fn name_bytes(&self) -> &[u8] { unsafe { CStr::from_ptr(self.entry.d_name.as_ptr()).to_bytes() } } - #[cfg(any(target_os = "solaris", target_os = "fuchsia", target_os = "redox"))] + #[cfg(any( + target_os = "solaris", + target_os = "illumos", + target_os = "fuchsia", + target_os = "redox" + ))] fn name_bytes(&self) -> &[u8] { &*self.name } diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index fbcb006ecdf..0154609d939 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -17,6 +17,8 @@ pub use crate::os::freebsd as platform; pub use crate::os::fuchsia as platform; #[cfg(all(not(doc), target_os = "haiku"))] pub use crate::os::haiku as platform; +#[cfg(all(not(doc), target_os = "illumos"))] +pub use crate::os::illumos as platform; #[cfg(all(not(doc), target_os = "ios"))] pub use crate::os::ios as platform; #[cfg(all(not(doc), target_os = "l4re"))] diff --git a/src/libstd/sys/unix/net.rs b/src/libstd/sys/unix/net.rs index b37675e0a0a..d18c22b0573 100644 --- a/src/libstd/sys/unix/net.rs +++ b/src/libstd/sys/unix/net.rs @@ -322,11 +322,19 @@ impl Socket { Ok(raw != 0) } + #[cfg(not(any(target_os = "solaris", target_os = "illumos")))] pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { let mut nonblocking = nonblocking as libc::c_int; cvt(unsafe { libc::ioctl(*self.as_inner(), libc::FIONBIO, &mut nonblocking) }).map(drop) } + #[cfg(any(target_os = "solaris", target_os = "illumos"))] + pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { + // FIONBIO is inadequate for sockets on illumos/Solaris, so use the + // fcntl(F_[GS]ETFL)-based method provided by FileDesc instead. + self.0.set_nonblocking(nonblocking) + } + pub fn take_error(&self) -> io::Result<Option<io::Error>> { let raw: c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_ERROR)?; if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) } diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index 91f7d1524cc..a9cd5094997 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -54,7 +54,7 @@ extern "C" { ), link_name = "__errno" )] - #[cfg_attr(target_os = "solaris", link_name = "___errno")] + #[cfg_attr(any(target_os = "solaris", target_os = "illumos"), link_name = "___errno")] #[cfg_attr( any(target_os = "macos", target_os = "ios", target_os = "freebsd"), link_name = "__error" @@ -357,7 +357,7 @@ pub fn current_exe() -> io::Result<PathBuf> { } } -#[cfg(any(target_os = "solaris"))] +#[cfg(any(target_os = "solaris", target_os = "illumos"))] pub fn current_exe() -> io::Result<PathBuf> { extern "C" { fn getexecname() -> *const c_char; diff --git a/src/libstd/sys/unix/stack_overflow.rs b/src/libstd/sys/unix/stack_overflow.rs index 2626ca37cf8..5e103578350 100644 --- a/src/libstd/sys/unix/stack_overflow.rs +++ b/src/libstd/sys/unix/stack_overflow.rs @@ -33,6 +33,7 @@ impl Drop for Handler { target_os = "dragonfly", target_os = "freebsd", target_os = "solaris", + target_os = "illumos", all(target_os = "netbsd", not(target_vendor = "rumprun")), target_os = "openbsd" ))] @@ -162,7 +163,8 @@ mod imp { target_os = "freebsd", target_os = "netbsd", target_os = "openbsd", - target_os = "solaris" + target_os = "solaris", + target_os = "illumos" ))] unsafe fn get_stack() -> libc::stack_t { libc::stack_t { ss_sp: get_stackp(), ss_flags: 0, ss_size: SIGSTKSZ } @@ -214,6 +216,7 @@ mod imp { target_os = "dragonfly", target_os = "freebsd", target_os = "solaris", + target_os = "illumos", all(target_os = "netbsd", not(target_vendor = "rumprun")), target_os = "openbsd" )))] diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index aab5a92a7ad..895ea48e2b4 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -132,7 +132,7 @@ impl Thread { } } - #[cfg(target_os = "solaris")] + #[cfg(any(target_os = "solaris", target_os = "illumos"))] pub fn set_name(name: &CStr) { weak! { fn pthread_setname_np( @@ -155,7 +155,7 @@ impl Thread { target_os = "redox" ))] pub fn set_name(_name: &CStr) { - // Newlib, Illumos, Haiku, and Emscripten have no way to set a thread name. + // Newlib, Haiku, and Emscripten have no way to set a thread name. } #[cfg(target_os = "fuchsia")] pub fn set_name(_name: &CStr) { diff --git a/src/libstd/sys/windows/ext/fs.rs b/src/libstd/sys/windows/ext/fs.rs index d508a333484..f85120d170f 100644 --- a/src/libstd/sys/windows/ext/fs.rs +++ b/src/libstd/sys/windows/ext/fs.rs @@ -224,7 +224,7 @@ pub trait OpenOptionsExt { /// opening a named pipe, to control to which degree a server process can /// act on behalf of a client process (security impersonation level). /// - /// When `security_qos_flags` is not set a malicious program can gain the + /// When `security_qos_flags` is not set, a malicious program can gain the /// elevated privileges of a privileged Rust process when it allows opening /// user-specified paths, by tricking it into opening a named pipe. So /// arguably `security_qos_flags` should also be set when opening arbitrary diff --git a/src/libstd/sys_common/net.rs b/src/libstd/sys_common/net.rs index 135e8308afa..cdd3d2edf1f 100644 --- a/src/libstd/sys_common/net.rs +++ b/src/libstd/sys_common/net.rs @@ -17,7 +17,7 @@ cfg_if::cfg_if! { if #[cfg(any( target_os = "dragonfly", target_os = "freebsd", target_os = "ios", target_os = "macos", - target_os = "openbsd", target_os = "netbsd", + target_os = "openbsd", target_os = "netbsd", target_os = "illumos", target_os = "solaris", target_os = "haiku", target_os = "l4re"))] { use crate::sys::net::netc::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP; use crate::sys::net::netc::IPV6_LEAVE_GROUP as IPV6_DROP_MEMBERSHIP; @@ -43,7 +43,7 @@ cfg_if::cfg_if! { if #[cfg(any( target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd", - target_os = "solaris"))] { + target_os = "solaris", target_os = "illumos"))] { use libc::c_uchar; type IpV4MultiCastType = c_uchar; } else { diff --git a/src/libtest/helpers/concurrency.rs b/src/libtest/helpers/concurrency.rs index 6b0c8a8af32..e8f3820558a 100644 --- a/src/libtest/helpers/concurrency.rs +++ b/src/libtest/helpers/concurrency.rs @@ -77,6 +77,7 @@ pub fn get_concurrency() -> usize { target_os = "linux", target_os = "macos", target_os = "solaris", + target_os = "illumos", ))] fn num_cpus() -> usize { unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as usize } diff --git a/src/libunwind/build.rs b/src/libunwind/build.rs index 0628e5d2fc0..c8d2419ab45 100644 --- a/src/libunwind/build.rs +++ b/src/libunwind/build.rs @@ -30,6 +30,8 @@ fn main() { } } else if target.contains("solaris") { println!("cargo:rustc-link-lib=gcc_s"); + } else if target.contains("illumos") { + println!("cargo:rustc-link-lib=gcc_s"); } else if target.contains("dragonfly") { println!("cargo:rustc-link-lib=gcc_pic"); } else if target.contains("pc-windows-gnu") { diff --git a/src/llvm-project b/src/llvm-project -Subproject 027e428197f3702599cfbb632883768175f4917 +Subproject 9f9da27fbdb0ba7d887f8d2521e082f12b00941 diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 9e8614e3b6d..b221c17b422 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -33,10 +33,8 @@ #include "llvm/Transforms/Instrumentation/AddressSanitizer.h" #include "llvm/Support/TimeProfiler.h" #endif -#if LLVM_VERSION_GE(8, 0) #include "llvm/Transforms/Instrumentation/ThreadSanitizer.h" #include "llvm/Transforms/Instrumentation/MemorySanitizer.h" -#endif #if LLVM_VERSION_GE(9, 0) #include "llvm/Transforms/Utils/CanonicalizeAliases.h" #endif @@ -138,19 +136,13 @@ extern "C" LLVMPassRef LLVMRustCreateMemorySanitizerPass(int TrackOrigins, bool return wrap(createMemorySanitizerLegacyPassPass( MemorySanitizerOptions{TrackOrigins, Recover, CompileKernel})); -#elif LLVM_VERSION_GE(8, 0) - return wrap(createMemorySanitizerLegacyPassPass(TrackOrigins, Recover)); #else - return wrap(createMemorySanitizerPass(TrackOrigins, Recover)); + return wrap(createMemorySanitizerLegacyPassPass(TrackOrigins, Recover)); #endif } extern "C" LLVMPassRef LLVMRustCreateThreadSanitizerPass() { -#if LLVM_VERSION_GE(8, 0) return wrap(createThreadSanitizerLegacyPassPass()); -#else - return wrap(createThreadSanitizerPass()); -#endif } extern "C" LLVMRustPassKind LLVMRustPassKind(LLVMPassRef RustPass) { @@ -1236,15 +1228,11 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules, auto deadIsPrevailing = [&](GlobalValue::GUID G) { return PrevailingType::Unknown; }; -#if LLVM_VERSION_GE(8, 0) // We don't have a complete picture in our use of ThinLTO, just our immediate // crate, so we need `ImportEnabled = false` to limit internalization. // Otherwise, we sometimes lose `static` values -- see #60184. computeDeadSymbolsWithConstProp(Ret->Index, Ret->GUIDPreservedSymbols, deadIsPrevailing, /* ImportEnabled = */ false); -#else - computeDeadSymbols(Ret->Index, Ret->GUIDPreservedSymbols, deadIsPrevailing); -#endif ComputeCrossModuleImport( Ret->Index, Ret->ModuleToDefinedGVSummaries, @@ -1277,10 +1265,8 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules, #if LLVM_VERSION_GE(9, 0) thinLTOResolvePrevailingInIndex(Ret->Index, isPrevailing, recordNewLinkage, Ret->GUIDPreservedSymbols); -#elif LLVM_VERSION_GE(8, 0) - thinLTOResolvePrevailingInIndex(Ret->Index, isPrevailing, recordNewLinkage); #else - thinLTOResolveWeakForLinkerInIndex(Ret->Index, isPrevailing, recordNewLinkage); + thinLTOResolvePrevailingInIndex(Ret->Index, isPrevailing, recordNewLinkage); #endif // Here we calculate an `ExportedGUIDs` set for use in the `isExported` @@ -1346,11 +1332,7 @@ extern "C" bool LLVMRustPrepareThinLTOResolveWeak(const LLVMRustThinLTOData *Data, LLVMModuleRef M) { Module &Mod = *unwrap(M); const auto &DefinedGlobals = Data->ModuleToDefinedGVSummaries.lookup(Mod.getModuleIdentifier()); -#if LLVM_VERSION_GE(8, 0) thinLTOResolvePrevailingInModule(Mod, DefinedGlobals); -#else - thinLTOResolveWeakForLinkerModule(Mod, DefinedGlobals); -#endif return true; } diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 21094b32520..28efc8bf5dd 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -586,7 +586,6 @@ inline LLVMRustDISPFlags virtuality(LLVMRustDISPFlags F) { return static_cast<LLVMRustDISPFlags>(static_cast<uint32_t>(F) & 0x3); } -#if LLVM_VERSION_GE(8, 0) static DISubprogram::DISPFlags fromRust(LLVMRustDISPFlags SPFlags) { DISubprogram::DISPFlags Result = DISubprogram::DISPFlags::SPFlagZero; @@ -619,7 +618,6 @@ static DISubprogram::DISPFlags fromRust(LLVMRustDISPFlags SPFlags) { return Result; } -#endif enum class LLVMRustDebugEmissionKind { NoDebug, @@ -734,7 +732,6 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFunction( LLVMMetadataRef Decl) { DITemplateParameterArray TParams = DITemplateParameterArray(unwrap<MDTuple>(TParam)); -#if LLVM_VERSION_GE(8, 0) DISubprogram::DISPFlags llvmSPFlags = fromRust(SPFlags); DINode::DIFlags llvmFlags = fromRust(Flags); #if LLVM_VERSION_LT(9, 0) @@ -748,22 +745,6 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFunction( unwrapDI<DIFile>(File), LineNo, unwrapDI<DISubroutineType>(Ty), ScopeLine, llvmFlags, llvmSPFlags, TParams, unwrapDIPtr<DISubprogram>(Decl)); -#else - bool IsLocalToUnit = isSet(SPFlags & LLVMRustDISPFlags::SPFlagLocalToUnit); - bool IsDefinition = isSet(SPFlags & LLVMRustDISPFlags::SPFlagDefinition); - bool IsOptimized = isSet(SPFlags & LLVMRustDISPFlags::SPFlagOptimized); - DINode::DIFlags llvmFlags = fromRust(Flags); - if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagMainSubprogram)) - llvmFlags |= DINode::DIFlags::FlagMainSubprogram; - DISubprogram *Sub = Builder->createFunction( - unwrapDI<DIScope>(Scope), - StringRef(Name, NameLen), - StringRef(LinkageName, LinkageNameLen), - unwrapDI<DIFile>(File), LineNo, - unwrapDI<DISubroutineType>(Ty), IsLocalToUnit, IsDefinition, - ScopeLine, llvmFlags, IsOptimized, TParams, - unwrapDIPtr<DISubprogram>(Decl)); -#endif unwrap<Function>(Fn)->setSubprogram(Sub); return wrap(Sub); } @@ -884,9 +865,7 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticVariable( /* isDefined */ true, #endif InitExpr, unwrapDIPtr<MDNode>(Decl), -#if LLVM_VERSION_GE(8, 0) /* templateParams */ nullptr, -#endif AlignInBits); InitVal->setMetadata("dbg", VarExpr); @@ -1107,11 +1086,7 @@ extern "C" void LLVMRustUnpackOptimizationDiagnostic( if (loc.isValid()) { *Line = loc.getLine(); *Column = loc.getColumn(); -#if LLVM_VERSION_GE(8, 0) FilenameOS << loc.getAbsolutePath(); -#else - FilenameOS << loc.getFilename(); -#endif } RawRustStringOstream MessageOS(MessageOut); diff --git a/src/test/codegen/c-variadic.rs b/src/test/codegen/c-variadic.rs index 971f4e3e12e..29c82686731 100644 --- a/src/test/codegen/c-variadic.rs +++ b/src/test/codegen/c-variadic.rs @@ -16,13 +16,13 @@ extern "C" { #[unwind(aborts)] // FIXME(#58794) pub unsafe extern "C" fn use_foreign_c_variadic_0() { // Ensure that we correctly call foreign C-variadic functions. - // CHECK: invoke void (i32, ...) @foreign_c_variadic_0([[PARAM:i32( signext)?]] 0) + // CHECK: call void (i32, ...) @foreign_c_variadic_0([[PARAM:i32( signext)?]] 0) foreign_c_variadic_0(0); - // CHECK: invoke void (i32, ...) @foreign_c_variadic_0([[PARAM]] 0, [[PARAM]] 42) + // CHECK: call void (i32, ...) @foreign_c_variadic_0([[PARAM]] 0, [[PARAM]] 42) foreign_c_variadic_0(0, 42i32); - // CHECK: invoke void (i32, ...) @foreign_c_variadic_0([[PARAM]] 0, [[PARAM]] 42, [[PARAM]] 1024) + // CHECK: call void (i32, ...) @foreign_c_variadic_0([[PARAM]] 0, [[PARAM]] 42, [[PARAM]] 1024) foreign_c_variadic_0(0, 42i32, 1024i32); - // CHECK: invoke void (i32, ...) @foreign_c_variadic_0([[PARAM]] 0, [[PARAM]] 42, [[PARAM]] 1024, [[PARAM]] 0) + // CHECK: call void (i32, ...) @foreign_c_variadic_0([[PARAM]] 0, [[PARAM]] 42, [[PARAM]] 1024, [[PARAM]] 0) foreign_c_variadic_0(0, 42i32, 1024i32, 0i32); } @@ -30,24 +30,24 @@ pub unsafe extern "C" fn use_foreign_c_variadic_0() { // removing the "spoofed" `VaListImpl` that is used by Rust defined C-variadics. #[unwind(aborts)] // FIXME(#58794) pub unsafe extern "C" fn use_foreign_c_variadic_1_0(ap: VaList) { - // CHECK: invoke void ({{.*}}*, ...) @foreign_c_variadic_1({{.*}} %ap) + // CHECK: call void ({{.*}}*, ...) @foreign_c_variadic_1({{.*}} %ap) foreign_c_variadic_1(ap); } #[unwind(aborts)] // FIXME(#58794) pub unsafe extern "C" fn use_foreign_c_variadic_1_1(ap: VaList) { - // CHECK: invoke void ({{.*}}*, ...) @foreign_c_variadic_1({{.*}} %ap, [[PARAM]] 42) + // CHECK: call void ({{.*}}*, ...) @foreign_c_variadic_1({{.*}} %ap, [[PARAM]] 42) foreign_c_variadic_1(ap, 42i32); } #[unwind(aborts)] // FIXME(#58794) pub unsafe extern "C" fn use_foreign_c_variadic_1_2(ap: VaList) { - // CHECK: invoke void ({{.*}}*, ...) @foreign_c_variadic_1({{.*}} %ap, [[PARAM]] 2, [[PARAM]] 42) + // CHECK: call void ({{.*}}*, ...) @foreign_c_variadic_1({{.*}} %ap, [[PARAM]] 2, [[PARAM]] 42) foreign_c_variadic_1(ap, 2i32, 42i32); } #[unwind(aborts)] // FIXME(#58794) pub unsafe extern "C" fn use_foreign_c_variadic_1_3(ap: VaList) { - // CHECK: invoke void ({{.*}}*, ...) @foreign_c_variadic_1({{.*}} %ap, [[PARAM]] 2, [[PARAM]] 42, [[PARAM]] 0) + // CHECK: call void ({{.*}}*, ...) @foreign_c_variadic_1({{.*}} %ap, [[PARAM]] 2, [[PARAM]] 42, [[PARAM]] 0) foreign_c_variadic_1(ap, 2i32, 42i32, 0i32); } diff --git a/src/test/codegen/call-llvm-intrinsics.rs b/src/test/codegen/call-llvm-intrinsics.rs new file mode 100644 index 00000000000..c7a464a9b0e --- /dev/null +++ b/src/test/codegen/call-llvm-intrinsics.rs @@ -0,0 +1,27 @@ +// compile-flags: -C no-prepopulate-passes + +#![feature(link_llvm_intrinsics)] +#![crate_type = "lib"] + +struct A; + +impl Drop for A { + fn drop(&mut self) { + println!("A"); + } +} + +extern { + #[link_name = "llvm.sqrt.f32"] + fn sqrt(x: f32) -> f32; +} + +pub fn do_call() { + let _a = A; + + unsafe { + // Ensure that we `call` LLVM intrinsics instead of trying to `invoke` them + // CHECK: call float @llvm.sqrt.f32(float 4.000000e+00 + sqrt(4.0); + } +} diff --git a/src/test/codegen/enum-debug-clike.rs b/src/test/codegen/enum-debug-clike.rs index f268c8bcbcc..134443931e9 100644 --- a/src/test/codegen/enum-debug-clike.rs +++ b/src/test/codegen/enum-debug-clike.rs @@ -1,18 +1,13 @@ -// This test depends on a patch that was committed to upstream LLVM -// before 7.0, then backported to the Rust LLVM fork. It tests that -// debug info for "c-like" enums is properly emitted. +// This tests that debug info for "c-like" enums is properly emitted. +// This is ignored for the fallback mode on MSVC due to problems with PDB. // ignore-tidy-linelength -// ignore-windows -// min-system-llvm-version 8.0 +// ignore-msvc // compile-flags: -g -C no-prepopulate-passes -// DIFlagFixedEnum was deprecated in 8.0, renamed to DIFlagEnumClass. -// We match either for compatibility. - // CHECK-LABEL: @main -// CHECK: {{.*}}DICompositeType{{.*}}tag: DW_TAG_enumeration_type,{{.*}}name: "E",{{.*}}flags: {{(DIFlagEnumClass|DIFlagFixedEnum)}},{{.*}} +// CHECK: {{.*}}DICompositeType{{.*}}tag: DW_TAG_enumeration_type,{{.*}}name: "E",{{.*}}flags: DIFlagEnumClass,{{.*}} // CHECK: {{.*}}DIEnumerator{{.*}}name: "A",{{.*}}value: {{[0-9].*}} // CHECK: {{.*}}DIEnumerator{{.*}}name: "B",{{.*}}value: {{[0-9].*}} // CHECK: {{.*}}DIEnumerator{{.*}}name: "C",{{.*}}value: {{[0-9].*}} diff --git a/src/test/codegen/enum-debug-niche-2.rs b/src/test/codegen/enum-debug-niche-2.rs index 0f17976ef49..0f78234d977 100644 --- a/src/test/codegen/enum-debug-niche-2.rs +++ b/src/test/codegen/enum-debug-niche-2.rs @@ -1,10 +1,8 @@ -// This test depends on a patch that was committed to upstream LLVM -// before 7.0, then backported to the Rust LLVM fork. It tests that -// optimized enum debug info accurately reflects the enum layout. +// This tests that optimized enum debug info accurately reflects the enum layout. +// This is ignored for the fallback mode on MSVC due to problems with PDB. // ignore-tidy-linelength -// ignore-windows -// min-system-llvm-version 8.0 +// ignore-msvc // compile-flags: -g -C no-prepopulate-passes diff --git a/src/test/codegen/enum-debug-niche.rs b/src/test/codegen/enum-debug-niche.rs index 2272488375f..b718a6854dd 100644 --- a/src/test/codegen/enum-debug-niche.rs +++ b/src/test/codegen/enum-debug-niche.rs @@ -1,9 +1,7 @@ -// This test depends on a patch that was committed to upstream LLVM -// before 7.0, then backported to the Rust LLVM fork. It tests that -// optimized enum debug info accurately reflects the enum layout. +// This tests that optimized enum debug info accurately reflects the enum layout. +// This is ignored for the fallback mode on MSVC due to problems with PDB. -// ignore-windows -// min-system-llvm-version 8.0 +// ignore-msvc // compile-flags: -g -C no-prepopulate-passes diff --git a/src/test/codegen/enum-debug-tagged.rs b/src/test/codegen/enum-debug-tagged.rs index 3539aae42ea..095c49ac3ac 100644 --- a/src/test/codegen/enum-debug-tagged.rs +++ b/src/test/codegen/enum-debug-tagged.rs @@ -1,9 +1,7 @@ -// This test depends on a patch that was committed to upstream LLVM -// before 7.0, then backported to the Rust LLVM fork. It tests that -// debug info for tagged (ordinary) enums is properly emitted. +// This tests that debug info for tagged (ordinary) enums is properly emitted. +// This is ignored for the fallback mode on MSVC due to problems with PDB. -// ignore-windows -// min-system-llvm-version 8.0 +// ignore-msvc // compile-flags: -g -C no-prepopulate-passes diff --git a/src/test/codegen/force-frame-pointers.rs b/src/test/codegen/force-frame-pointers.rs index 4c94a601f33..637c4234654 100644 --- a/src/test/codegen/force-frame-pointers.rs +++ b/src/test/codegen/force-frame-pointers.rs @@ -1,4 +1,3 @@ -// min-llvm-version 8.0 // compile-flags: -C no-prepopulate-passes -C force-frame-pointers=y #![crate_type="lib"] diff --git a/src/test/codegen/instrument-mcount.rs b/src/test/codegen/instrument-mcount.rs index e4e6d5ca2b8..518a2a0da2a 100644 --- a/src/test/codegen/instrument-mcount.rs +++ b/src/test/codegen/instrument-mcount.rs @@ -1,4 +1,3 @@ -// min-llvm-version 8.0 // ignore-tidy-linelength // compile-flags: -Z instrument-mcount diff --git a/src/test/compile-fail/issue-52443.rs b/src/test/compile-fail/issue-52443.rs index 3a022230b39..ad6f4970367 100644 --- a/src/test/compile-fail/issue-52443.rs +++ b/src/test/compile-fail/issue-52443.rs @@ -8,4 +8,9 @@ fn main() { //~| WARN denote infinite loops with [(); { for _ in 0usize.. {}; 0}]; //~^ ERROR `for` is not allowed in a `const` + //~| ERROR calls in constants are limited to constant functions + //~| ERROR references in constants may only refer to immutable values + //~| ERROR calls in constants are limited to constant functions + //~| ERROR constant contains unimplemented expression type + //~| ERROR evaluation of constant value failed } diff --git a/src/test/debuginfo/borrowed-enum.rs b/src/test/debuginfo/borrowed-enum.rs index 63c11f59c15..85e11c10c68 100644 --- a/src/test/debuginfo/borrowed-enum.rs +++ b/src/test/debuginfo/borrowed-enum.rs @@ -1,7 +1,6 @@ // ignore-tidy-linelength -// Require LLVM with DW_TAG_variant_part and a gdb or lldb that can read it. -// min-system-llvm-version: 8.0 +// Require a gdb or lldb that can read DW_TAG_variant_part. // min-gdb-version: 8.2 // rust-lldb diff --git a/src/test/debuginfo/enum-thinlto.rs b/src/test/debuginfo/enum-thinlto.rs index 13577b0587f..9359e55dcee 100644 --- a/src/test/debuginfo/enum-thinlto.rs +++ b/src/test/debuginfo/enum-thinlto.rs @@ -1,5 +1,4 @@ -// Require LLVM with DW_TAG_variant_part and a gdb that can read it. -// min-system-llvm-version: 8.0 +// Require a gdb that can read DW_TAG_variant_part. // min-gdb-version: 8.2 // compile-flags:-g -Z thinlto diff --git a/src/test/debuginfo/generator-objects.rs b/src/test/debuginfo/generator-objects.rs index f19a3c71dd8..382b0231d3b 100644 --- a/src/test/debuginfo/generator-objects.rs +++ b/src/test/debuginfo/generator-objects.rs @@ -1,7 +1,6 @@ // ignore-tidy-linelength -// Require LLVM with DW_TAG_variant_part and a gdb that can read it. -// min-system-llvm-version: 8.0 +// Require a gdb that can read DW_TAG_variant_part. // min-gdb-version: 8.2 // compile-flags:-g diff --git a/src/test/debuginfo/generic-enum-with-different-disr-sizes.rs b/src/test/debuginfo/generic-enum-with-different-disr-sizes.rs index 72d38a6f045..adcb04da30d 100644 --- a/src/test/debuginfo/generic-enum-with-different-disr-sizes.rs +++ b/src/test/debuginfo/generic-enum-with-different-disr-sizes.rs @@ -1,8 +1,7 @@ // ignore-lldb: FIXME(#27089) // min-lldb-version: 310 -// Require LLVM with DW_TAG_variant_part and a gdb that can read it. -// min-system-llvm-version: 8.0 +// Require a gdb that can read DW_TAG_variant_part. // min-gdb-version: 8.2 // compile-flags:-g diff --git a/src/test/debuginfo/generic-struct-style-enum.rs b/src/test/debuginfo/generic-struct-style-enum.rs index 3dc5cb807b4..678ca8df040 100644 --- a/src/test/debuginfo/generic-struct-style-enum.rs +++ b/src/test/debuginfo/generic-struct-style-enum.rs @@ -1,8 +1,7 @@ // ignore-tidy-linelength // min-lldb-version: 310 -// Require LLVM with DW_TAG_variant_part and a gdb that can read it. -// min-system-llvm-version: 8.0 +// Require a gdb that can read DW_TAG_variant_part. // min-gdb-version: 8.2 // compile-flags:-g diff --git a/src/test/debuginfo/generic-tuple-style-enum.rs b/src/test/debuginfo/generic-tuple-style-enum.rs index b16634ee6d7..89aa78a6e10 100644 --- a/src/test/debuginfo/generic-tuple-style-enum.rs +++ b/src/test/debuginfo/generic-tuple-style-enum.rs @@ -1,8 +1,6 @@ // ignore-tidy-linelength -// Require LLVM with DW_TAG_variant_part and a gdb and lldb that can -// read it. -// min-system-llvm-version: 8.0 +// Require a gdb or lldb that can read DW_TAG_variant_part. // min-gdb-version: 8.2 // rust-lldb diff --git a/src/test/debuginfo/issue-57822.rs b/src/test/debuginfo/issue-57822.rs index 4de88e9dae6..e9cfa3f7d69 100644 --- a/src/test/debuginfo/issue-57822.rs +++ b/src/test/debuginfo/issue-57822.rs @@ -1,8 +1,7 @@ // This test makes sure that the LLDB pretty printer does not throw an exception // for nested closures and generators. -// Require LLVM with DW_TAG_variant_part and a gdb that can read it. -// min-system-llvm-version: 8.0 +// Require a gdb that can read DW_TAG_variant_part. // min-gdb-version: 8.2 // ignore-tidy-linelength diff --git a/src/test/debuginfo/recursive-struct.rs b/src/test/debuginfo/recursive-struct.rs index 4f75ef4fa9b..c0bd6736701 100644 --- a/src/test/debuginfo/recursive-struct.rs +++ b/src/test/debuginfo/recursive-struct.rs @@ -1,7 +1,6 @@ // ignore-lldb -// Require LLVM with DW_TAG_variant_part and a gdb that can read it. -// min-system-llvm-version: 8.0 +// Require a gdb that can read DW_TAG_variant_part. // min-gdb-version: 8.2 // compile-flags:-g diff --git a/src/test/debuginfo/struct-style-enum.rs b/src/test/debuginfo/struct-style-enum.rs index 5843b076b1f..34f75a4e304 100644 --- a/src/test/debuginfo/struct-style-enum.rs +++ b/src/test/debuginfo/struct-style-enum.rs @@ -1,8 +1,6 @@ // ignore-tidy-linelength -// Require LLVM with DW_TAG_variant_part and a gdb and lldb that can -// read it. -// min-system-llvm-version: 8.0 +// Require a gdb or lldb that can read DW_TAG_variant_part. // min-gdb-version: 8.2 // rust-lldb diff --git a/src/test/debuginfo/tuple-style-enum.rs b/src/test/debuginfo/tuple-style-enum.rs index 4d9727a388b..87b0bc6294d 100644 --- a/src/test/debuginfo/tuple-style-enum.rs +++ b/src/test/debuginfo/tuple-style-enum.rs @@ -1,8 +1,6 @@ // ignore-tidy-linelength -// Require LLVM with DW_TAG_variant_part and a gdb and lldb that can -// read it. -// min-system-llvm-version: 8.0 +// Require a gdb or lldb that can read DW_TAG_variant_part. // min-gdb-version: 8.2 // rust-lldb diff --git a/src/test/debuginfo/unique-enum.rs b/src/test/debuginfo/unique-enum.rs index c440ce059f7..9d938b6e369 100644 --- a/src/test/debuginfo/unique-enum.rs +++ b/src/test/debuginfo/unique-enum.rs @@ -1,6 +1,4 @@ -// Require LLVM with DW_TAG_variant_part and a gdb and lldb that can -// read it. -// min-system-llvm-version: 8.0 +// Require a gdb or lldb that can read DW_TAG_variant_part. // min-gdb-version: 8.2 // rust-lldb diff --git a/src/test/incremental/thinlto/cgu_invalidated_when_export_added.rs b/src/test/incremental/thinlto/cgu_invalidated_when_export_added.rs new file mode 100644 index 00000000000..4d48a5f0ac5 --- /dev/null +++ b/src/test/incremental/thinlto/cgu_invalidated_when_export_added.rs @@ -0,0 +1,26 @@ +// revisions: cfail1 cfail2 +// build-pass + +// rust-lang/rust#69798: +// +// This is analgous to cgu_invalidated_when_import_added, but it covers a +// problem uncovered where a change to the *export* set caused a link failure +// when reusing post-LTO optimized object code. + +pub struct Foo {} +impl Drop for Foo { + fn drop(&mut self) { + println!("Dropping Foo"); + } +} +#[no_mangle] +pub extern "C" fn run() { + thread_local! { pub static FOO : Foo = Foo { } ; } + + #[cfg(cfail2)] + { + FOO.with(|_f| ()) + } +} + +pub fn main() { run() } diff --git a/src/test/incremental/thinlto/cgu_invalidated_when_export_removed.rs b/src/test/incremental/thinlto/cgu_invalidated_when_export_removed.rs new file mode 100644 index 00000000000..e85b4856f3a --- /dev/null +++ b/src/test/incremental/thinlto/cgu_invalidated_when_export_removed.rs @@ -0,0 +1,26 @@ +// revisions: cfail1 cfail2 +// build-pass + +// rust-lang/rust#69798: +// +// This is analgous to cgu_invalidated_when_export_added, but it covers the +// other direction. This is analogous to cgu_invalidated_when_import_added: we +// include it, because it may uncover bugs in variant implementation strategies. + +pub struct Foo {} +impl Drop for Foo { + fn drop(&mut self) { + println!("Dropping Foo"); + } +} +#[no_mangle] +pub extern "C" fn run() { + thread_local! { pub static FOO : Foo = Foo { } ; } + + #[cfg(cfail1)] + { + FOO.with(|_f| ()) + } +} + +pub fn main() { run() } diff --git a/src/test/mir-opt/address-of/rustc.address_of_reborrow.SimplifyCfg-initial.after.mir b/src/test/mir-opt/address-of/rustc.address_of_reborrow.SimplifyCfg-initial.after.mir index af07da4cfe0..d0b5c401bea 100644 --- a/src/test/mir-opt/address-of/rustc.address_of_reborrow.SimplifyCfg-initial.after.mir +++ b/src/test/mir-opt/address-of/rustc.address_of_reborrow.SimplifyCfg-initial.after.mir @@ -298,7 +298,13 @@ fn address_of_reborrow() -> () { StorageDead(_48); // bb0[157]: scope 13 at $DIR/address-of.rs:36:25: 36:26 FakeRead(ForLet, _47); // bb0[158]: scope 13 at $DIR/address-of.rs:36:9: 36:10 AscribeUserType(_47, o, UserTypeProjection { base: UserType(29), projs: [] }); // bb0[159]: scope 13 at $DIR/address-of.rs:36:12: 36:22 - _0 = (); // bb0[160]: scope 0 at $DIR/address-of.rs:3:26: 37:2 + _0 = const (); // bb0[160]: scope 0 at $DIR/address-of.rs:3:26: 37:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/address-of.rs:3:26: 37:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_47); // bb0[161]: scope 13 at $DIR/address-of.rs:37:1: 37:2 StorageDead(_45); // bb0[162]: scope 12 at $DIR/address-of.rs:37:1: 37:2 StorageDead(_44); // bb0[163]: scope 11 at $DIR/address-of.rs:37:1: 37:2 diff --git a/src/test/mir-opt/address-of/rustc.borrow_and_cast.SimplifyCfg-initial.after.mir b/src/test/mir-opt/address-of/rustc.borrow_and_cast.SimplifyCfg-initial.after.mir index 29ccff49202..0ed76f230fd 100644 --- a/src/test/mir-opt/address-of/rustc.borrow_and_cast.SimplifyCfg-initial.after.mir +++ b/src/test/mir-opt/address-of/rustc.borrow_and_cast.SimplifyCfg-initial.after.mir @@ -38,7 +38,13 @@ fn borrow_and_cast(_1: i32) -> () { _6 = &raw mut (*_7); // bb0[15]: scope 2 at $DIR/address-of.rs:44:13: 44:19 FakeRead(ForLet, _6); // bb0[16]: scope 2 at $DIR/address-of.rs:44:9: 44:10 StorageDead(_7); // bb0[17]: scope 2 at $DIR/address-of.rs:44:31: 44:32 - _0 = (); // bb0[18]: scope 0 at $DIR/address-of.rs:41:32: 45:2 + _0 = const (); // bb0[18]: scope 0 at $DIR/address-of.rs:41:32: 45:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/address-of.rs:41:32: 45:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_6); // bb0[19]: scope 2 at $DIR/address-of.rs:45:1: 45:2 StorageDead(_4); // bb0[20]: scope 1 at $DIR/address-of.rs:45:1: 45:2 StorageDead(_2); // bb0[21]: scope 0 at $DIR/address-of.rs:45:1: 45:2 diff --git a/src/test/mir-opt/array-index-is-temporary/32bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/array-index-is-temporary/32bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir index 0016cebbb4c..217d080be4f 100644 --- a/src/test/mir-opt/array-index-is-temporary/32bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/array-index-is-temporary/32bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir @@ -82,7 +82,13 @@ fn main() -> () { _1[_7] = move _5; // bb2[0]: scope 3 at $DIR/array-index-is-temporary.rs:16:5: 16:29 StorageDead(_5); // bb2[1]: scope 3 at $DIR/array-index-is-temporary.rs:16:28: 16:29 StorageDead(_7); // bb2[2]: scope 3 at $DIR/array-index-is-temporary.rs:16:29: 16:30 - _0 = (); // bb2[3]: scope 0 at $DIR/array-index-is-temporary.rs:12:11: 17:2 + _0 = const (); // bb2[3]: scope 0 at $DIR/array-index-is-temporary.rs:12:11: 17:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/array-index-is-temporary.rs:12:11: 17:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_3); // bb2[4]: scope 2 at $DIR/array-index-is-temporary.rs:17:1: 17:2 StorageDead(_2); // bb2[5]: scope 1 at $DIR/array-index-is-temporary.rs:17:1: 17:2 StorageDead(_1); // bb2[6]: scope 0 at $DIR/array-index-is-temporary.rs:17:1: 17:2 diff --git a/src/test/mir-opt/array-index-is-temporary/64bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/array-index-is-temporary/64bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir index a004ab4a06a..c75acef2a27 100644 --- a/src/test/mir-opt/array-index-is-temporary/64bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/array-index-is-temporary/64bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir @@ -82,7 +82,13 @@ fn main() -> () { _1[_7] = move _5; // bb2[0]: scope 3 at $DIR/array-index-is-temporary.rs:16:5: 16:29 StorageDead(_5); // bb2[1]: scope 3 at $DIR/array-index-is-temporary.rs:16:28: 16:29 StorageDead(_7); // bb2[2]: scope 3 at $DIR/array-index-is-temporary.rs:16:29: 16:30 - _0 = (); // bb2[3]: scope 0 at $DIR/array-index-is-temporary.rs:12:11: 17:2 + _0 = const (); // bb2[3]: scope 0 at $DIR/array-index-is-temporary.rs:12:11: 17:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/array-index-is-temporary.rs:12:11: 17:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_3); // bb2[4]: scope 2 at $DIR/array-index-is-temporary.rs:17:1: 17:2 StorageDead(_2); // bb2[5]: scope 1 at $DIR/array-index-is-temporary.rs:17:1: 17:2 StorageDead(_1); // bb2[6]: scope 0 at $DIR/array-index-is-temporary.rs:17:1: 17:2 diff --git a/src/test/mir-opt/basic_assignment/rustc.main.SimplifyCfg-initial.after.mir b/src/test/mir-opt/basic_assignment/rustc.main.SimplifyCfg-initial.after.mir index a3f4573964c..86ee1be6f74 100644 --- a/src/test/mir-opt/basic_assignment/rustc.main.SimplifyCfg-initial.after.mir +++ b/src/test/mir-opt/basic_assignment/rustc.main.SimplifyCfg-initial.after.mir @@ -72,7 +72,13 @@ fn main() -> () { bb6: { StorageDead(_6); // bb6[0]: scope 4 at $DIR/basic_assignment.rs:23:19: 23:20 - _0 = (); // bb6[1]: scope 0 at $DIR/basic_assignment.rs:10:11: 24:2 + _0 = const (); // bb6[1]: scope 0 at $DIR/basic_assignment.rs:10:11: 24:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/basic_assignment.rs:10:11: 24:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } drop(_5) -> [return: bb7, unwind: bb3]; // bb6[2]: scope 3 at $DIR/basic_assignment.rs:24:1: 24:2 } diff --git a/src/test/mir-opt/box_expr/rustc.main.ElaborateDrops.before.mir b/src/test/mir-opt/box_expr/rustc.main.ElaborateDrops.before.mir index 61986535dd3..aef0da9d6f0 100644 --- a/src/test/mir-opt/box_expr/rustc.main.ElaborateDrops.before.mir +++ b/src/test/mir-opt/box_expr/rustc.main.ElaborateDrops.before.mir @@ -53,7 +53,13 @@ fn main() -> () { bb5: { StorageDead(_4); // bb5[0]: scope 1 at $DIR/box_expr.rs:8:11: 8:12 StorageDead(_3); // bb5[1]: scope 1 at $DIR/box_expr.rs:8:12: 8:13 - _0 = (); // bb5[2]: scope 0 at $DIR/box_expr.rs:6:11: 9:2 + _0 = const (); // bb5[2]: scope 0 at $DIR/box_expr.rs:6:11: 9:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/box_expr.rs:6:11: 9:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } drop(_1) -> bb8; // bb5[3]: scope 0 at $DIR/box_expr.rs:9:1: 9:2 } diff --git a/src/test/mir-opt/byte_slice/rustc.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/byte_slice/rustc.main.SimplifyCfg-elaborate-drops.after.mir index 14be9c990bd..84f4e5bfd63 100644 --- a/src/test/mir-opt/byte_slice/rustc.main.SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/byte_slice/rustc.main.SimplifyCfg-elaborate-drops.after.mir @@ -34,7 +34,13 @@ fn main() -> () { // mir::Constant // + span: $DIR/byte_slice.rs:6:19: 6:23 // + literal: Const { ty: u8, val: Value(Scalar(0x78)) } - _0 = (); // bb0[4]: scope 0 at $DIR/byte_slice.rs:4:11: 7:2 + _0 = const (); // bb0[4]: scope 0 at $DIR/byte_slice.rs:4:11: 7:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/byte_slice.rs:4:11: 7:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_2); // bb0[5]: scope 1 at $DIR/byte_slice.rs:7:1: 7:2 StorageDead(_1); // bb0[6]: scope 0 at $DIR/byte_slice.rs:7:1: 7:2 return; // bb0[7]: scope 0 at $DIR/byte_slice.rs:7:2: 7:2 diff --git a/src/test/mir-opt/const_allocation/32bit/rustc.main.ConstProp.after.mir b/src/test/mir-opt/const_allocation/32bit/rustc.main.ConstProp.after.mir index 58806724508..2247b8e155a 100644 --- a/src/test/mir-opt/const_allocation/32bit/rustc.main.ConstProp.after.mir +++ b/src/test/mir-opt/const_allocation/32bit/rustc.main.ConstProp.after.mir @@ -18,7 +18,13 @@ fn main() -> () { _1 = (*_2); // bb0[3]: scope 0 at $DIR/const_allocation.rs:8:5: 8:8 StorageDead(_2); // bb0[4]: scope 0 at $DIR/const_allocation.rs:8:8: 8:9 StorageDead(_1); // bb0[5]: scope 0 at $DIR/const_allocation.rs:8:8: 8:9 - _0 = (); // bb0[6]: scope 0 at $DIR/const_allocation.rs:7:11: 9:2 + _0 = const (); // bb0[6]: scope 0 at $DIR/const_allocation.rs:7:11: 9:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/const_allocation.rs:7:11: 9:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } return; // bb0[7]: scope 0 at $DIR/const_allocation.rs:9:2: 9:2 } } diff --git a/src/test/mir-opt/const_allocation/64bit/rustc.main.ConstProp.after.mir b/src/test/mir-opt/const_allocation/64bit/rustc.main.ConstProp.after.mir index b60d23aa3f1..d6cca185ab0 100644 --- a/src/test/mir-opt/const_allocation/64bit/rustc.main.ConstProp.after.mir +++ b/src/test/mir-opt/const_allocation/64bit/rustc.main.ConstProp.after.mir @@ -18,7 +18,13 @@ fn main() -> () { _1 = (*_2); // bb0[3]: scope 0 at $DIR/const_allocation.rs:8:5: 8:8 StorageDead(_2); // bb0[4]: scope 0 at $DIR/const_allocation.rs:8:8: 8:9 StorageDead(_1); // bb0[5]: scope 0 at $DIR/const_allocation.rs:8:8: 8:9 - _0 = (); // bb0[6]: scope 0 at $DIR/const_allocation.rs:7:11: 9:2 + _0 = const (); // bb0[6]: scope 0 at $DIR/const_allocation.rs:7:11: 9:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/const_allocation.rs:7:11: 9:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } return; // bb0[7]: scope 0 at $DIR/const_allocation.rs:9:2: 9:2 } } diff --git a/src/test/mir-opt/const_allocation2/32bit/rustc.main.ConstProp.after.mir b/src/test/mir-opt/const_allocation2/32bit/rustc.main.ConstProp.after.mir index 6caecf1ecea..4105d673218 100644 --- a/src/test/mir-opt/const_allocation2/32bit/rustc.main.ConstProp.after.mir +++ b/src/test/mir-opt/const_allocation2/32bit/rustc.main.ConstProp.after.mir @@ -18,7 +18,13 @@ fn main() -> () { _1 = (*_2); // bb0[3]: scope 0 at $DIR/const_allocation2.rs:5:5: 5:8 StorageDead(_2); // bb0[4]: scope 0 at $DIR/const_allocation2.rs:5:8: 5:9 StorageDead(_1); // bb0[5]: scope 0 at $DIR/const_allocation2.rs:5:8: 5:9 - _0 = (); // bb0[6]: scope 0 at $DIR/const_allocation2.rs:4:11: 6:2 + _0 = const (); // bb0[6]: scope 0 at $DIR/const_allocation2.rs:4:11: 6:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/const_allocation2.rs:4:11: 6:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } return; // bb0[7]: scope 0 at $DIR/const_allocation2.rs:6:2: 6:2 } } diff --git a/src/test/mir-opt/const_allocation2/64bit/rustc.main.ConstProp.after.mir b/src/test/mir-opt/const_allocation2/64bit/rustc.main.ConstProp.after.mir index 52e7c2aec2b..e61f0a8b69f 100644 --- a/src/test/mir-opt/const_allocation2/64bit/rustc.main.ConstProp.after.mir +++ b/src/test/mir-opt/const_allocation2/64bit/rustc.main.ConstProp.after.mir @@ -18,7 +18,13 @@ fn main() -> () { _1 = (*_2); // bb0[3]: scope 0 at $DIR/const_allocation2.rs:5:5: 5:8 StorageDead(_2); // bb0[4]: scope 0 at $DIR/const_allocation2.rs:5:8: 5:9 StorageDead(_1); // bb0[5]: scope 0 at $DIR/const_allocation2.rs:5:8: 5:9 - _0 = (); // bb0[6]: scope 0 at $DIR/const_allocation2.rs:4:11: 6:2 + _0 = const (); // bb0[6]: scope 0 at $DIR/const_allocation2.rs:4:11: 6:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/const_allocation2.rs:4:11: 6:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } return; // bb0[7]: scope 0 at $DIR/const_allocation2.rs:6:2: 6:2 } } diff --git a/src/test/mir-opt/const_allocation3/32bit/rustc.main.ConstProp.after.mir b/src/test/mir-opt/const_allocation3/32bit/rustc.main.ConstProp.after.mir index 4fc2c4c3fb3..63e6b8358a5 100644 --- a/src/test/mir-opt/const_allocation3/32bit/rustc.main.ConstProp.after.mir +++ b/src/test/mir-opt/const_allocation3/32bit/rustc.main.ConstProp.after.mir @@ -18,36 +18,42 @@ fn main() -> () { _1 = (*_2); // bb0[3]: scope 0 at $DIR/const_allocation3.rs:5:5: 5:8 StorageDead(_2); // bb0[4]: scope 0 at $DIR/const_allocation3.rs:5:8: 5:9 StorageDead(_1); // bb0[5]: scope 0 at $DIR/const_allocation3.rs:5:8: 5:9 - _0 = (); // bb0[6]: scope 0 at $DIR/const_allocation3.rs:4:11: 6:2 + _0 = const (); // bb0[6]: scope 0 at $DIR/const_allocation3.rs:4:11: 6:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/const_allocation3.rs:4:11: 6:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } return; // bb0[7]: scope 0 at $DIR/const_allocation3.rs:6:2: 6:2 } } alloc0 (static: FOO, size: 4, align: 4) { - ╾alloc10+0╼ │ ╾──╼ + ╾alloc9+0─╼ │ ╾──╼ } -alloc10 (size: 168, align: 1) { +alloc9 (size: 168, align: 1) { 0x00 │ ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab │ ................ - 0x10 │ ab ab ab ab ab ab ab ab ab ab ab ab ╾alloc5+0─╼ │ ............╾──╼ + 0x10 │ ab ab ab ab ab ab ab ab ab ab ab ab ╾alloc4+0─╼ │ ............╾──╼ 0x20 │ 01 ef cd ab 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ 0x30 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ 0x40 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ 0x50 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ 0x60 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ 0x70 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ - 0x80 │ 00 00 00 00 00 00 00 00 00 00 ╾alloc7+0─╼ 00 00 │ ..........╾──╼.. - 0x90 │ ╾alloc8+99╼ 00 00 00 00 00 00 00 00 00 00 00 00 │ ╾──╼............ + 0x80 │ 00 00 00 00 00 00 00 00 00 00 ╾alloc6+0─╼ 00 00 │ ..........╾──╼.. + 0x90 │ ╾alloc7+99╼ 00 00 00 00 00 00 00 00 00 00 00 00 │ ╾──╼............ 0xa0 │ 00 00 00 00 00 00 00 00 │ ........ } -alloc5 (size: 4, align: 4) { +alloc4 (size: 4, align: 4) { 2a 00 00 00 │ *... } -alloc7 (fn: main) +alloc6 (fn: main) -alloc8 (size: 100, align: 1) { +alloc7 (size: 100, align: 1) { 0x00 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ 0x10 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ 0x20 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ diff --git a/src/test/mir-opt/const_allocation3/64bit/rustc.main.ConstProp.after.mir b/src/test/mir-opt/const_allocation3/64bit/rustc.main.ConstProp.after.mir index ae5ebe70437..7dea5c664d8 100644 --- a/src/test/mir-opt/const_allocation3/64bit/rustc.main.ConstProp.after.mir +++ b/src/test/mir-opt/const_allocation3/64bit/rustc.main.ConstProp.after.mir @@ -18,18 +18,24 @@ fn main() -> () { _1 = (*_2); // bb0[3]: scope 0 at $DIR/const_allocation3.rs:5:5: 5:8 StorageDead(_2); // bb0[4]: scope 0 at $DIR/const_allocation3.rs:5:8: 5:9 StorageDead(_1); // bb0[5]: scope 0 at $DIR/const_allocation3.rs:5:8: 5:9 - _0 = (); // bb0[6]: scope 0 at $DIR/const_allocation3.rs:4:11: 6:2 + _0 = const (); // bb0[6]: scope 0 at $DIR/const_allocation3.rs:4:11: 6:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/const_allocation3.rs:4:11: 6:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } return; // bb0[7]: scope 0 at $DIR/const_allocation3.rs:6:2: 6:2 } } alloc0 (static: FOO, size: 8, align: 8) { - ╾──────alloc10+0──────╼ │ ╾──────╼ + ╾──────alloc9+0───────╼ │ ╾──────╼ } -alloc10 (size: 180, align: 1) { +alloc9 (size: 180, align: 1) { 0x00 │ ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab │ ................ - 0x10 │ ab ab ab ab ab ab ab ab ab ab ab ab ╾─alloc5+0─ │ ............╾─── + 0x10 │ ab ab ab ab ab ab ab ab ab ab ab ab ╾─alloc4+0─ │ ............╾─── 0x20 │ ──────────╼ 01 ef cd ab 00 00 00 00 00 00 00 00 │ ───╼............ 0x30 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ 0x40 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ @@ -37,18 +43,18 @@ alloc10 (size: 180, align: 1) { 0x60 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ 0x70 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ 0x80 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ╾──── │ ..............╾─ - 0x90 │ ────alloc7+0────╼ 00 00 ╾──────alloc8+99──────╼ │ ─────╼..╾──────╼ + 0x90 │ ────alloc6+0────╼ 00 00 ╾──────alloc7+99──────╼ │ ─────╼..╾──────╼ 0xa0 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ 0xb0 │ 00 00 00 00 │ .... } -alloc5 (size: 4, align: 4) { +alloc4 (size: 4, align: 4) { 2a 00 00 00 │ *... } -alloc7 (fn: main) +alloc6 (fn: main) -alloc8 (size: 100, align: 1) { +alloc7 (size: 100, align: 1) { 0x00 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ 0x10 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ 0x20 │ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................ diff --git a/src/test/mir-opt/const_prop/aggregate/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/aggregate/rustc.main.ConstProp.diff index d20019287b0..50e6cfc37ee 100644 --- a/src/test/mir-opt/const_prop/aggregate/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/aggregate/rustc.main.ConstProp.diff @@ -54,7 +54,13 @@ + // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) } StorageDead(_2); // bb0[6]: scope 0 at $DIR/aggregate.rs:5:27: 5:28 StorageDead(_3); // bb0[7]: scope 0 at $DIR/aggregate.rs:5:28: 5:29 - _0 = (); // bb0[8]: scope 0 at $DIR/aggregate.rs:4:11: 6:2 + _0 = const (); // bb0[8]: scope 0 at $DIR/aggregate.rs:4:11: 6:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/aggregate.rs:4:11: 6:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_1); // bb0[9]: scope 0 at $DIR/aggregate.rs:6:1: 6:2 return; // bb0[10]: scope 0 at $DIR/aggregate.rs:6:2: 6:2 } diff --git a/src/test/mir-opt/const_prop/array_index/32bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/array_index/32bit/rustc.main.ConstProp.diff index 99d79b23e9e..474d50100b0 100644 --- a/src/test/mir-opt/const_prop/array_index/32bit/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/array_index/32bit/rustc.main.ConstProp.diff @@ -84,7 +84,13 @@ + // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) } StorageDead(_3); // bb1[1]: scope 0 at $DIR/array_index.rs:5:33: 5:34 StorageDead(_2); // bb1[2]: scope 0 at $DIR/array_index.rs:5:33: 5:34 - _0 = (); // bb1[3]: scope 0 at $DIR/array_index.rs:4:11: 6:2 + _0 = const (); // bb1[3]: scope 0 at $DIR/array_index.rs:4:11: 6:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/array_index.rs:4:11: 6:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_1); // bb1[4]: scope 0 at $DIR/array_index.rs:6:1: 6:2 return; // bb1[5]: scope 0 at $DIR/array_index.rs:6:2: 6:2 } diff --git a/src/test/mir-opt/const_prop/array_index/64bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/array_index/64bit/rustc.main.ConstProp.diff index 629ca226f2a..b3d353bd487 100644 --- a/src/test/mir-opt/const_prop/array_index/64bit/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/array_index/64bit/rustc.main.ConstProp.diff @@ -84,7 +84,13 @@ + // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) } StorageDead(_3); // bb1[1]: scope 0 at $DIR/array_index.rs:5:33: 5:34 StorageDead(_2); // bb1[2]: scope 0 at $DIR/array_index.rs:5:33: 5:34 - _0 = (); // bb1[3]: scope 0 at $DIR/array_index.rs:4:11: 6:2 + _0 = const (); // bb1[3]: scope 0 at $DIR/array_index.rs:4:11: 6:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/array_index.rs:4:11: 6:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_1); // bb1[4]: scope 0 at $DIR/array_index.rs:6:1: 6:2 return; // bb1[5]: scope 0 at $DIR/array_index.rs:6:2: 6:2 } diff --git a/src/test/mir-opt/const_prop/boxes/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/boxes/rustc.main.ConstProp.diff index 50ee2abecfe..bf5aff0cf46 100644 --- a/src/test/mir-opt/const_prop/boxes/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/boxes/rustc.main.ConstProp.diff @@ -44,7 +44,13 @@ bb2: { StorageDead(_3); // bb2[0]: scope 0 at $DIR/boxes.rs:12:26: 12:27 - _0 = (); // bb2[1]: scope 0 at $DIR/boxes.rs:11:11: 13:2 + _0 = const (); // bb2[1]: scope 0 at $DIR/boxes.rs:11:11: 13:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/boxes.rs:11:11: 13:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_1); // bb2[2]: scope 0 at $DIR/boxes.rs:13:1: 13:2 return; // bb2[3]: scope 0 at $DIR/boxes.rs:13:2: 13:2 } diff --git a/src/test/mir-opt/const_prop/cast/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/cast/rustc.main.ConstProp.diff index ee6a0e87b12..ca0a309b1b5 100644 --- a/src/test/mir-opt/const_prop/cast/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/cast/rustc.main.ConstProp.diff @@ -39,7 +39,13 @@ + // mir::Constant + // + span: $DIR/cast.rs:6:13: 6:24 + // + literal: Const { ty: u8, val: Value(Scalar(0x2a)) } - _0 = (); // bb0[4]: scope 0 at $DIR/cast.rs:3:11: 7:2 + _0 = const (); // bb0[4]: scope 0 at $DIR/cast.rs:3:11: 7:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/cast.rs:3:11: 7:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_2); // bb0[5]: scope 1 at $DIR/cast.rs:7:1: 7:2 StorageDead(_1); // bb0[6]: scope 0 at $DIR/cast.rs:7:1: 7:2 return; // bb0[7]: scope 0 at $DIR/cast.rs:7:2: 7:2 diff --git a/src/test/mir-opt/const_prop/checked_add/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/checked_add/rustc.main.ConstProp.diff index 0a0a4ff852f..762927575f0 100644 --- a/src/test/mir-opt/const_prop/checked_add/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/checked_add/rustc.main.ConstProp.diff @@ -51,7 +51,13 @@ + // mir::Constant + // + span: $DIR/checked_add.rs:5:18: 5:23 + // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) } - _0 = (); // bb1[1]: scope 0 at $DIR/checked_add.rs:4:11: 6:2 + _0 = const (); // bb1[1]: scope 0 at $DIR/checked_add.rs:4:11: 6:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/checked_add.rs:4:11: 6:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_1); // bb1[2]: scope 0 at $DIR/checked_add.rs:6:1: 6:2 return; // bb1[3]: scope 0 at $DIR/checked_add.rs:6:2: 6:2 } diff --git a/src/test/mir-opt/const_prop/const_prop_fails_gracefully/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/const_prop_fails_gracefully/rustc.main.ConstProp.diff index f4a5b64f0d9..d3a6105a852 100644 --- a/src/test/mir-opt/const_prop/const_prop_fails_gracefully/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/const_prop_fails_gracefully/rustc.main.ConstProp.diff @@ -42,7 +42,13 @@ bb1: { StorageDead(_5); // bb1[0]: scope 1 at $DIR/const_prop_fails_gracefully.rs:8:11: 8:12 StorageDead(_4); // bb1[1]: scope 1 at $DIR/const_prop_fails_gracefully.rs:8:12: 8:13 - _0 = (); // bb1[2]: scope 0 at $DIR/const_prop_fails_gracefully.rs:5:11: 9:2 + _0 = const (); // bb1[2]: scope 0 at $DIR/const_prop_fails_gracefully.rs:5:11: 9:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/const_prop_fails_gracefully.rs:5:11: 9:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_1); // bb1[3]: scope 0 at $DIR/const_prop_fails_gracefully.rs:9:1: 9:2 return; // bb1[4]: scope 0 at $DIR/const_prop_fails_gracefully.rs:9:2: 9:2 } diff --git a/src/test/mir-opt/const_prop/control-flow-simplification/rustc.hello.ConstProp.diff b/src/test/mir-opt/const_prop/control-flow-simplification/rustc.hello.ConstProp.diff index c551bd77d40..cbda5e4ef86 100644 --- a/src/test/mir-opt/const_prop/control-flow-simplification/rustc.hello.ConstProp.diff +++ b/src/test/mir-opt/const_prop/control-flow-simplification/rustc.hello.ConstProp.diff @@ -29,7 +29,13 @@ } bb1: { - _0 = (); // bb1[0]: scope 0 at $DIR/control-flow-simplification.rs:12:5: 14:6 + _0 = const (); // bb1[0]: scope 0 at $DIR/control-flow-simplification.rs:12:5: 14:6 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/control-flow-simplification.rs:12:5: 14:6 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_1); // bb1[1]: scope 0 at $DIR/control-flow-simplification.rs:15:1: 15:2 return; // bb1[2]: scope 0 at $DIR/control-flow-simplification.rs:15:2: 15:2 } diff --git a/src/test/mir-opt/const_prop/control-flow-simplification/rustc.hello.PreCodegen.before.mir b/src/test/mir-opt/const_prop/control-flow-simplification/rustc.hello.PreCodegen.before.mir index 53296f8714b..73922b56669 100644 --- a/src/test/mir-opt/const_prop/control-flow-simplification/rustc.hello.PreCodegen.before.mir +++ b/src/test/mir-opt/const_prop/control-flow-simplification/rustc.hello.PreCodegen.before.mir @@ -4,6 +4,13 @@ fn hello() -> () { let mut _0: (); // return place in scope 0 at $DIR/control-flow-simplification.rs:11:14: 11:14 bb0: { - return; // bb0[0]: scope 0 at $DIR/control-flow-simplification.rs:15:2: 15:2 + _0 = const (); // bb0[0]: scope 0 at $DIR/control-flow-simplification.rs:12:5: 14:6 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/control-flow-simplification.rs:12:5: 14:6 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } + return; // bb0[1]: scope 0 at $DIR/control-flow-simplification.rs:15:2: 15:2 } } diff --git a/src/test/mir-opt/const_prop/discriminant/32bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/discriminant/32bit/rustc.main.ConstProp.diff index 7423a3cd38d..f89d869cab5 100644 --- a/src/test/mir-opt/const_prop/discriminant/32bit/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/discriminant/32bit/rustc.main.ConstProp.diff @@ -87,7 +87,13 @@ // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) } StorageDead(_2); // bb4[1]: scope 0 at $DIR/discriminant.rs:6:67: 6:68 StorageDead(_3); // bb4[2]: scope 0 at $DIR/discriminant.rs:6:68: 6:69 - _0 = (); // bb4[3]: scope 0 at $DIR/discriminant.rs:5:11: 7:2 + _0 = const (); // bb4[3]: scope 0 at $DIR/discriminant.rs:5:11: 7:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/discriminant.rs:5:11: 7:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_1); // bb4[4]: scope 0 at $DIR/discriminant.rs:7:1: 7:2 return; // bb4[5]: scope 0 at $DIR/discriminant.rs:7:2: 7:2 } diff --git a/src/test/mir-opt/const_prop/discriminant/64bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/discriminant/64bit/rustc.main.ConstProp.diff index 60d18cdc942..06f43db50f4 100644 --- a/src/test/mir-opt/const_prop/discriminant/64bit/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/discriminant/64bit/rustc.main.ConstProp.diff @@ -87,7 +87,13 @@ // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) } StorageDead(_2); // bb4[1]: scope 0 at $DIR/discriminant.rs:6:67: 6:68 StorageDead(_3); // bb4[2]: scope 0 at $DIR/discriminant.rs:6:68: 6:69 - _0 = (); // bb4[3]: scope 0 at $DIR/discriminant.rs:5:11: 7:2 + _0 = const (); // bb4[3]: scope 0 at $DIR/discriminant.rs:5:11: 7:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/discriminant.rs:5:11: 7:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_1); // bb4[4]: scope 0 at $DIR/discriminant.rs:7:1: 7:2 return; // bb4[5]: scope 0 at $DIR/discriminant.rs:7:2: 7:2 } diff --git a/src/test/mir-opt/const_prop/indirect/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/indirect/rustc.main.ConstProp.diff index ca3e3bb5d2d..4c80d0d1278 100644 --- a/src/test/mir-opt/const_prop/indirect/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/indirect/rustc.main.ConstProp.diff @@ -62,7 +62,13 @@ + // + span: $DIR/indirect.rs:5:13: 5:29 + // + literal: Const { ty: u8, val: Value(Scalar(0x03)) } StorageDead(_2); // bb1[1]: scope 0 at $DIR/indirect.rs:5:28: 5:29 - _0 = (); // bb1[2]: scope 0 at $DIR/indirect.rs:4:11: 6:2 + _0 = const (); // bb1[2]: scope 0 at $DIR/indirect.rs:4:11: 6:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/indirect.rs:4:11: 6:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_1); // bb1[3]: scope 0 at $DIR/indirect.rs:6:1: 6:2 return; // bb1[4]: scope 0 at $DIR/indirect.rs:6:2: 6:2 } diff --git a/src/test/mir-opt/const_prop/issue-66971/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/issue-66971/rustc.main.ConstProp.diff index d3ebaa0a632..76c6759f700 100644 --- a/src/test/mir-opt/const_prop/issue-66971/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/issue-66971/rustc.main.ConstProp.diff @@ -45,7 +45,13 @@ bb1: { StorageDead(_2); // bb1[0]: scope 0 at $DIR/issue-66971.rs:16:22: 16:23 StorageDead(_1); // bb1[1]: scope 0 at $DIR/issue-66971.rs:16:23: 16:24 - _0 = (); // bb1[2]: scope 0 at $DIR/issue-66971.rs:15:11: 17:2 + _0 = const (); // bb1[2]: scope 0 at $DIR/issue-66971.rs:15:11: 17:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/issue-66971.rs:15:11: 17:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } return; // bb1[3]: scope 0 at $DIR/issue-66971.rs:17:2: 17:2 } } diff --git a/src/test/mir-opt/const_prop/issue-67019/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/issue-67019/rustc.main.ConstProp.diff index 96a20edd91a..05e1a615953 100644 --- a/src/test/mir-opt/const_prop/issue-67019/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/issue-67019/rustc.main.ConstProp.diff @@ -40,7 +40,13 @@ bb1: { StorageDead(_2); // bb1[0]: scope 0 at $DIR/issue-67019.rs:11:19: 11:20 StorageDead(_1); // bb1[1]: scope 0 at $DIR/issue-67019.rs:11:20: 11:21 - _0 = (); // bb1[2]: scope 0 at $DIR/issue-67019.rs:10:11: 12:2 + _0 = const (); // bb1[2]: scope 0 at $DIR/issue-67019.rs:10:11: 12:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/issue-67019.rs:10:11: 12:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } return; // bb1[3]: scope 0 at $DIR/issue-67019.rs:12:2: 12:2 } } diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable/32bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/optimizes_into_variable/32bit/rustc.main.ConstProp.diff index 41ffedf06bc..2868365e9ac 100644 --- a/src/test/mir-opt/const_prop/optimizes_into_variable/32bit/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/optimizes_into_variable/32bit/rustc.main.ConstProp.diff @@ -171,7 +171,13 @@ + // + span: $DIR/optimizes_into_variable.rs:14:13: 14:38 + // + literal: Const { ty: u32, val: Value(Scalar(0x0000002a)) } StorageDead(_9); // bb2[7]: scope 2 at $DIR/optimizes_into_variable.rs:14:38: 14:39 - _0 = (); // bb2[8]: scope 0 at $DIR/optimizes_into_variable.rs:11:11: 15:2 + _0 = const (); // bb2[8]: scope 0 at $DIR/optimizes_into_variable.rs:11:11: 15:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/optimizes_into_variable.rs:11:11: 15:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_8); // bb2[9]: scope 2 at $DIR/optimizes_into_variable.rs:15:1: 15:2 StorageDead(_3); // bb2[10]: scope 1 at $DIR/optimizes_into_variable.rs:15:1: 15:2 StorageDead(_1); // bb2[11]: scope 0 at $DIR/optimizes_into_variable.rs:15:1: 15:2 diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable/32bit/rustc.main.SimplifyLocals.after.mir b/src/test/mir-opt/const_prop/optimizes_into_variable/32bit/rustc.main.SimplifyLocals.after.mir index db4d2d13792..f8aea27df66 100644 --- a/src/test/mir-opt/const_prop/optimizes_into_variable/32bit/rustc.main.SimplifyLocals.after.mir +++ b/src/test/mir-opt/const_prop/optimizes_into_variable/32bit/rustc.main.SimplifyLocals.after.mir @@ -3,15 +3,14 @@ fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:11:11: 11:11 let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:12:9: 12:10 - let mut _3: [i32; 6]; // in scope 0 at $DIR/optimizes_into_variable.rs:13:13: 13:31 scope 1 { debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:12:9: 12:10 let _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:13:9: 13:10 scope 2 { debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:13:9: 13:10 - let _4: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:14:9: 14:10 + let _3: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:14:9: 14:10 scope 3 { - debug z => _4; // in scope 3 at $DIR/optimizes_into_variable.rs:14:9: 14:10 + debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:14:9: 14:10 } } } @@ -26,63 +25,31 @@ fn main() -> () { // + span: $DIR/optimizes_into_variable.rs:12:13: 12:18 // + literal: Const { ty: i32, val: Value(Scalar(0x00000004)) } StorageLive(_2); // bb0[2]: scope 1 at $DIR/optimizes_into_variable.rs:13:9: 13:10 - StorageLive(_3); // bb0[3]: scope 1 at $DIR/optimizes_into_variable.rs:13:13: 13:31 - _3 = [const 0i32, const 1i32, const 2i32, const 3i32, const 4i32, const 5i32]; // bb0[4]: scope 1 at $DIR/optimizes_into_variable.rs:13:13: 13:31 - // ty::Const - // + ty: i32 - // + val: Value(Scalar(0x00000000)) - // mir::Constant - // + span: $DIR/optimizes_into_variable.rs:13:14: 13:15 - // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) } - // ty::Const - // + ty: i32 - // + val: Value(Scalar(0x00000001)) - // mir::Constant - // + span: $DIR/optimizes_into_variable.rs:13:17: 13:18 - // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) } - // ty::Const - // + ty: i32 - // + val: Value(Scalar(0x00000002)) - // mir::Constant - // + span: $DIR/optimizes_into_variable.rs:13:20: 13:21 - // + literal: Const { ty: i32, val: Value(Scalar(0x00000002)) } - // ty::Const - // + ty: i32 - // + val: Value(Scalar(0x00000003)) - // mir::Constant - // + span: $DIR/optimizes_into_variable.rs:13:23: 13:24 - // + literal: Const { ty: i32, val: Value(Scalar(0x00000003)) } - // ty::Const - // + ty: i32 - // + val: Value(Scalar(0x00000004)) - // mir::Constant - // + span: $DIR/optimizes_into_variable.rs:13:26: 13:27 - // + literal: Const { ty: i32, val: Value(Scalar(0x00000004)) } - // ty::Const - // + ty: i32 - // + val: Value(Scalar(0x00000005)) - // mir::Constant - // + span: $DIR/optimizes_into_variable.rs:13:29: 13:30 - // + literal: Const { ty: i32, val: Value(Scalar(0x00000005)) } - _2 = const 3i32; // bb0[5]: scope 1 at $DIR/optimizes_into_variable.rs:13:13: 13:34 + _2 = const 3i32; // bb0[3]: scope 1 at $DIR/optimizes_into_variable.rs:13:13: 13:34 // ty::Const // + ty: i32 // + val: Value(Scalar(0x00000003)) // mir::Constant // + span: $DIR/optimizes_into_variable.rs:13:13: 13:34 // + literal: Const { ty: i32, val: Value(Scalar(0x00000003)) } - StorageDead(_3); // bb0[6]: scope 1 at $DIR/optimizes_into_variable.rs:13:34: 13:35 - StorageLive(_4); // bb0[7]: scope 2 at $DIR/optimizes_into_variable.rs:14:9: 14:10 - _4 = const 42u32; // bb0[8]: scope 2 at $DIR/optimizes_into_variable.rs:14:13: 14:38 + StorageLive(_3); // bb0[4]: scope 2 at $DIR/optimizes_into_variable.rs:14:9: 14:10 + _3 = const 42u32; // bb0[5]: scope 2 at $DIR/optimizes_into_variable.rs:14:13: 14:38 // ty::Const // + ty: u32 // + val: Value(Scalar(0x0000002a)) // mir::Constant // + span: $DIR/optimizes_into_variable.rs:14:13: 14:38 // + literal: Const { ty: u32, val: Value(Scalar(0x0000002a)) } - StorageDead(_4); // bb0[9]: scope 2 at $DIR/optimizes_into_variable.rs:15:1: 15:2 - StorageDead(_2); // bb0[10]: scope 1 at $DIR/optimizes_into_variable.rs:15:1: 15:2 - StorageDead(_1); // bb0[11]: scope 0 at $DIR/optimizes_into_variable.rs:15:1: 15:2 - return; // bb0[12]: scope 0 at $DIR/optimizes_into_variable.rs:15:2: 15:2 + _0 = const (); // bb0[6]: scope 0 at $DIR/optimizes_into_variable.rs:11:11: 15:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/optimizes_into_variable.rs:11:11: 15:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } + StorageDead(_3); // bb0[7]: scope 2 at $DIR/optimizes_into_variable.rs:15:1: 15:2 + StorageDead(_2); // bb0[8]: scope 1 at $DIR/optimizes_into_variable.rs:15:1: 15:2 + StorageDead(_1); // bb0[9]: scope 0 at $DIR/optimizes_into_variable.rs:15:1: 15:2 + return; // bb0[10]: scope 0 at $DIR/optimizes_into_variable.rs:15:2: 15:2 } } diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable/64bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/optimizes_into_variable/64bit/rustc.main.ConstProp.diff index fd3281f5273..0097d9448c8 100644 --- a/src/test/mir-opt/const_prop/optimizes_into_variable/64bit/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/optimizes_into_variable/64bit/rustc.main.ConstProp.diff @@ -171,7 +171,13 @@ + // + span: $DIR/optimizes_into_variable.rs:14:13: 14:38 + // + literal: Const { ty: u32, val: Value(Scalar(0x0000002a)) } StorageDead(_9); // bb2[7]: scope 2 at $DIR/optimizes_into_variable.rs:14:38: 14:39 - _0 = (); // bb2[8]: scope 0 at $DIR/optimizes_into_variable.rs:11:11: 15:2 + _0 = const (); // bb2[8]: scope 0 at $DIR/optimizes_into_variable.rs:11:11: 15:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/optimizes_into_variable.rs:11:11: 15:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_8); // bb2[9]: scope 2 at $DIR/optimizes_into_variable.rs:15:1: 15:2 StorageDead(_3); // bb2[10]: scope 1 at $DIR/optimizes_into_variable.rs:15:1: 15:2 StorageDead(_1); // bb2[11]: scope 0 at $DIR/optimizes_into_variable.rs:15:1: 15:2 diff --git a/src/test/mir-opt/const_prop/optimizes_into_variable/64bit/rustc.main.SimplifyLocals.after.mir b/src/test/mir-opt/const_prop/optimizes_into_variable/64bit/rustc.main.SimplifyLocals.after.mir index db4d2d13792..f8aea27df66 100644 --- a/src/test/mir-opt/const_prop/optimizes_into_variable/64bit/rustc.main.SimplifyLocals.after.mir +++ b/src/test/mir-opt/const_prop/optimizes_into_variable/64bit/rustc.main.SimplifyLocals.after.mir @@ -3,15 +3,14 @@ fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:11:11: 11:11 let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:12:9: 12:10 - let mut _3: [i32; 6]; // in scope 0 at $DIR/optimizes_into_variable.rs:13:13: 13:31 scope 1 { debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:12:9: 12:10 let _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:13:9: 13:10 scope 2 { debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:13:9: 13:10 - let _4: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:14:9: 14:10 + let _3: u32; // in scope 2 at $DIR/optimizes_into_variable.rs:14:9: 14:10 scope 3 { - debug z => _4; // in scope 3 at $DIR/optimizes_into_variable.rs:14:9: 14:10 + debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:14:9: 14:10 } } } @@ -26,63 +25,31 @@ fn main() -> () { // + span: $DIR/optimizes_into_variable.rs:12:13: 12:18 // + literal: Const { ty: i32, val: Value(Scalar(0x00000004)) } StorageLive(_2); // bb0[2]: scope 1 at $DIR/optimizes_into_variable.rs:13:9: 13:10 - StorageLive(_3); // bb0[3]: scope 1 at $DIR/optimizes_into_variable.rs:13:13: 13:31 - _3 = [const 0i32, const 1i32, const 2i32, const 3i32, const 4i32, const 5i32]; // bb0[4]: scope 1 at $DIR/optimizes_into_variable.rs:13:13: 13:31 - // ty::Const - // + ty: i32 - // + val: Value(Scalar(0x00000000)) - // mir::Constant - // + span: $DIR/optimizes_into_variable.rs:13:14: 13:15 - // + literal: Const { ty: i32, val: Value(Scalar(0x00000000)) } - // ty::Const - // + ty: i32 - // + val: Value(Scalar(0x00000001)) - // mir::Constant - // + span: $DIR/optimizes_into_variable.rs:13:17: 13:18 - // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) } - // ty::Const - // + ty: i32 - // + val: Value(Scalar(0x00000002)) - // mir::Constant - // + span: $DIR/optimizes_into_variable.rs:13:20: 13:21 - // + literal: Const { ty: i32, val: Value(Scalar(0x00000002)) } - // ty::Const - // + ty: i32 - // + val: Value(Scalar(0x00000003)) - // mir::Constant - // + span: $DIR/optimizes_into_variable.rs:13:23: 13:24 - // + literal: Const { ty: i32, val: Value(Scalar(0x00000003)) } - // ty::Const - // + ty: i32 - // + val: Value(Scalar(0x00000004)) - // mir::Constant - // + span: $DIR/optimizes_into_variable.rs:13:26: 13:27 - // + literal: Const { ty: i32, val: Value(Scalar(0x00000004)) } - // ty::Const - // + ty: i32 - // + val: Value(Scalar(0x00000005)) - // mir::Constant - // + span: $DIR/optimizes_into_variable.rs:13:29: 13:30 - // + literal: Const { ty: i32, val: Value(Scalar(0x00000005)) } - _2 = const 3i32; // bb0[5]: scope 1 at $DIR/optimizes_into_variable.rs:13:13: 13:34 + _2 = const 3i32; // bb0[3]: scope 1 at $DIR/optimizes_into_variable.rs:13:13: 13:34 // ty::Const // + ty: i32 // + val: Value(Scalar(0x00000003)) // mir::Constant // + span: $DIR/optimizes_into_variable.rs:13:13: 13:34 // + literal: Const { ty: i32, val: Value(Scalar(0x00000003)) } - StorageDead(_3); // bb0[6]: scope 1 at $DIR/optimizes_into_variable.rs:13:34: 13:35 - StorageLive(_4); // bb0[7]: scope 2 at $DIR/optimizes_into_variable.rs:14:9: 14:10 - _4 = const 42u32; // bb0[8]: scope 2 at $DIR/optimizes_into_variable.rs:14:13: 14:38 + StorageLive(_3); // bb0[4]: scope 2 at $DIR/optimizes_into_variable.rs:14:9: 14:10 + _3 = const 42u32; // bb0[5]: scope 2 at $DIR/optimizes_into_variable.rs:14:13: 14:38 // ty::Const // + ty: u32 // + val: Value(Scalar(0x0000002a)) // mir::Constant // + span: $DIR/optimizes_into_variable.rs:14:13: 14:38 // + literal: Const { ty: u32, val: Value(Scalar(0x0000002a)) } - StorageDead(_4); // bb0[9]: scope 2 at $DIR/optimizes_into_variable.rs:15:1: 15:2 - StorageDead(_2); // bb0[10]: scope 1 at $DIR/optimizes_into_variable.rs:15:1: 15:2 - StorageDead(_1); // bb0[11]: scope 0 at $DIR/optimizes_into_variable.rs:15:1: 15:2 - return; // bb0[12]: scope 0 at $DIR/optimizes_into_variable.rs:15:2: 15:2 + _0 = const (); // bb0[6]: scope 0 at $DIR/optimizes_into_variable.rs:11:11: 15:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/optimizes_into_variable.rs:11:11: 15:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } + StorageDead(_3); // bb0[7]: scope 2 at $DIR/optimizes_into_variable.rs:15:1: 15:2 + StorageDead(_2); // bb0[8]: scope 1 at $DIR/optimizes_into_variable.rs:15:1: 15:2 + StorageDead(_1); // bb0[9]: scope 0 at $DIR/optimizes_into_variable.rs:15:1: 15:2 + return; // bb0[10]: scope 0 at $DIR/optimizes_into_variable.rs:15:2: 15:2 } } diff --git a/src/test/mir-opt/const_prop/read_immutable_static/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/read_immutable_static/rustc.main.ConstProp.diff index 6183b22a95f..d9852539844 100644 --- a/src/test/mir-opt/const_prop/read_immutable_static/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/read_immutable_static/rustc.main.ConstProp.diff @@ -60,7 +60,13 @@ StorageDead(_2); // bb0[11]: scope 0 at $DIR/read_immutable_static.rs:7:21: 7:22 StorageDead(_5); // bb0[12]: scope 0 at $DIR/read_immutable_static.rs:7:22: 7:23 StorageDead(_3); // bb0[13]: scope 0 at $DIR/read_immutable_static.rs:7:22: 7:23 - _0 = (); // bb0[14]: scope 0 at $DIR/read_immutable_static.rs:6:11: 8:2 + _0 = const (); // bb0[14]: scope 0 at $DIR/read_immutable_static.rs:6:11: 8:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/read_immutable_static.rs:6:11: 8:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_1); // bb0[15]: scope 0 at $DIR/read_immutable_static.rs:8:1: 8:2 return; // bb0[16]: scope 0 at $DIR/read_immutable_static.rs:8:2: 8:2 } diff --git a/src/test/mir-opt/const_prop/ref_deref/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/ref_deref/rustc.main.ConstProp.diff index 0f8563daba5..591fdaddfcc 100644 --- a/src/test/mir-opt/const_prop/ref_deref/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/ref_deref/rustc.main.ConstProp.diff @@ -29,7 +29,13 @@ + // + literal: Const { ty: i32, val: Value(Scalar(0x00000004)) } StorageDead(_2); // bb0[5]: scope 0 at $DIR/ref_deref.rs:5:10: 5:11 StorageDead(_1); // bb0[6]: scope 0 at $DIR/ref_deref.rs:5:10: 5:11 - _0 = (); // bb0[7]: scope 0 at $DIR/ref_deref.rs:4:11: 6:2 + _0 = const (); // bb0[7]: scope 0 at $DIR/ref_deref.rs:4:11: 6:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/ref_deref.rs:4:11: 6:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } return; // bb0[8]: scope 0 at $DIR/ref_deref.rs:6:2: 6:2 } } diff --git a/src/test/mir-opt/const_prop/ref_deref/rustc.main.PromoteTemps.diff b/src/test/mir-opt/const_prop/ref_deref/rustc.main.PromoteTemps.diff index ea1baa40f7e..5cd9f43a5c6 100644 --- a/src/test/mir-opt/const_prop/ref_deref/rustc.main.PromoteTemps.diff +++ b/src/test/mir-opt/const_prop/ref_deref/rustc.main.PromoteTemps.diff @@ -27,15 +27,21 @@ - StorageDead(_3); // bb0[6]: scope 0 at $DIR/ref_deref.rs:5:10: 5:11 - StorageDead(_2); // bb0[7]: scope 0 at $DIR/ref_deref.rs:5:10: 5:11 - StorageDead(_1); // bb0[8]: scope 0 at $DIR/ref_deref.rs:5:10: 5:11 -- _0 = (); // bb0[9]: scope 0 at $DIR/ref_deref.rs:4:11: 6:2 -- return; // bb0[10]: scope 0 at $DIR/ref_deref.rs:6:2: 6:2 +- _0 = const (); // bb0[9]: scope 0 at $DIR/ref_deref.rs:4:11: 6:2 + // + span: $DIR/ref_deref.rs:5:6: 5:10 + // + literal: Const { ty: &i32, val: Unevaluated(DefId(0:3 ~ ref_deref[317d]::main[0]), [], Some(promoted[0])) } + _2 = &(*_4); // bb0[3]: scope 0 at $DIR/ref_deref.rs:5:6: 5:10 + _1 = (*_2); // bb0[4]: scope 0 at $DIR/ref_deref.rs:5:5: 5:10 + StorageDead(_2); // bb0[5]: scope 0 at $DIR/ref_deref.rs:5:10: 5:11 + StorageDead(_1); // bb0[6]: scope 0 at $DIR/ref_deref.rs:5:10: 5:11 -+ _0 = (); // bb0[7]: scope 0 at $DIR/ref_deref.rs:4:11: 6:2 ++ _0 = const (); // bb0[7]: scope 0 at $DIR/ref_deref.rs:4:11: 6:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/ref_deref.rs:4:11: 6:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } +- return; // bb0[10]: scope 0 at $DIR/ref_deref.rs:6:2: 6:2 + return; // bb0[8]: scope 0 at $DIR/ref_deref.rs:6:2: 6:2 } } diff --git a/src/test/mir-opt/const_prop/ref_deref_project/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/ref_deref_project/rustc.main.ConstProp.diff index c4b3d6b6c27..6393bad2993 100644 --- a/src/test/mir-opt/const_prop/ref_deref_project/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/ref_deref_project/rustc.main.ConstProp.diff @@ -22,7 +22,13 @@ _1 = (*_2); // bb0[4]: scope 0 at $DIR/ref_deref_project.rs:5:5: 5:17 StorageDead(_2); // bb0[5]: scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18 StorageDead(_1); // bb0[6]: scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18 - _0 = (); // bb0[7]: scope 0 at $DIR/ref_deref_project.rs:4:11: 6:2 + _0 = const (); // bb0[7]: scope 0 at $DIR/ref_deref_project.rs:4:11: 6:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/ref_deref_project.rs:4:11: 6:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } return; // bb0[8]: scope 0 at $DIR/ref_deref_project.rs:6:2: 6:2 } } diff --git a/src/test/mir-opt/const_prop/ref_deref_project/rustc.main.PromoteTemps.diff b/src/test/mir-opt/const_prop/ref_deref_project/rustc.main.PromoteTemps.diff index 852436e13b6..020ad7278c0 100644 --- a/src/test/mir-opt/const_prop/ref_deref_project/rustc.main.PromoteTemps.diff +++ b/src/test/mir-opt/const_prop/ref_deref_project/rustc.main.PromoteTemps.diff @@ -22,7 +22,14 @@ // mir::Constant - // + span: $DIR/ref_deref_project.rs:5:9: 5:10 - // + literal: Const { ty: i32, val: Value(Scalar(0x00000004)) } -- // ty::Const ++ // + span: $DIR/ref_deref_project.rs:5:6: 5:17 ++ // + literal: Const { ty: &(i32, i32), val: Unevaluated(DefId(0:3 ~ ref_deref_project[317d]::main[0]), [], Some(promoted[0])) } ++ _2 = &((*_4).1: i32); // bb0[3]: scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17 ++ _1 = (*_2); // bb0[4]: scope 0 at $DIR/ref_deref_project.rs:5:5: 5:17 ++ StorageDead(_2); // bb0[5]: scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18 ++ StorageDead(_1); // bb0[6]: scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18 ++ _0 = const (); // bb0[7]: scope 0 at $DIR/ref_deref_project.rs:4:11: 6:2 + // ty::Const - // + ty: i32 - // + val: Value(Scalar(0x00000005)) - // mir::Constant @@ -33,15 +40,14 @@ - StorageDead(_3); // bb0[6]: scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18 - StorageDead(_2); // bb0[7]: scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18 - StorageDead(_1); // bb0[8]: scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18 -- _0 = (); // bb0[9]: scope 0 at $DIR/ref_deref_project.rs:4:11: 6:2 +- _0 = const (); // bb0[9]: scope 0 at $DIR/ref_deref_project.rs:4:11: 6:2 +- // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/ref_deref_project.rs:4:11: 6:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } - return; // bb0[10]: scope 0 at $DIR/ref_deref_project.rs:6:2: 6:2 -+ // + span: $DIR/ref_deref_project.rs:5:6: 5:17 -+ // + literal: Const { ty: &(i32, i32), val: Unevaluated(DefId(0:3 ~ ref_deref_project[317d]::main[0]), [], Some(promoted[0])) } -+ _2 = &((*_4).1: i32); // bb0[3]: scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17 -+ _1 = (*_2); // bb0[4]: scope 0 at $DIR/ref_deref_project.rs:5:5: 5:17 -+ StorageDead(_2); // bb0[5]: scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18 -+ StorageDead(_1); // bb0[6]: scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18 -+ _0 = (); // bb0[7]: scope 0 at $DIR/ref_deref_project.rs:4:11: 6:2 + return; // bb0[8]: scope 0 at $DIR/ref_deref_project.rs:6:2: 6:2 } } diff --git a/src/test/mir-opt/const_prop/reify_fn_ptr/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/reify_fn_ptr/rustc.main.ConstProp.diff index 7a41a8ad74e..388ebe08689 100644 --- a/src/test/mir-opt/const_prop/reify_fn_ptr/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/reify_fn_ptr/rustc.main.ConstProp.diff @@ -25,7 +25,13 @@ _1 = move _2 as *const fn() (Misc); // bb0[6]: scope 0 at $DIR/reify_fn_ptr.rs:4:13: 4:41 StorageDead(_2); // bb0[7]: scope 0 at $DIR/reify_fn_ptr.rs:4:40: 4:41 StorageDead(_1); // bb0[8]: scope 0 at $DIR/reify_fn_ptr.rs:4:41: 4:42 - _0 = (); // bb0[9]: scope 0 at $DIR/reify_fn_ptr.rs:3:11: 5:2 + _0 = const (); // bb0[9]: scope 0 at $DIR/reify_fn_ptr.rs:3:11: 5:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/reify_fn_ptr.rs:3:11: 5:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } return; // bb0[10]: scope 0 at $DIR/reify_fn_ptr.rs:5:2: 5:2 } } diff --git a/src/test/mir-opt/const_prop/repeat/32bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/repeat/32bit/rustc.main.ConstProp.diff index 9d62fa31a45..921de794722 100644 --- a/src/test/mir-opt/const_prop/repeat/32bit/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/repeat/32bit/rustc.main.ConstProp.diff @@ -80,7 +80,13 @@ StorageDead(_2); // bb1[2]: scope 0 at $DIR/repeat.rs:6:31: 6:32 StorageDead(_4); // bb1[3]: scope 0 at $DIR/repeat.rs:6:32: 6:33 StorageDead(_3); // bb1[4]: scope 0 at $DIR/repeat.rs:6:32: 6:33 - _0 = (); // bb1[5]: scope 0 at $DIR/repeat.rs:5:11: 7:2 + _0 = const (); // bb1[5]: scope 0 at $DIR/repeat.rs:5:11: 7:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/repeat.rs:5:11: 7:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_1); // bb1[6]: scope 0 at $DIR/repeat.rs:7:1: 7:2 return; // bb1[7]: scope 0 at $DIR/repeat.rs:7:2: 7:2 } diff --git a/src/test/mir-opt/const_prop/repeat/64bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/repeat/64bit/rustc.main.ConstProp.diff index cb84ee82cfe..361ee493378 100644 --- a/src/test/mir-opt/const_prop/repeat/64bit/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/repeat/64bit/rustc.main.ConstProp.diff @@ -80,7 +80,13 @@ StorageDead(_2); // bb1[2]: scope 0 at $DIR/repeat.rs:6:31: 6:32 StorageDead(_4); // bb1[3]: scope 0 at $DIR/repeat.rs:6:32: 6:33 StorageDead(_3); // bb1[4]: scope 0 at $DIR/repeat.rs:6:32: 6:33 - _0 = (); // bb1[5]: scope 0 at $DIR/repeat.rs:5:11: 7:2 + _0 = const (); // bb1[5]: scope 0 at $DIR/repeat.rs:5:11: 7:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/repeat.rs:5:11: 7:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_1); // bb1[6]: scope 0 at $DIR/repeat.rs:7:1: 7:2 return; // bb1[7]: scope 0 at $DIR/repeat.rs:7:2: 7:2 } diff --git a/src/test/mir-opt/const_prop/slice_len/32bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/slice_len/32bit/rustc.main.ConstProp.diff index dbb4171e7f0..01818095455 100644 --- a/src/test/mir-opt/const_prop/slice_len/32bit/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/slice_len/32bit/rustc.main.ConstProp.diff @@ -76,7 +76,13 @@ StorageDead(_4); // bb1[2]: scope 0 at $DIR/slice_len.rs:5:33: 5:34 StorageDead(_2); // bb1[3]: scope 0 at $DIR/slice_len.rs:5:33: 5:34 StorageDead(_1); // bb1[4]: scope 0 at $DIR/slice_len.rs:5:33: 5:34 - _0 = (); // bb1[5]: scope 0 at $DIR/slice_len.rs:4:11: 6:2 + _0 = const (); // bb1[5]: scope 0 at $DIR/slice_len.rs:4:11: 6:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/slice_len.rs:4:11: 6:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } return; // bb1[6]: scope 0 at $DIR/slice_len.rs:6:2: 6:2 } } diff --git a/src/test/mir-opt/const_prop/slice_len/64bit/rustc.main.ConstProp.diff b/src/test/mir-opt/const_prop/slice_len/64bit/rustc.main.ConstProp.diff index 3c4415e0558..f1379446d7a 100644 --- a/src/test/mir-opt/const_prop/slice_len/64bit/rustc.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/slice_len/64bit/rustc.main.ConstProp.diff @@ -76,7 +76,13 @@ StorageDead(_4); // bb1[2]: scope 0 at $DIR/slice_len.rs:5:33: 5:34 StorageDead(_2); // bb1[3]: scope 0 at $DIR/slice_len.rs:5:33: 5:34 StorageDead(_1); // bb1[4]: scope 0 at $DIR/slice_len.rs:5:33: 5:34 - _0 = (); // bb1[5]: scope 0 at $DIR/slice_len.rs:4:11: 6:2 + _0 = const (); // bb1[5]: scope 0 at $DIR/slice_len.rs:4:11: 6:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/slice_len.rs:4:11: 6:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } return; // bb1[6]: scope 0 at $DIR/slice_len.rs:6:2: 6:2 } } diff --git a/src/test/mir-opt/copy_propagation_arg/rustc.bar.CopyPropagation.diff b/src/test/mir-opt/copy_propagation_arg/rustc.bar.CopyPropagation.diff index 8bdc91109b3..16bdb7d0a99 100644 --- a/src/test/mir-opt/copy_propagation_arg/rustc.bar.CopyPropagation.diff +++ b/src/test/mir-opt/copy_propagation_arg/rustc.bar.CopyPropagation.diff @@ -30,7 +30,13 @@ // mir::Constant // + span: $DIR/copy_propagation_arg.rs:17:5: 17:10 // + literal: Const { ty: u8, val: Value(Scalar(0x05)) } - nop; // bb1[3]: scope 0 at $DIR/copy_propagation_arg.rs:15:19: 18:2 + _0 = const (); // bb1[3]: scope 0 at $DIR/copy_propagation_arg.rs:15:19: 18:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/copy_propagation_arg.rs:15:19: 18:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } return; // bb1[4]: scope 0 at $DIR/copy_propagation_arg.rs:18:2: 18:2 } } diff --git a/src/test/mir-opt/copy_propagation_arg/rustc.baz.CopyPropagation.diff b/src/test/mir-opt/copy_propagation_arg/rustc.baz.CopyPropagation.diff index 10f2a98b206..7df995c990a 100644 --- a/src/test/mir-opt/copy_propagation_arg/rustc.baz.CopyPropagation.diff +++ b/src/test/mir-opt/copy_propagation_arg/rustc.baz.CopyPropagation.diff @@ -11,7 +11,13 @@ _2 = _1; // bb0[1]: scope 0 at $DIR/copy_propagation_arg.rs:23:9: 23:10 _1 = move _2; // bb0[2]: scope 0 at $DIR/copy_propagation_arg.rs:23:5: 23:10 StorageDead(_2); // bb0[3]: scope 0 at $DIR/copy_propagation_arg.rs:23:9: 23:10 - nop; // bb0[4]: scope 0 at $DIR/copy_propagation_arg.rs:21:20: 24:2 + _0 = const (); // bb0[4]: scope 0 at $DIR/copy_propagation_arg.rs:21:20: 24:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/copy_propagation_arg.rs:21:20: 24:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } return; // bb0[5]: scope 0 at $DIR/copy_propagation_arg.rs:24:2: 24:2 } } diff --git a/src/test/mir-opt/copy_propagation_arg/rustc.foo.CopyPropagation.diff b/src/test/mir-opt/copy_propagation_arg/rustc.foo.CopyPropagation.diff index a47880c540e..67b58c30f05 100644 --- a/src/test/mir-opt/copy_propagation_arg/rustc.foo.CopyPropagation.diff +++ b/src/test/mir-opt/copy_propagation_arg/rustc.foo.CopyPropagation.diff @@ -24,7 +24,13 @@ StorageDead(_3); // bb1[0]: scope 0 at $DIR/copy_propagation_arg.rs:11:16: 11:17 _1 = move _2; // bb1[1]: scope 0 at $DIR/copy_propagation_arg.rs:11:5: 11:17 StorageDead(_2); // bb1[2]: scope 0 at $DIR/copy_propagation_arg.rs:11:16: 11:17 - nop; // bb1[3]: scope 0 at $DIR/copy_propagation_arg.rs:9:19: 12:2 + _0 = const (); // bb1[3]: scope 0 at $DIR/copy_propagation_arg.rs:9:19: 12:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/copy_propagation_arg.rs:9:19: 12:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } return; // bb1[4]: scope 0 at $DIR/copy_propagation_arg.rs:12:2: 12:2 } } diff --git a/src/test/mir-opt/generator-storage-dead-unwind/rustc.main-{{closure}}.StateTransform.before.mir b/src/test/mir-opt/generator-storage-dead-unwind/rustc.main-{{closure}}.StateTransform.before.mir index cc22982a515..50a48f2eee4 100644 --- a/src/test/mir-opt/generator-storage-dead-unwind/rustc.main-{{closure}}.StateTransform.before.mir +++ b/src/test/mir-opt/generator-storage-dead-unwind/rustc.main-{{closure}}.StateTransform.before.mir @@ -112,7 +112,13 @@ yields () bb10: { StorageDead(_10); // bb10[0]: scope 2 at $DIR/generator-storage-dead-unwind.rs:27:15: 27:16 StorageDead(_9); // bb10[1]: scope 2 at $DIR/generator-storage-dead-unwind.rs:27:16: 27:17 - _0 = (); // bb10[2]: scope 0 at $DIR/generator-storage-dead-unwind.rs:22:19: 28:6 + _0 = const (); // bb10[2]: scope 0 at $DIR/generator-storage-dead-unwind.rs:22:19: 28:6 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/generator-storage-dead-unwind.rs:22:19: 28:6 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_4); // bb10[3]: scope 1 at $DIR/generator-storage-dead-unwind.rs:28:5: 28:6 StorageDead(_3); // bb10[4]: scope 0 at $DIR/generator-storage-dead-unwind.rs:28:5: 28:6 drop(_1) -> [return: bb12, unwind: bb1]; // bb10[5]: scope 0 at $DIR/generator-storage-dead-unwind.rs:28:5: 28:6 diff --git a/src/test/mir-opt/generator-tiny/rustc.main-{{closure}}.generator_resume.0.mir b/src/test/mir-opt/generator-tiny/rustc.main-{{closure}}.generator_resume.0.mir index a79f0d53f3c..2e3354699fb 100644 --- a/src/test/mir-opt/generator-tiny/rustc.main-{{closure}}.generator_resume.0.mir +++ b/src/test/mir-opt/generator-tiny/rustc.main-{{closure}}.generator_resume.0.mir @@ -54,7 +54,13 @@ fn main::{{closure}}#0(_1: std::pin::Pin<&mut [generator@$DIR/generator-tiny.rs: bb4: { StorageDead(_8); // bb4[0]: scope 1 at $DIR/generator-tiny.rs:22:21: 22:22 - _5 = (); // bb4[1]: scope 1 at $DIR/generator-tiny.rs:20:14: 23:10 + _5 = const (); // bb4[1]: scope 1 at $DIR/generator-tiny.rs:20:14: 23:10 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/generator-tiny.rs:20:14: 23:10 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } goto -> bb2; // bb4[2]: scope 1 at $DIR/generator-tiny.rs:20:9: 23:10 } diff --git a/src/test/mir-opt/graphviz/rustc.main.mir_map.0.dot b/src/test/mir-opt/graphviz/rustc.main.mir_map.0.dot index 2caef3459b8..f5d8b84812a 100644 --- a/src/test/mir-opt/graphviz/rustc.main.mir_map.0.dot +++ b/src/test/mir-opt/graphviz/rustc.main.mir_map.0.dot @@ -3,7 +3,7 @@ digraph Mir_0_3 { node [fontname="monospace"]; edge [fontname="monospace"]; label=<fn main() -> ()<br align="left"/>>; - bb0__0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">0</td></tr><tr><td align="left" balign="left">_0 = ()<br/></td></tr><tr><td align="left">goto</td></tr></table>>]; + bb0__0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">0</td></tr><tr><td align="left" balign="left">_0 = const ()<br/></td></tr><tr><td align="left">goto</td></tr></table>>]; bb1__0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">1</td></tr><tr><td align="left">resume</td></tr></table>>]; bb2__0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">2</td></tr><tr><td align="left">return</td></tr></table>>]; bb0__0_3 -> bb2__0_3 [label=""]; diff --git a/src/test/mir-opt/inline/inline-into-box-place.rs b/src/test/mir-opt/inline/inline-into-box-place.rs index d36d93cd01c..77834e9661c 100644 --- a/src/test/mir-opt/inline/inline-into-box-place.rs +++ b/src/test/mir-opt/inline/inline-into-box-place.rs @@ -1,6 +1,6 @@ // ignore-wasm32-bare compiled with panic=abort by default // compile-flags: -Z mir-opt-level=3 -// only-64bit FIXME: the mir representation of RawVec depends on ptr size +// EMIT_MIR_FOR_EACH_BIT_WIDTH #![feature(box_syntax)] // EMIT_MIR rustc.main.Inline.diff diff --git a/src/test/mir-opt/inline/inline-into-box-place/32bit/rustc.main.Inline.diff b/src/test/mir-opt/inline/inline-into-box-place/32bit/rustc.main.Inline.diff new file mode 100644 index 00000000000..6983e94ff8d --- /dev/null +++ b/src/test/mir-opt/inline/inline-into-box-place/32bit/rustc.main.Inline.diff @@ -0,0 +1,85 @@ +- // MIR for `main` before Inline ++ // MIR for `main` after Inline + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline-into-box-place.rs:7:11: 7:11 + let _1: std::boxed::Box<std::vec::Vec<u32>> as UserTypeProjection { base: UserType(0), projs: [] }; // in scope 0 at $DIR/inline-into-box-place.rs:8:9: 8:11 + let mut _2: std::boxed::Box<std::vec::Vec<u32>>; // in scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43 + let mut _3: (); // in scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43 ++ let mut _4: &mut std::vec::Vec<u32>; // in scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43 + scope 1 { + debug _x => _1; // in scope 1 at $DIR/inline-into-box-place.rs:8:9: 8:11 + } ++ scope 2 { ++ } + + bb0: { + StorageLive(_1); // bb0[0]: scope 0 at $DIR/inline-into-box-place.rs:8:9: 8:11 + StorageLive(_2); // bb0[1]: scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43 + _2 = Box(std::vec::Vec<u32>); // bb0[2]: scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43 +- (*_2) = const std::vec::Vec::<u32>::new() -> [return: bb2, unwind: bb4]; // bb0[3]: scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43 ++ _4 = &mut (*_2); // bb0[3]: scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43 ++ ((*_4).0: alloc::raw_vec::RawVec<u32>) = const ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), undef_mask: UndefMask { blocks: [255], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }: alloc::raw_vec::RawVec::<u32>; // bb0[4]: scope 2 at $SRC_DIR/liballoc/vec.rs:LL:COL + // ty::Const +- // + ty: fn() -> std::vec::Vec<u32> {std::vec::Vec::<u32>::new} +- // + val: Value(Scalar(<ZST>)) ++ // + ty: alloc::raw_vec::RawVec<u32> ++ // + val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), undef_mask: UndefMask { blocks: [255], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) + // mir::Constant +- // + span: $DIR/inline-into-box-place.rs:8:33: 8:41 +- // + user_ty: UserType(1) +- // + literal: Const { ty: fn() -> std::vec::Vec<u32> {std::vec::Vec::<u32>::new}, val: Value(Scalar(<ZST>)) } +- } +- +- bb1 (cleanup): { +- resume; // bb1[0]: scope 0 at $DIR/inline-into-box-place.rs:7:1: 9:2 +- } +- +- bb2: { +- _1 = move _2; // bb2[0]: scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43 +- StorageDead(_2); // bb2[1]: scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43 +- _0 = const (); // bb2[2]: scope 0 at $DIR/inline-into-box-place.rs:7:11: 9:2 ++ // + span: $SRC_DIR/liballoc/vec.rs:LL:COL ++ // + user_ty: UserType(0) ++ // + literal: Const { ty: alloc::raw_vec::RawVec<u32>, val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), undef_mask: UndefMask { blocks: [255], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) } ++ ((*_4).1: usize) = const 0usize; // bb0[5]: scope 2 at $SRC_DIR/liballoc/vec.rs:LL:COL + // ty::Const ++ // + ty: usize ++ // + val: Value(Scalar(0x00000000)) ++ // mir::Constant ++ // + span: $SRC_DIR/liballoc/vec.rs:LL:COL ++ // + literal: Const { ty: usize, val: Value(Scalar(0x00000000)) } ++ _1 = move _2; // bb0[6]: scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43 ++ StorageDead(_2); // bb0[7]: scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43 ++ _0 = const (); // bb0[8]: scope 0 at $DIR/inline-into-box-place.rs:7:11: 9:2 ++ // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/inline-into-box-place.rs:7:11: 9:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } +- drop(_1) -> [return: bb3, unwind: bb1]; // bb2[3]: scope 0 at $DIR/inline-into-box-place.rs:9:1: 9:2 ++ drop(_1) -> [return: bb2, unwind: bb1]; // bb0[9]: scope 0 at $DIR/inline-into-box-place.rs:9:1: 9:2 + } + +- bb3: { +- StorageDead(_1); // bb3[0]: scope 0 at $DIR/inline-into-box-place.rs:9:1: 9:2 +- return; // bb3[1]: scope 0 at $DIR/inline-into-box-place.rs:9:2: 9:2 ++ bb1 (cleanup): { ++ resume; // bb1[0]: scope 0 at $DIR/inline-into-box-place.rs:7:1: 9:2 + } + +- bb4 (cleanup): { +- _3 = const alloc::alloc::box_free::<std::vec::Vec<u32>>(move (_2.0: std::ptr::Unique<std::vec::Vec<u32>>)) -> bb1; // bb4[0]: scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43 +- // ty::Const +- // + ty: unsafe fn(std::ptr::Unique<std::vec::Vec<u32>>) {alloc::alloc::box_free::<std::vec::Vec<u32>>} +- // + val: Value(Scalar(<ZST>)) +- // mir::Constant +- // + span: $DIR/inline-into-box-place.rs:8:42: 8:43 +- // + literal: Const { ty: unsafe fn(std::ptr::Unique<std::vec::Vec<u32>>) {alloc::alloc::box_free::<std::vec::Vec<u32>>}, val: Value(Scalar(<ZST>)) } ++ bb2: { ++ StorageDead(_1); // bb2[0]: scope 0 at $DIR/inline-into-box-place.rs:9:1: 9:2 ++ return; // bb2[1]: scope 0 at $DIR/inline-into-box-place.rs:9:2: 9:2 + } + } + diff --git a/src/test/mir-opt/inline/inline-into-box-place/rustc.main.Inline.diff b/src/test/mir-opt/inline/inline-into-box-place/64bit/rustc.main.Inline.diff index a0db20cbb74..38ab9ce9926 100644 --- a/src/test/mir-opt/inline/inline-into-box-place/rustc.main.Inline.diff +++ b/src/test/mir-opt/inline/inline-into-box-place/64bit/rustc.main.Inline.diff @@ -29,11 +29,21 @@ - // + span: $DIR/inline-into-box-place.rs:8:33: 8:41 - // + user_ty: UserType(1) - // + literal: Const { ty: fn() -> std::vec::Vec<u32> {std::vec::Vec::<u32>::new}, val: Value(Scalar(<ZST>)) } +- } +- +- bb1 (cleanup): { +- resume; // bb1[0]: scope 0 at $DIR/inline-into-box-place.rs:7:1: 9:2 +- } +- +- bb2: { +- _1 = move _2; // bb2[0]: scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43 +- StorageDead(_2); // bb2[1]: scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43 +- _0 = const (); // bb2[2]: scope 0 at $DIR/inline-into-box-place.rs:7:11: 9:2 + // + span: $SRC_DIR/liballoc/vec.rs:LL:COL + // + user_ty: UserType(0) + // + literal: Const { ty: alloc::raw_vec::RawVec<u32>, val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), undef_mask: UndefMask { blocks: [65535], len: Size { raw: 16 } }, size: Size { raw: 16 }, align: Align { pow2: 3 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) } + ((*_4).1: usize) = const 0usize; // bb0[5]: scope 2 at $SRC_DIR/liballoc/vec.rs:LL:COL -+ // ty::Const + // ty::Const + // + ty: usize + // + val: Value(Scalar(0x0000000000000000)) + // mir::Constant @@ -41,26 +51,24 @@ + // + literal: Const { ty: usize, val: Value(Scalar(0x0000000000000000)) } + _1 = move _2; // bb0[6]: scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43 + StorageDead(_2); // bb0[7]: scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43 -+ _0 = (); // bb0[8]: scope 0 at $DIR/inline-into-box-place.rs:7:11: 9:2 ++ _0 = const (); // bb0[8]: scope 0 at $DIR/inline-into-box-place.rs:7:11: 9:2 ++ // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/inline-into-box-place.rs:7:11: 9:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } +- drop(_1) -> [return: bb3, unwind: bb1]; // bb2[3]: scope 0 at $DIR/inline-into-box-place.rs:9:1: 9:2 + drop(_1) -> [return: bb2, unwind: bb1]; // bb0[9]: scope 0 at $DIR/inline-into-box-place.rs:9:1: 9:2 } - bb1 (cleanup): { - resume; // bb1[0]: scope 0 at $DIR/inline-into-box-place.rs:7:1: 9:2 - } - - bb2: { -- _1 = move _2; // bb2[0]: scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43 -- StorageDead(_2); // bb2[1]: scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43 -- _0 = (); // bb2[2]: scope 0 at $DIR/inline-into-box-place.rs:7:11: 9:2 -- drop(_1) -> [return: bb3, unwind: bb1]; // bb2[3]: scope 0 at $DIR/inline-into-box-place.rs:9:1: 9:2 -- } -- - bb3: { - StorageDead(_1); // bb3[0]: scope 0 at $DIR/inline-into-box-place.rs:9:1: 9:2 - return; // bb3[1]: scope 0 at $DIR/inline-into-box-place.rs:9:2: 9:2 -- } -- ++ bb1 (cleanup): { ++ resume; // bb1[0]: scope 0 at $DIR/inline-into-box-place.rs:7:1: 9:2 + } + - bb4 (cleanup): { - _3 = const alloc::alloc::box_free::<std::vec::Vec<u32>>(move (_2.0: std::ptr::Unique<std::vec::Vec<u32>>)) -> bb1; // bb4[0]: scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43 - // ty::Const @@ -69,6 +77,7 @@ - // mir::Constant - // + span: $DIR/inline-into-box-place.rs:8:42: 8:43 - // + literal: Const { ty: unsafe fn(std::ptr::Unique<std::vec::Vec<u32>>) {alloc::alloc::box_free::<std::vec::Vec<u32>>}, val: Value(Scalar(<ZST>)) } ++ bb2: { + StorageDead(_1); // bb2[0]: scope 0 at $DIR/inline-into-box-place.rs:9:1: 9:2 + return; // bb2[1]: scope 0 at $DIR/inline-into-box-place.rs:9:2: 9:2 } diff --git a/src/test/mir-opt/inline/inline-specialization/rustc.main.Inline.diff b/src/test/mir-opt/inline/inline-specialization/rustc.main.Inline.diff index 98d03b19977..35c400035a6 100644 --- a/src/test/mir-opt/inline/inline-specialization/rustc.main.Inline.diff +++ b/src/test/mir-opt/inline/inline-specialization/rustc.main.Inline.diff @@ -25,12 +25,18 @@ - } - - bb1: { -- _0 = (); // bb1[0]: scope 0 at $DIR/inline-specialization.rs:4:11: 6:2 -- StorageDead(_1); // bb1[1]: scope 0 at $DIR/inline-specialization.rs:6:1: 6:2 -- return; // bb1[2]: scope 0 at $DIR/inline-specialization.rs:6:2: 6:2 +- _0 = const (); // bb1[0]: scope 0 at $DIR/inline-specialization.rs:4:11: 6:2 + // + span: $DIR/inline-specialization.rs:14:31: 14:34 + // + literal: Const { ty: u32, val: Value(Scalar(0x0000007b)) } -+ _0 = (); // bb0[2]: scope 0 at $DIR/inline-specialization.rs:4:11: 6:2 ++ _0 = const (); // bb0[2]: scope 0 at $DIR/inline-specialization.rs:4:11: 6:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/inline-specialization.rs:4:11: 6:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } +- StorageDead(_1); // bb1[1]: scope 0 at $DIR/inline-specialization.rs:6:1: 6:2 +- return; // bb1[2]: scope 0 at $DIR/inline-specialization.rs:6:2: 6:2 + StorageDead(_1); // bb0[3]: scope 0 at $DIR/inline-specialization.rs:6:1: 6:2 + return; // bb0[4]: scope 0 at $DIR/inline-specialization.rs:6:2: 6:2 } diff --git a/src/test/mir-opt/issue-38669/rustc.main.SimplifyCfg-initial.after.mir b/src/test/mir-opt/issue-38669/rustc.main.SimplifyCfg-initial.after.mir index 5144cdd3dab..62d2f8db7a4 100644 --- a/src/test/mir-opt/issue-38669/rustc.main.SimplifyCfg-initial.after.mir +++ b/src/test/mir-opt/issue-38669/rustc.main.SimplifyCfg-initial.after.mir @@ -45,7 +45,13 @@ fn main() -> () { } bb5: { - _3 = (); // bb5[0]: scope 1 at $DIR/issue-38669.rs:7:9: 9:10 + _3 = const (); // bb5[0]: scope 1 at $DIR/issue-38669.rs:7:9: 9:10 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/issue-38669.rs:7:9: 9:10 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_4); // bb5[1]: scope 1 at $DIR/issue-38669.rs:9:9: 9:10 StorageDead(_3); // bb5[2]: scope 1 at $DIR/issue-38669.rs:9:9: 9:10 _1 = const true; // bb5[3]: scope 1 at $DIR/issue-38669.rs:10:9: 10:28 @@ -55,12 +61,24 @@ fn main() -> () { // mir::Constant // + span: $DIR/issue-38669.rs:10:24: 10:28 // + literal: Const { ty: bool, val: Value(Scalar(0x01)) } - _2 = (); // bb5[4]: scope 1 at $DIR/issue-38669.rs:6:10: 11:6 + _2 = const (); // bb5[4]: scope 1 at $DIR/issue-38669.rs:6:10: 11:6 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/issue-38669.rs:6:10: 11:6 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } goto -> bb2; // bb5[5]: scope 1 at $DIR/issue-38669.rs:6:5: 11:6 } bb6: { - _0 = (); // bb6[0]: scope 1 at $DIR/issue-38669.rs:8:13: 8:18 + _0 = const (); // bb6[0]: scope 1 at $DIR/issue-38669.rs:8:13: 8:18 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/issue-38669.rs:8:13: 8:18 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_4); // bb6[1]: scope 1 at $DIR/issue-38669.rs:9:9: 9:10 StorageDead(_3); // bb6[2]: scope 1 at $DIR/issue-38669.rs:9:9: 9:10 StorageDead(_1); // bb6[3]: scope 0 at $DIR/issue-38669.rs:12:1: 12:2 diff --git a/src/test/mir-opt/issue-41110/rustc.main.ElaborateDrops.after.mir b/src/test/mir-opt/issue-41110/rustc.main.ElaborateDrops.after.mir index 0499054c329..55849b27732 100644 --- a/src/test/mir-opt/issue-41110/rustc.main.ElaborateDrops.after.mir +++ b/src/test/mir-opt/issue-41110/rustc.main.ElaborateDrops.after.mir @@ -85,7 +85,13 @@ fn main() -> () { // + span: $DIR/issue-41110.rs:8:27: 8:28 // + literal: Const { ty: bool, val: Value(Scalar(0x00)) } StorageDead(_2); // bb6[2]: scope 0 at $DIR/issue-41110.rs:8:27: 8:28 - _0 = (); // bb6[3]: scope 0 at $DIR/issue-41110.rs:7:11: 9:2 + _0 = const (); // bb6[3]: scope 0 at $DIR/issue-41110.rs:7:11: 9:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/issue-41110.rs:7:11: 9:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_1); // bb6[4]: scope 0 at $DIR/issue-41110.rs:9:1: 9:2 return; // bb6[5]: scope 0 at $DIR/issue-41110.rs:9:2: 9:2 } diff --git a/src/test/mir-opt/issue-41110/rustc.test.ElaborateDrops.after.mir b/src/test/mir-opt/issue-41110/rustc.test.ElaborateDrops.after.mir index b6623fcd4d9..cc1a49dd245 100644 --- a/src/test/mir-opt/issue-41110/rustc.test.ElaborateDrops.after.mir +++ b/src/test/mir-opt/issue-41110/rustc.test.ElaborateDrops.after.mir @@ -87,7 +87,13 @@ fn test() -> () { bb8: { StorageDead(_5); // bb8[0]: scope 2 at $DIR/issue-41110.rs:18:9: 18:10 - _0 = (); // bb8[1]: scope 0 at $DIR/issue-41110.rs:14:15: 19:2 + _0 = const (); // bb8[1]: scope 0 at $DIR/issue-41110.rs:14:15: 19:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/issue-41110.rs:14:15: 19:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } drop(_2) -> [return: bb9, unwind: bb3]; // bb8[2]: scope 1 at $DIR/issue-41110.rs:19:1: 19:2 } diff --git a/src/test/mir-opt/issue-41888/rustc.main.ElaborateDrops.after.mir b/src/test/mir-opt/issue-41888/rustc.main.ElaborateDrops.after.mir index 6cd3e2dec83..ee05bf48d62 100644 --- a/src/test/mir-opt/issue-41888/rustc.main.ElaborateDrops.after.mir +++ b/src/test/mir-opt/issue-41888/rustc.main.ElaborateDrops.after.mir @@ -66,7 +66,13 @@ fn main() -> () { } bb4: { - _0 = (); // bb4[0]: scope 1 at $DIR/issue-41888.rs:8:5: 14:6 + _0 = const (); // bb4[0]: scope 1 at $DIR/issue-41888.rs:8:5: 14:6 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/issue-41888.rs:8:5: 14:6 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } goto -> bb11; // bb4[1]: scope 1 at $DIR/issue-41888.rs:8:5: 14:6 } @@ -94,7 +100,13 @@ fn main() -> () { } bb9: { - _0 = (); // bb9[0]: scope 1 at $DIR/issue-41888.rs:10:9: 13:10 + _0 = const (); // bb9[0]: scope 1 at $DIR/issue-41888.rs:10:9: 13:10 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/issue-41888.rs:10:9: 13:10 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } goto -> bb11; // bb9[1]: scope 1 at $DIR/issue-41888.rs:10:9: 13:10 } @@ -108,7 +120,13 @@ fn main() -> () { // + span: $DIR/issue-41888.rs:10:21: 10:23 // + literal: Const { ty: bool, val: Value(Scalar(0x00)) } _6 = move ((_1 as F).0: K); // bb10[2]: scope 1 at $DIR/issue-41888.rs:10:21: 10:23 - _0 = (); // bb10[3]: scope 2 at $DIR/issue-41888.rs:10:29: 13:10 + _0 = const (); // bb10[3]: scope 2 at $DIR/issue-41888.rs:10:29: 13:10 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/issue-41888.rs:10:29: 13:10 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_6); // bb10[4]: scope 1 at $DIR/issue-41888.rs:13:9: 13:10 goto -> bb11; // bb10[5]: scope 1 at $DIR/issue-41888.rs:10:9: 13:10 } diff --git a/src/test/mir-opt/issue-49232/rustc.main.mir_map.0.mir b/src/test/mir-opt/issue-49232/rustc.main.mir_map.0.mir index 03815d58bbc..5440d4488bb 100644 --- a/src/test/mir-opt/issue-49232/rustc.main.mir_map.0.mir +++ b/src/test/mir-opt/issue-49232/rustc.main.mir_map.0.mir @@ -47,7 +47,13 @@ fn main() -> () { } bb6: { - _0 = (); // bb6[0]: scope 0 at $DIR/issue-49232.rs:10:25: 10:30 + _0 = const (); // bb6[0]: scope 0 at $DIR/issue-49232.rs:10:25: 10:30 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/issue-49232.rs:10:25: 10:30 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } goto -> bb8; // bb6[1]: scope 0 at $DIR/issue-49232.rs:10:25: 10:30 } @@ -73,7 +79,13 @@ fn main() -> () { } bb10: { - _4 = (); // bb10[0]: scope 0 at $DIR/issue-49232.rs:10:25: 10:30 + _4 = const (); // bb10[0]: scope 0 at $DIR/issue-49232.rs:10:25: 10:30 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/issue-49232.rs:10:25: 10:30 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } unreachable; // bb10[1]: scope 0 at $DIR/issue-49232.rs:10:25: 10:30 } @@ -99,7 +111,13 @@ fn main() -> () { bb13: { StorageDead(_6); // bb13[0]: scope 1 at $DIR/issue-49232.rs:13:21: 13:22 StorageDead(_5); // bb13[1]: scope 1 at $DIR/issue-49232.rs:13:22: 13:23 - _1 = (); // bb13[2]: scope 0 at $DIR/issue-49232.rs:6:10: 14:6 + _1 = const (); // bb13[2]: scope 0 at $DIR/issue-49232.rs:6:10: 14:6 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/issue-49232.rs:6:10: 14:6 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_2); // bb13[3]: scope 0 at $DIR/issue-49232.rs:14:5: 14:6 goto -> bb1; // bb13[4]: scope 0 at $DIR/issue-49232.rs:6:5: 14:6 } diff --git a/src/test/mir-opt/loop_test/rustc.main.SimplifyCfg-qualify-consts.after.mir b/src/test/mir-opt/loop_test/rustc.main.SimplifyCfg-qualify-consts.after.mir index c458592e920..df05dbabc77 100644 --- a/src/test/mir-opt/loop_test/rustc.main.SimplifyCfg-qualify-consts.after.mir +++ b/src/test/mir-opt/loop_test/rustc.main.SimplifyCfg-qualify-consts.after.mir @@ -35,7 +35,13 @@ fn main() -> () { } bb3: { - _1 = (); // bb3[0]: scope 0 at $DIR/loop_test.rs:10:5: 12:6 + _1 = const (); // bb3[0]: scope 0 at $DIR/loop_test.rs:10:5: 12:6 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/loop_test.rs:10:5: 12:6 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_2); // bb3[1]: scope 0 at $DIR/loop_test.rs:12:5: 12:6 StorageDead(_1); // bb3[2]: scope 0 at $DIR/loop_test.rs:12:5: 12:6 StorageLive(_4); // bb3[3]: scope 0 at $DIR/loop_test.rs:13:5: 16:6 @@ -43,7 +49,13 @@ fn main() -> () { } bb4: { - _0 = (); // bb4[0]: scope 0 at $DIR/loop_test.rs:11:9: 11:15 + _0 = const (); // bb4[0]: scope 0 at $DIR/loop_test.rs:11:9: 11:15 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/loop_test.rs:11:9: 11:15 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_2); // bb4[1]: scope 0 at $DIR/loop_test.rs:12:5: 12:6 StorageDead(_1); // bb4[2]: scope 0 at $DIR/loop_test.rs:12:5: 12:6 return; // bb4[3]: scope 0 at $DIR/loop_test.rs:17:2: 17:2 diff --git a/src/test/mir-opt/match_false_edges/rustc.full_tested_match.PromoteTemps.after.mir b/src/test/mir-opt/match_false_edges/rustc.full_tested_match.PromoteTemps.after.mir index acc03cce46e..a296bd05312 100644 --- a/src/test/mir-opt/match_false_edges/rustc.full_tested_match.PromoteTemps.after.mir +++ b/src/test/mir-opt/match_false_edges/rustc.full_tested_match.PromoteTemps.after.mir @@ -143,7 +143,13 @@ fn full_tested_match() -> () { bb11: { StorageDead(_2); // bb11[0]: scope 0 at $DIR/match_false_edges.rs:19:6: 19:7 StorageDead(_1); // bb11[1]: scope 0 at $DIR/match_false_edges.rs:19:6: 19:7 - _0 = (); // bb11[2]: scope 0 at $DIR/match_false_edges.rs:14:28: 20:2 + _0 = const (); // bb11[2]: scope 0 at $DIR/match_false_edges.rs:14:28: 20:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/match_false_edges.rs:14:28: 20:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } return; // bb11[3]: scope 0 at $DIR/match_false_edges.rs:20:2: 20:2 } } diff --git a/src/test/mir-opt/match_false_edges/rustc.full_tested_match2.PromoteTemps.before.mir b/src/test/mir-opt/match_false_edges/rustc.full_tested_match2.PromoteTemps.before.mir index cc1fa562645..567e3ebdd93 100644 --- a/src/test/mir-opt/match_false_edges/rustc.full_tested_match2.PromoteTemps.before.mir +++ b/src/test/mir-opt/match_false_edges/rustc.full_tested_match2.PromoteTemps.before.mir @@ -135,7 +135,13 @@ fn full_tested_match2() -> () { bb11: { StorageDead(_2); // bb11[0]: scope 0 at $DIR/match_false_edges.rs:30:6: 30:7 StorageDead(_1); // bb11[1]: scope 0 at $DIR/match_false_edges.rs:30:6: 30:7 - _0 = (); // bb11[2]: scope 0 at $DIR/match_false_edges.rs:25:29: 31:2 + _0 = const (); // bb11[2]: scope 0 at $DIR/match_false_edges.rs:25:29: 31:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/match_false_edges.rs:25:29: 31:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } return; // bb11[3]: scope 0 at $DIR/match_false_edges.rs:31:2: 31:2 } } diff --git a/src/test/mir-opt/match_false_edges/rustc.main.PromoteTemps.before.mir b/src/test/mir-opt/match_false_edges/rustc.main.PromoteTemps.before.mir index fce497df982..a24fa9dedb3 100644 --- a/src/test/mir-opt/match_false_edges/rustc.main.PromoteTemps.before.mir +++ b/src/test/mir-opt/match_false_edges/rustc.main.PromoteTemps.before.mir @@ -182,7 +182,13 @@ fn main() -> () { bb15: { StorageDead(_2); // bb15[0]: scope 0 at $DIR/match_false_edges.rs:40:6: 40:7 StorageDead(_1); // bb15[1]: scope 0 at $DIR/match_false_edges.rs:40:6: 40:7 - _0 = (); // bb15[2]: scope 0 at $DIR/match_false_edges.rs:34:11: 41:2 + _0 = const (); // bb15[2]: scope 0 at $DIR/match_false_edges.rs:34:11: 41:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/match_false_edges.rs:34:11: 41:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } return; // bb15[3]: scope 0 at $DIR/match_false_edges.rs:41:2: 41:2 } } diff --git a/src/test/mir-opt/match_test/rustc.main.SimplifyCfg-initial.after.mir b/src/test/mir-opt/match_test/rustc.main.SimplifyCfg-initial.after.mir index ef5feb79bec..3236b3bcc73 100644 --- a/src/test/mir-opt/match_test/rustc.main.SimplifyCfg-initial.after.mir +++ b/src/test/mir-opt/match_test/rustc.main.SimplifyCfg-initial.after.mir @@ -158,7 +158,13 @@ fn main() -> () { bb14: { StorageDead(_3); // bb14[0]: scope 2 at $DIR/match_test.rs:17:6: 17:7 - _0 = (); // bb14[1]: scope 0 at $DIR/match_test.rs:6:11: 18:2 + _0 = const (); // bb14[1]: scope 0 at $DIR/match_test.rs:6:11: 18:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/match_test.rs:6:11: 18:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_2); // bb14[2]: scope 1 at $DIR/match_test.rs:18:1: 18:2 StorageDead(_1); // bb14[3]: scope 0 at $DIR/match_test.rs:18:1: 18:2 return; // bb14[4]: scope 0 at $DIR/match_test.rs:18:2: 18:2 diff --git a/src/test/mir-opt/nll/region-subtyping-basic/32bit/rustc.main.nll.0.mir b/src/test/mir-opt/nll/region-subtyping-basic/32bit/rustc.main.nll.0.mir index 1f75658aa26..7d396c3f1fb 100644 --- a/src/test/mir-opt/nll/region-subtyping-basic/32bit/rustc.main.nll.0.mir +++ b/src/test/mir-opt/nll/region-subtyping-basic/32bit/rustc.main.nll.0.mir @@ -137,13 +137,25 @@ fn main() -> () { bb6: { StorageDead(_9); // bb6[0]: scope 3 at $DIR/region-subtyping-basic.rs:19:17: 19:18 StorageDead(_8); // bb6[1]: scope 3 at $DIR/region-subtyping-basic.rs:19:18: 19:19 - _0 = (); // bb6[2]: scope 3 at $DIR/region-subtyping-basic.rs:18:13: 20:6 + _0 = const Const(Value(Scalar(<ZST>)): ()); // bb6[2]: scope 3 at $DIR/region-subtyping-basic.rs:18:13: 20:6 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/region-subtyping-basic.rs:18:13: 20:6 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } goto -> bb8; // bb6[3]: scope 3 at $DIR/region-subtyping-basic.rs:18:5: 22:6 } bb7: { StorageDead(_10); // bb7[0]: scope 3 at $DIR/region-subtyping-basic.rs:21:18: 21:19 - _0 = (); // bb7[1]: scope 3 at $DIR/region-subtyping-basic.rs:20:12: 22:6 + _0 = const Const(Value(Scalar(<ZST>)): ()); // bb7[1]: scope 3 at $DIR/region-subtyping-basic.rs:20:12: 22:6 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/region-subtyping-basic.rs:20:12: 22:6 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } goto -> bb8; // bb7[2]: scope 3 at $DIR/region-subtyping-basic.rs:18:5: 22:6 } diff --git a/src/test/mir-opt/nll/region-subtyping-basic/64bit/rustc.main.nll.0.mir b/src/test/mir-opt/nll/region-subtyping-basic/64bit/rustc.main.nll.0.mir index 8305c3fe7c4..4a285d035be 100644 --- a/src/test/mir-opt/nll/region-subtyping-basic/64bit/rustc.main.nll.0.mir +++ b/src/test/mir-opt/nll/region-subtyping-basic/64bit/rustc.main.nll.0.mir @@ -137,13 +137,25 @@ fn main() -> () { bb6: { StorageDead(_9); // bb6[0]: scope 3 at $DIR/region-subtyping-basic.rs:19:17: 19:18 StorageDead(_8); // bb6[1]: scope 3 at $DIR/region-subtyping-basic.rs:19:18: 19:19 - _0 = (); // bb6[2]: scope 3 at $DIR/region-subtyping-basic.rs:18:13: 20:6 + _0 = const Const(Value(Scalar(<ZST>)): ()); // bb6[2]: scope 3 at $DIR/region-subtyping-basic.rs:18:13: 20:6 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/region-subtyping-basic.rs:18:13: 20:6 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } goto -> bb8; // bb6[3]: scope 3 at $DIR/region-subtyping-basic.rs:18:5: 22:6 } bb7: { StorageDead(_10); // bb7[0]: scope 3 at $DIR/region-subtyping-basic.rs:21:18: 21:19 - _0 = (); // bb7[1]: scope 3 at $DIR/region-subtyping-basic.rs:20:12: 22:6 + _0 = const Const(Value(Scalar(<ZST>)): ()); // bb7[1]: scope 3 at $DIR/region-subtyping-basic.rs:20:12: 22:6 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/region-subtyping-basic.rs:20:12: 22:6 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } goto -> bb8; // bb7[2]: scope 3 at $DIR/region-subtyping-basic.rs:18:5: 22:6 } diff --git a/src/test/mir-opt/no-spurious-drop-after-call/rustc.main.ElaborateDrops.before.mir b/src/test/mir-opt/no-spurious-drop-after-call/rustc.main.ElaborateDrops.before.mir index b65bc760330..e43e37feba7 100644 --- a/src/test/mir-opt/no-spurious-drop-after-call/rustc.main.ElaborateDrops.before.mir +++ b/src/test/mir-opt/no-spurious-drop-after-call/rustc.main.ElaborateDrops.before.mir @@ -48,7 +48,13 @@ fn main() -> () { StorageDead(_2); // bb3[0]: scope 0 at $DIR/no-spurious-drop-after-call.rs:9:34: 9:35 StorageDead(_4); // bb3[1]: scope 0 at $DIR/no-spurious-drop-after-call.rs:9:35: 9:36 StorageDead(_1); // bb3[2]: scope 0 at $DIR/no-spurious-drop-after-call.rs:9:35: 9:36 - _0 = (); // bb3[3]: scope 0 at $DIR/no-spurious-drop-after-call.rs:8:11: 10:2 + _0 = const (); // bb3[3]: scope 0 at $DIR/no-spurious-drop-after-call.rs:8:11: 10:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/no-spurious-drop-after-call.rs:8:11: 10:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } return; // bb3[4]: scope 0 at $DIR/no-spurious-drop-after-call.rs:10:2: 10:2 } diff --git a/src/test/mir-opt/packed-struct-drop-aligned/32bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/packed-struct-drop-aligned/32bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir index 03265c613bc..cea10872942 100644 --- a/src/test/mir-opt/packed-struct-drop-aligned/32bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/packed-struct-drop-aligned/32bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir @@ -61,7 +61,13 @@ fn main() -> () { StorageDead(_6); // bb4[0]: scope 1 at $DIR/packed-struct-drop-aligned.rs:7:5: 7:8 (_1.0: Aligned) = move _4; // bb4[1]: scope 1 at $DIR/packed-struct-drop-aligned.rs:7:5: 7:8 StorageDead(_4); // bb4[2]: scope 1 at $DIR/packed-struct-drop-aligned.rs:7:28: 7:29 - _0 = (); // bb4[3]: scope 0 at $DIR/packed-struct-drop-aligned.rs:5:11: 8:2 + _0 = const (); // bb4[3]: scope 0 at $DIR/packed-struct-drop-aligned.rs:5:11: 8:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/packed-struct-drop-aligned.rs:5:11: 8:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } drop(_1) -> [return: bb2, unwind: bb1]; // bb4[4]: scope 0 at $DIR/packed-struct-drop-aligned.rs:8:1: 8:2 } } diff --git a/src/test/mir-opt/packed-struct-drop-aligned/64bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/packed-struct-drop-aligned/64bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir index a1424d0bf59..432f91d91e5 100644 --- a/src/test/mir-opt/packed-struct-drop-aligned/64bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/packed-struct-drop-aligned/64bit/rustc.main.SimplifyCfg-elaborate-drops.after.mir @@ -61,7 +61,13 @@ fn main() -> () { StorageDead(_6); // bb4[0]: scope 1 at $DIR/packed-struct-drop-aligned.rs:7:5: 7:8 (_1.0: Aligned) = move _4; // bb4[1]: scope 1 at $DIR/packed-struct-drop-aligned.rs:7:5: 7:8 StorageDead(_4); // bb4[2]: scope 1 at $DIR/packed-struct-drop-aligned.rs:7:28: 7:29 - _0 = (); // bb4[3]: scope 0 at $DIR/packed-struct-drop-aligned.rs:5:11: 8:2 + _0 = const (); // bb4[3]: scope 0 at $DIR/packed-struct-drop-aligned.rs:5:11: 8:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/packed-struct-drop-aligned.rs:5:11: 8:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } drop(_1) -> [return: bb2, unwind: bb1]; // bb4[4]: scope 0 at $DIR/packed-struct-drop-aligned.rs:8:1: 8:2 } } diff --git a/src/test/mir-opt/retag/rustc.main.SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/retag/rustc.main.SimplifyCfg-elaborate-drops.after.mir index 780cb9d4ad5..727c271a478 100644 --- a/src/test/mir-opt/retag/rustc.main.SimplifyCfg-elaborate-drops.after.mir +++ b/src/test/mir-opt/retag/rustc.main.SimplifyCfg-elaborate-drops.after.mir @@ -125,7 +125,13 @@ fn main() -> () { Retag([raw] _12); // bb4[14]: scope 4 at $DIR/retag.rs:36:18: 36:19 _11 = _12; // bb4[15]: scope 4 at $DIR/retag.rs:36:18: 36:29 StorageDead(_12); // bb4[16]: scope 4 at $DIR/retag.rs:36:29: 36:30 - _2 = (); // bb4[17]: scope 1 at $DIR/retag.rs:31:5: 37:6 + _2 = const (); // bb4[17]: scope 1 at $DIR/retag.rs:31:5: 37:6 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/retag.rs:31:5: 37:6 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_11); // bb4[18]: scope 4 at $DIR/retag.rs:37:5: 37:6 StorageDead(_10); // bb4[19]: scope 3 at $DIR/retag.rs:37:5: 37:6 StorageDead(_8); // bb4[20]: scope 2 at $DIR/retag.rs:37:5: 37:6 @@ -217,7 +223,13 @@ fn main() -> () { Retag([raw] _26); // bb8[5]: scope 7 at $DIR/retag.rs:50:14: 50:16 _25 = _26; // bb8[6]: scope 7 at $DIR/retag.rs:50:14: 50:28 StorageDead(_26); // bb8[7]: scope 7 at $DIR/retag.rs:50:28: 50:29 - _0 = (); // bb8[8]: scope 0 at $DIR/retag.rs:29:11: 51:2 + _0 = const (); // bb8[8]: scope 0 at $DIR/retag.rs:29:11: 51:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/retag.rs:29:11: 51:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_25); // bb8[9]: scope 7 at $DIR/retag.rs:51:1: 51:2 StorageDead(_15); // bb8[10]: scope 6 at $DIR/retag.rs:51:1: 51:2 StorageDead(_13); // bb8[11]: scope 1 at $DIR/retag.rs:51:1: 51:2 diff --git a/src/test/mir-opt/simplify-arm-identity/rustc.main.SimplifyArmIdentity.diff b/src/test/mir-opt/simplify-arm-identity/rustc.main.SimplifyArmIdentity.diff index 32338127923..2caa6235d54 100644 --- a/src/test/mir-opt/simplify-arm-identity/rustc.main.SimplifyArmIdentity.diff +++ b/src/test/mir-opt/simplify-arm-identity/rustc.main.SimplifyArmIdentity.diff @@ -57,8 +57,15 @@ bb4: { StorageDead(_2); // bb4[0]: scope 1 at $DIR/simplify-arm-identity.rs:21:6: 21:7 - StorageDead(_1); // bb4[1]: scope 0 at $DIR/simplify-arm-identity.rs:22:1: 22:2 - return; // bb4[2]: scope 0 at $DIR/simplify-arm-identity.rs:22:2: 22:2 + _0 = const (); // bb4[1]: scope 0 at $DIR/simplify-arm-identity.rs:16:11: 22:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/simplify-arm-identity.rs:16:11: 22:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } + StorageDead(_1); // bb4[2]: scope 0 at $DIR/simplify-arm-identity.rs:22:1: 22:2 + return; // bb4[3]: scope 0 at $DIR/simplify-arm-identity.rs:22:2: 22:2 } } diff --git a/src/test/mir-opt/simplify-locals-fixedpoint.rs b/src/test/mir-opt/simplify-locals-fixedpoint.rs new file mode 100644 index 00000000000..aa5bc345359 --- /dev/null +++ b/src/test/mir-opt/simplify-locals-fixedpoint.rs @@ -0,0 +1,15 @@ +// compile-flags: -Zmir-opt-level=1 + +fn foo<T>() { + if let (Some(a), None) = (Option::<u8>::None, Option::<T>::None) { + if a > 42u8 { + + } + } +} + +fn main() { + foo::<()>(); +} + +// EMIT_MIR rustc.foo.SimplifyLocals.diff diff --git a/src/test/mir-opt/simplify-locals-fixedpoint/rustc.foo.SimplifyLocals.diff b/src/test/mir-opt/simplify-locals-fixedpoint/rustc.foo.SimplifyLocals.diff new file mode 100644 index 00000000000..bc59be48eee --- /dev/null +++ b/src/test/mir-opt/simplify-locals-fixedpoint/rustc.foo.SimplifyLocals.diff @@ -0,0 +1,102 @@ +- // MIR for `foo` before SimplifyLocals ++ // MIR for `foo` after SimplifyLocals + + fn foo() -> () { + let mut _0: (); // return place in scope 0 at $DIR/simplify-locals-fixedpoint.rs:3:13: 3:13 + let mut _1: (std::option::Option<u8>, std::option::Option<T>); // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:30: 4:69 + let mut _2: std::option::Option<u8>; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:31: 4:49 + let mut _3: std::option::Option<T>; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:51: 4:68 + let mut _4: isize; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:22: 4:26 + let mut _5: isize; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:13: 4:20 + let _6: u8; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:18: 4:19 + let mut _7: bool; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:20 + let mut _8: u8; // in scope 0 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:13 + scope 1 { + debug a => _6; // in scope 1 at $DIR/simplify-locals-fixedpoint.rs:4:18: 4:19 + } + + bb0: { + StorageLive(_1); // bb0[0]: scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:30: 4:69 + StorageLive(_2); // bb0[1]: scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:31: 4:49 + discriminant(_2) = 0; // bb0[2]: scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:31: 4:49 + StorageLive(_3); // bb0[3]: scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:51: 4:68 + discriminant(_3) = 0; // bb0[4]: scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:51: 4:68 + (_1.0: std::option::Option<u8>) = move _2; // bb0[5]: scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:30: 4:69 + (_1.1: std::option::Option<T>) = move _3; // bb0[6]: scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:30: 4:69 + StorageDead(_3); // bb0[7]: scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:68: 4:69 + StorageDead(_2); // bb0[8]: scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:68: 4:69 + _5 = discriminant((_1.0: std::option::Option<u8>)); // bb0[9]: scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:13: 4:20 + switchInt(move _5) -> [1isize: bb2, otherwise: bb1]; // bb0[10]: scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:13: 4:20 + } + + bb1: { + _0 = const (); // bb1[0]: scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:5: 8:6 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/simplify-locals-fixedpoint.rs:4:5: 8:6 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } + goto -> bb7; // bb1[1]: scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:5: 8:6 + } + + bb2: { + _4 = discriminant((_1.1: std::option::Option<T>)); // bb2[0]: scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:22: 4:26 + switchInt(move _4) -> [0isize: bb3, otherwise: bb1]; // bb2[1]: scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:22: 4:26 + } + + bb3: { + StorageLive(_6); // bb3[0]: scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:18: 4:19 + _6 = (((_1.0: std::option::Option<u8>) as Some).0: u8); // bb3[1]: scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:18: 4:19 + StorageLive(_7); // bb3[2]: scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:20 + StorageLive(_8); // bb3[3]: scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:13 + _8 = _6; // bb3[4]: scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:13 + _7 = Gt(move _8, const 42u8); // bb3[5]: scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:12: 5:20 + // ty::Const + // + ty: u8 + // + val: Value(Scalar(0x2a)) + // mir::Constant + // + span: $DIR/simplify-locals-fixedpoint.rs:5:16: 5:20 + // + literal: Const { ty: u8, val: Value(Scalar(0x2a)) } + StorageDead(_8); // bb3[6]: scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:19: 5:20 + switchInt(_7) -> [false: bb4, otherwise: bb5]; // bb3[7]: scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:9: 7:10 + } + + bb4: { + _0 = const (); // bb4[0]: scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:9: 7:10 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/simplify-locals-fixedpoint.rs:5:9: 7:10 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } + goto -> bb6; // bb4[1]: scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:9: 7:10 + } + + bb5: { + _0 = const (); // bb5[0]: scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:21: 7:10 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/simplify-locals-fixedpoint.rs:5:21: 7:10 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } + goto -> bb6; // bb5[1]: scope 1 at $DIR/simplify-locals-fixedpoint.rs:5:9: 7:10 + } + + bb6: { + StorageDead(_7); // bb6[0]: scope 1 at $DIR/simplify-locals-fixedpoint.rs:8:5: 8:6 + StorageDead(_6); // bb6[1]: scope 0 at $DIR/simplify-locals-fixedpoint.rs:8:5: 8:6 + goto -> bb7; // bb6[2]: scope 0 at $DIR/simplify-locals-fixedpoint.rs:4:5: 8:6 + } + + bb7: { + drop(_1) -> bb8; // bb7[0]: scope 0 at $DIR/simplify-locals-fixedpoint.rs:9:1: 9:2 + } + + bb8: { + StorageDead(_1); // bb8[0]: scope 0 at $DIR/simplify-locals-fixedpoint.rs:9:1: 9:2 + return; // bb8[1]: scope 0 at $DIR/simplify-locals-fixedpoint.rs:9:2: 9:2 + } + } + diff --git a/src/test/mir-opt/simplify-locals-removes-unused-consts/rustc.main.SimplifyLocals.diff b/src/test/mir-opt/simplify-locals-removes-unused-consts/rustc.main.SimplifyLocals.diff index 15deb3e31bd..8613a812a83 100644 --- a/src/test/mir-opt/simplify-locals-removes-unused-consts/rustc.main.SimplifyLocals.diff +++ b/src/test/mir-opt/simplify-locals-removes-unused-consts/rustc.main.SimplifyLocals.diff @@ -124,9 +124,17 @@ bb2: { - StorageDead(_11); // bb2[0]: scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:35: 16:36 - StorageDead(_8); // bb2[1]: scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:35: 16:36 -- return; // bb2[2]: scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:17:2: 17:2 +- _0 = const (); // bb2[2]: scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:12:11: 17:2 + StorageDead(_2); // bb2[0]: scope 1 at $DIR/simplify-locals-removes-unused-consts.rs:16:35: 16:36 -+ return; // bb2[1]: scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:17:2: 17:2 ++ _0 = const (); // bb2[1]: scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:12:11: 17:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/simplify-locals-removes-unused-consts.rs:12:11: 17:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } +- return; // bb2[3]: scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:17:2: 17:2 ++ return; // bb2[2]: scope 0 at $DIR/simplify-locals-removes-unused-consts.rs:17:2: 17:2 } } diff --git a/src/test/mir-opt/simplify_cfg/rustc.main.SimplifyCfg-early-opt.diff b/src/test/mir-opt/simplify_cfg/rustc.main.SimplifyCfg-early-opt.diff index 9225bcd0b65..ecac835fb87 100644 --- a/src/test/mir-opt/simplify_cfg/rustc.main.SimplifyCfg-early-opt.diff +++ b/src/test/mir-opt/simplify_cfg/rustc.main.SimplifyCfg-early-opt.diff @@ -33,28 +33,40 @@ - bb3: { - nop; // bb3[0]: scope 0 at $DIR/simplify_cfg.rs:7:12: 7:17 - switchInt(_2) -> [false: bb5, otherwise: bb4]; // bb3[1]: scope 0 at $DIR/simplify_cfg.rs:7:9: 9:10 -+ bb2: { -+ _1 = (); // bb2[0]: scope 0 at $DIR/simplify_cfg.rs:7:9: 9:10 -+ StorageDead(_2); // bb2[1]: scope 0 at $DIR/simplify_cfg.rs:10:5: 10:6 -+ goto -> bb0; // bb2[2]: scope 0 at $DIR/simplify_cfg.rs:6:5: 10:6 - } - +- } +- - bb4: { - goto -> bb6; // bb4[0]: scope 0 at $DIR/simplify_cfg.rs:7:9: 9:10 - } - - bb5: { -- _1 = (); // bb5[0]: scope 0 at $DIR/simplify_cfg.rs:7:9: 9:10 +- _1 = const (); // bb5[0]: scope 0 at $DIR/simplify_cfg.rs:7:9: 9:10 ++ bb2: { ++ _1 = const (); // bb2[0]: scope 0 at $DIR/simplify_cfg.rs:7:9: 9:10 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/simplify_cfg.rs:7:9: 9:10 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } - StorageDead(_2); // bb5[1]: scope 0 at $DIR/simplify_cfg.rs:10:5: 10:6 - goto -> bb0; // bb5[2]: scope 0 at $DIR/simplify_cfg.rs:6:5: 10:6 -- } -- ++ StorageDead(_2); // bb2[1]: scope 0 at $DIR/simplify_cfg.rs:10:5: 10:6 ++ goto -> bb0; // bb2[2]: scope 0 at $DIR/simplify_cfg.rs:6:5: 10:6 + } + - bb6: { -- _0 = (); // bb6[0]: scope 0 at $DIR/simplify_cfg.rs:8:13: 8:18 +- _0 = const (); // bb6[0]: scope 0 at $DIR/simplify_cfg.rs:8:13: 8:18 ++ bb3: { ++ _0 = const (); // bb3[0]: scope 0 at $DIR/simplify_cfg.rs:8:13: 8:18 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/simplify_cfg.rs:8:13: 8:18 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } - StorageDead(_2); // bb6[1]: scope 0 at $DIR/simplify_cfg.rs:10:5: 10:6 - return; // bb6[2]: scope 0 at $DIR/simplify_cfg.rs:11:2: 11:2 -+ bb3: { -+ _0 = (); // bb3[0]: scope 0 at $DIR/simplify_cfg.rs:8:13: 8:18 + StorageDead(_2); // bb3[1]: scope 0 at $DIR/simplify_cfg.rs:10:5: 10:6 + return; // bb3[2]: scope 0 at $DIR/simplify_cfg.rs:11:2: 11:2 } diff --git a/src/test/mir-opt/simplify_cfg/rustc.main.SimplifyCfg-initial.diff b/src/test/mir-opt/simplify_cfg/rustc.main.SimplifyCfg-initial.diff index 856ee3508cb..7c8bdde5418 100644 --- a/src/test/mir-opt/simplify_cfg/rustc.main.SimplifyCfg-initial.diff +++ b/src/test/mir-opt/simplify_cfg/rustc.main.SimplifyCfg-initial.diff @@ -54,16 +54,30 @@ } - bb7: { -- _1 = (); // bb7[0]: scope 0 at $DIR/simplify_cfg.rs:7:9: 9:10 -- goto -> bb12; // bb7[1]: scope 0 at $DIR/simplify_cfg.rs:7:9: 9:10 +- _1 = const (); // bb7[0]: scope 0 at $DIR/simplify_cfg.rs:7:9: 9:10 + bb5: { -+ _1 = (); // bb5[0]: scope 0 at $DIR/simplify_cfg.rs:7:9: 9:10 ++ _1 = const (); // bb5[0]: scope 0 at $DIR/simplify_cfg.rs:7:9: 9:10 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/simplify_cfg.rs:7:9: 9:10 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } +- goto -> bb12; // bb7[1]: scope 0 at $DIR/simplify_cfg.rs:7:9: 9:10 + StorageDead(_2); // bb5[1]: scope 0 at $DIR/simplify_cfg.rs:10:5: 10:6 + goto -> bb0; // bb5[2]: scope 0 at $DIR/simplify_cfg.rs:6:5: 10:6 } - bb8: { -- _0 = (); // bb8[0]: scope 0 at $DIR/simplify_cfg.rs:8:13: 8:18 +- _0 = const (); // bb8[0]: scope 0 at $DIR/simplify_cfg.rs:8:13: 8:18 ++ bb6: { ++ _0 = const (); // bb6[0]: scope 0 at $DIR/simplify_cfg.rs:8:13: 8:18 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/simplify_cfg.rs:8:13: 8:18 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } - goto -> bb9; // bb8[1]: scope 0 at $DIR/simplify_cfg.rs:8:13: 8:18 - } - @@ -87,8 +101,6 @@ - - bb13: { - return; // bb13[0]: scope 0 at $DIR/simplify_cfg.rs:11:2: 11:2 -+ bb6: { -+ _0 = (); // bb6[0]: scope 0 at $DIR/simplify_cfg.rs:8:13: 8:18 + StorageDead(_2); // bb6[1]: scope 0 at $DIR/simplify_cfg.rs:10:5: 10:6 + return; // bb6[2]: scope 0 at $DIR/simplify_cfg.rs:11:2: 11:2 } diff --git a/src/test/mir-opt/simplify_if/rustc.main.SimplifyBranches-after-const-prop.diff b/src/test/mir-opt/simplify_if/rustc.main.SimplifyBranches-after-const-prop.diff index 9e53a0f18af..2946eb1cc44 100644 --- a/src/test/mir-opt/simplify_if/rustc.main.SimplifyBranches-after-const-prop.diff +++ b/src/test/mir-opt/simplify_if/rustc.main.SimplifyBranches-after-const-prop.diff @@ -26,7 +26,13 @@ } bb1: { - _0 = (); // bb1[0]: scope 0 at $DIR/simplify_if.rs:6:5: 8:6 + _0 = const (); // bb1[0]: scope 0 at $DIR/simplify_if.rs:6:5: 8:6 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/simplify_if.rs:6:5: 8:6 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } goto -> bb4; // bb1[1]: scope 0 at $DIR/simplify_if.rs:6:5: 8:6 } @@ -43,7 +49,13 @@ bb3: { StorageDead(_2); // bb3[0]: scope 0 at $DIR/simplify_if.rs:7:15: 7:16 - _0 = (); // bb3[1]: scope 0 at $DIR/simplify_if.rs:6:14: 8:6 + _0 = const (); // bb3[1]: scope 0 at $DIR/simplify_if.rs:6:14: 8:6 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/simplify_if.rs:6:14: 8:6 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } goto -> bb4; // bb3[2]: scope 0 at $DIR/simplify_if.rs:6:5: 8:6 } diff --git a/src/test/mir-opt/simplify_match/rustc.main.SimplifyBranches-after-copy-prop.diff b/src/test/mir-opt/simplify_match/rustc.main.SimplifyBranches-after-copy-prop.diff index 5429032b099..1c83bb13425 100644 --- a/src/test/mir-opt/simplify_match/rustc.main.SimplifyBranches-after-copy-prop.diff +++ b/src/test/mir-opt/simplify_match/rustc.main.SimplifyBranches-after-copy-prop.diff @@ -26,7 +26,13 @@ } bb1: { - nop; // bb1[0]: scope 0 at $DIR/simplify_match.rs:8:18: 8:20 + _0 = const (); // bb1[0]: scope 0 at $DIR/simplify_match.rs:8:18: 8:20 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/simplify_match.rs:8:18: 8:20 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } goto -> bb3; // bb1[1]: scope 0 at $DIR/simplify_match.rs:6:5: 9:6 } diff --git a/src/test/mir-opt/storage_ranges/rustc.main.nll.0.mir b/src/test/mir-opt/storage_ranges/rustc.main.nll.0.mir index 57ec47346e8..e455a27642d 100644 --- a/src/test/mir-opt/storage_ranges/rustc.main.nll.0.mir +++ b/src/test/mir-opt/storage_ranges/rustc.main.nll.0.mir @@ -54,7 +54,13 @@ fn main() -> () { StorageDead(_5); // bb0[9]: scope 1 at $DIR/storage_ranges.rs:6:24: 6:25 _3 = &_4; // bb0[10]: scope 1 at $DIR/storage_ranges.rs:6:17: 6:25 FakeRead(ForLet, _3); // bb0[11]: scope 1 at $DIR/storage_ranges.rs:6:13: 6:14 - _2 = (); // bb0[12]: scope 1 at $DIR/storage_ranges.rs:5:5: 7:6 + _2 = const (); // bb0[12]: scope 1 at $DIR/storage_ranges.rs:5:5: 7:6 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/storage_ranges.rs:5:5: 7:6 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_4); // bb0[13]: scope 1 at $DIR/storage_ranges.rs:7:5: 7:6 StorageDead(_3); // bb0[14]: scope 1 at $DIR/storage_ranges.rs:7:5: 7:6 StorageDead(_2); // bb0[15]: scope 1 at $DIR/storage_ranges.rs:7:5: 7:6 @@ -67,7 +73,13 @@ fn main() -> () { // + span: $DIR/storage_ranges.rs:8:13: 8:14 // + literal: Const { ty: i32, val: Value(Scalar(0x00000001)) } FakeRead(ForLet, _6); // bb0[18]: scope 1 at $DIR/storage_ranges.rs:8:9: 8:10 - _0 = (); // bb0[19]: scope 0 at $DIR/storage_ranges.rs:3:11: 9:2 + _0 = const (); // bb0[19]: scope 0 at $DIR/storage_ranges.rs:3:11: 9:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/storage_ranges.rs:3:11: 9:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_6); // bb0[20]: scope 1 at $DIR/storage_ranges.rs:9:1: 9:2 StorageDead(_1); // bb0[21]: scope 0 at $DIR/storage_ranges.rs:9:1: 9:2 return; // bb0[22]: scope 0 at $DIR/storage_ranges.rs:9:2: 9:2 diff --git a/src/test/mir-opt/uniform_array_move_out/rustc.move_out_by_subslice.mir_map.0.mir b/src/test/mir-opt/uniform_array_move_out/rustc.move_out_by_subslice.mir_map.0.mir index 5dbee8f7b3d..b46adadf101 100644 --- a/src/test/mir-opt/uniform_array_move_out/rustc.move_out_by_subslice.mir_map.0.mir +++ b/src/test/mir-opt/uniform_array_move_out/rustc.move_out_by_subslice.mir_map.0.mir @@ -83,7 +83,13 @@ fn move_out_by_subslice() -> () { FakeRead(ForLet, _1); // bb9[1]: scope 0 at $DIR/uniform_array_move_out.rs:11:9: 11:10 StorageLive(_6); // bb9[2]: scope 1 at $DIR/uniform_array_move_out.rs:12:10: 12:17 _6 = move _1[0..2]; // bb9[3]: scope 1 at $DIR/uniform_array_move_out.rs:12:10: 12:17 - _0 = (); // bb9[4]: scope 0 at $DIR/uniform_array_move_out.rs:10:27: 13:2 + _0 = const (); // bb9[4]: scope 0 at $DIR/uniform_array_move_out.rs:10:27: 13:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/uniform_array_move_out.rs:10:27: 13:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } drop(_6) -> [return: bb12, unwind: bb10]; // bb9[5]: scope 1 at $DIR/uniform_array_move_out.rs:13:1: 13:2 } diff --git a/src/test/mir-opt/uniform_array_move_out/rustc.move_out_from_end.mir_map.0.mir b/src/test/mir-opt/uniform_array_move_out/rustc.move_out_from_end.mir_map.0.mir index 4a5cd625c9d..851107efe11 100644 --- a/src/test/mir-opt/uniform_array_move_out/rustc.move_out_from_end.mir_map.0.mir +++ b/src/test/mir-opt/uniform_array_move_out/rustc.move_out_from_end.mir_map.0.mir @@ -83,7 +83,13 @@ fn move_out_from_end() -> () { FakeRead(ForLet, _1); // bb9[1]: scope 0 at $DIR/uniform_array_move_out.rs:5:9: 5:10 StorageLive(_6); // bb9[2]: scope 1 at $DIR/uniform_array_move_out.rs:6:14: 6:16 _6 = move _1[1 of 2]; // bb9[3]: scope 1 at $DIR/uniform_array_move_out.rs:6:14: 6:16 - _0 = (); // bb9[4]: scope 0 at $DIR/uniform_array_move_out.rs:4:24: 7:2 + _0 = const (); // bb9[4]: scope 0 at $DIR/uniform_array_move_out.rs:4:24: 7:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/uniform_array_move_out.rs:4:24: 7:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } drop(_6) -> [return: bb12, unwind: bb10]; // bb9[5]: scope 1 at $DIR/uniform_array_move_out.rs:7:1: 7:2 } diff --git a/src/test/mir-opt/uninhabited-enum/rustc.process_void.SimplifyLocals.after.mir b/src/test/mir-opt/uninhabited-enum/rustc.process_void.SimplifyLocals.after.mir index 2eb820bbdc3..1ee2297daac 100644 --- a/src/test/mir-opt/uninhabited-enum/rustc.process_void.SimplifyLocals.after.mir +++ b/src/test/mir-opt/uninhabited-enum/rustc.process_void.SimplifyLocals.after.mir @@ -13,7 +13,14 @@ fn process_void(_1: *const Void) -> () { bb0: { StorageLive(_2); // bb0[0]: scope 0 at $DIR/uninhabited-enum.rs:14:8: 14:14 _2 = &(*_1); // bb0[1]: scope 2 at $DIR/uninhabited-enum.rs:14:26: 14:33 - StorageDead(_2); // bb0[2]: scope 0 at $DIR/uninhabited-enum.rs:17:1: 17:2 - return; // bb0[3]: scope 0 at $DIR/uninhabited-enum.rs:17:2: 17:2 + _0 = const (); // bb0[2]: scope 0 at $DIR/uninhabited-enum.rs:13:41: 17:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/uninhabited-enum.rs:13:41: 17:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } + StorageDead(_2); // bb0[3]: scope 0 at $DIR/uninhabited-enum.rs:17:1: 17:2 + return; // bb0[4]: scope 0 at $DIR/uninhabited-enum.rs:17:2: 17:2 } } diff --git a/src/test/mir-opt/uninhabited_enum_branching/rustc.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir b/src/test/mir-opt/uninhabited_enum_branching/rustc.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir index c8dde4d360c..fba77dfe239 100644 --- a/src/test/mir-opt/uninhabited_enum_branching/rustc.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir +++ b/src/test/mir-opt/uninhabited_enum_branching/rustc.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir @@ -64,7 +64,13 @@ fn main() -> () { bb3: { StorageDead(_7); // bb3[0]: scope 0 at $DIR/uninhabited_enum_branching.rs:29:6: 29:7 StorageDead(_6); // bb3[1]: scope 0 at $DIR/uninhabited_enum_branching.rs:29:6: 29:7 - _0 = (); // bb3[2]: scope 0 at $DIR/uninhabited_enum_branching.rs:19:11: 30:2 + _0 = const (); // bb3[2]: scope 0 at $DIR/uninhabited_enum_branching.rs:19:11: 30:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/uninhabited_enum_branching.rs:19:11: 30:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } return; // bb3[3]: scope 0 at $DIR/uninhabited_enum_branching.rs:30:2: 30:2 } } diff --git a/src/test/mir-opt/uninhabited_enum_branching/rustc.main.UninhabitedEnumBranching.diff b/src/test/mir-opt/uninhabited_enum_branching/rustc.main.UninhabitedEnumBranching.diff index cccd6aa3230..35842fdaa4e 100644 --- a/src/test/mir-opt/uninhabited_enum_branching/rustc.main.UninhabitedEnumBranching.diff +++ b/src/test/mir-opt/uninhabited_enum_branching/rustc.main.UninhabitedEnumBranching.diff @@ -99,7 +99,13 @@ bb7: { StorageDead(_7); // bb7[0]: scope 0 at $DIR/uninhabited_enum_branching.rs:29:6: 29:7 StorageDead(_6); // bb7[1]: scope 0 at $DIR/uninhabited_enum_branching.rs:29:6: 29:7 - _0 = (); // bb7[2]: scope 0 at $DIR/uninhabited_enum_branching.rs:19:11: 30:2 + _0 = const (); // bb7[2]: scope 0 at $DIR/uninhabited_enum_branching.rs:19:11: 30:2 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/uninhabited_enum_branching.rs:19:11: 30:2 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } return; // bb7[3]: scope 0 at $DIR/uninhabited_enum_branching.rs:30:2: 30:2 } } diff --git a/src/test/mir-opt/unreachable/rustc.main.UnreachablePropagation.diff b/src/test/mir-opt/unreachable/rustc.main.UnreachablePropagation.diff index 3a239c6e3b0..d530a999409 100644 --- a/src/test/mir-opt/unreachable/rustc.main.UnreachablePropagation.diff +++ b/src/test/mir-opt/unreachable/rustc.main.UnreachablePropagation.diff @@ -35,7 +35,13 @@ } bb2: { - _0 = (); // bb2[0]: scope 0 at $DIR/unreachable.rs:9:5: 19:6 + _0 = const (); // bb2[0]: scope 0 at $DIR/unreachable.rs:9:5: 19:6 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/unreachable.rs:9:5: 19:6 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_1); // bb2[1]: scope 0 at $DIR/unreachable.rs:20:1: 20:2 return; // bb2[2]: scope 0 at $DIR/unreachable.rs:20:2: 20:2 - } @@ -64,7 +70,13 @@ - // mir::Constant - // + span: $DIR/unreachable.rs:15:18: 15:20 - // + literal: Const { ty: i32, val: Value(Scalar(0x0000002a)) } -- _5 = (); // bb4[1]: scope 2 at $DIR/unreachable.rs:14:16: 16:10 +- _5 = const (); // bb4[1]: scope 2 at $DIR/unreachable.rs:14:16: 16:10 +- // ty::Const +- // + ty: () +- // + val: Value(Scalar(<ZST>)) +- // mir::Constant +- // + span: $DIR/unreachable.rs:14:16: 16:10 +- // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } - goto -> bb6; // bb4[2]: scope 2 at $DIR/unreachable.rs:12:9: 16:10 - } - @@ -76,7 +88,13 @@ - // mir::Constant - // + span: $DIR/unreachable.rs:13:18: 13:20 - // + literal: Const { ty: i32, val: Value(Scalar(0x00000015)) } -- _5 = (); // bb5[1]: scope 2 at $DIR/unreachable.rs:12:17: 14:10 +- _5 = const (); // bb5[1]: scope 2 at $DIR/unreachable.rs:12:17: 14:10 +- // ty::Const +- // + ty: () +- // + val: Value(Scalar(<ZST>)) +- // mir::Constant +- // + span: $DIR/unreachable.rs:12:17: 14:10 +- // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } - goto -> bb6; // bb5[2]: scope 2 at $DIR/unreachable.rs:12:9: 16:10 - } - diff --git a/src/test/mir-opt/unreachable_asm/rustc.main.UnreachablePropagation.diff b/src/test/mir-opt/unreachable_asm/rustc.main.UnreachablePropagation.diff index c32165a3893..2b3ab80fa0f 100644 --- a/src/test/mir-opt/unreachable_asm/rustc.main.UnreachablePropagation.diff +++ b/src/test/mir-opt/unreachable_asm/rustc.main.UnreachablePropagation.diff @@ -37,7 +37,13 @@ } bb2: { - _0 = (); // bb2[0]: scope 0 at $DIR/unreachable_asm.rs:11:5: 23:6 + _0 = const (); // bb2[0]: scope 0 at $DIR/unreachable_asm.rs:11:5: 23:6 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/unreachable_asm.rs:11:5: 23:6 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_1); // bb2[1]: scope 0 at $DIR/unreachable_asm.rs:24:1: 24:2 return; // bb2[2]: scope 0 at $DIR/unreachable_asm.rs:24:2: 24:2 } @@ -66,7 +72,13 @@ // mir::Constant // + span: $DIR/unreachable_asm.rs:17:18: 17:20 // + literal: Const { ty: i32, val: Value(Scalar(0x0000002a)) } - _5 = (); // bb4[1]: scope 2 at $DIR/unreachable_asm.rs:16:16: 18:10 + _5 = const (); // bb4[1]: scope 2 at $DIR/unreachable_asm.rs:16:16: 18:10 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/unreachable_asm.rs:16:16: 18:10 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } goto -> bb6; // bb4[2]: scope 2 at $DIR/unreachable_asm.rs:14:9: 18:10 } @@ -78,7 +90,13 @@ // mir::Constant // + span: $DIR/unreachable_asm.rs:15:18: 15:20 // + literal: Const { ty: i32, val: Value(Scalar(0x00000015)) } - _5 = (); // bb5[1]: scope 2 at $DIR/unreachable_asm.rs:14:17: 16:10 + _5 = const (); // bb5[1]: scope 2 at $DIR/unreachable_asm.rs:14:17: 16:10 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/unreachable_asm.rs:14:17: 16:10 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } goto -> bb6; // bb5[2]: scope 2 at $DIR/unreachable_asm.rs:14:9: 18:10 } @@ -87,7 +105,13 @@ StorageDead(_5); // bb6[1]: scope 2 at $DIR/unreachable_asm.rs:18:9: 18:10 StorageLive(_7); // bb6[2]: scope 2 at $DIR/unreachable_asm.rs:21:9: 21:37 llvm_asm!(LlvmInlineAsmInner { asm: "NOP", asm_str_style: Cooked, outputs: [], inputs: [], clobbers: [], volatile: true, alignstack: false, dialect: Att } : [] : []); // bb6[3]: scope 3 at $DIR/unreachable_asm.rs:21:18: 21:35 - _7 = (); // bb6[4]: scope 3 at $DIR/unreachable_asm.rs:21:9: 21:37 + _7 = const (); // bb6[4]: scope 3 at $DIR/unreachable_asm.rs:21:9: 21:37 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/unreachable_asm.rs:21:9: 21:37 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_7); // bb6[5]: scope 2 at $DIR/unreachable_asm.rs:21:36: 21:37 StorageLive(_8); // bb6[6]: scope 2 at $DIR/unreachable_asm.rs:22:9: 22:21 unreachable; // bb6[7]: scope 2 at $DIR/unreachable_asm.rs:22:15: 22:17 diff --git a/src/test/mir-opt/unreachable_asm_2/rustc.main.UnreachablePropagation.diff b/src/test/mir-opt/unreachable_asm_2/rustc.main.UnreachablePropagation.diff index a3741787566..c3760f6a7fc 100644 --- a/src/test/mir-opt/unreachable_asm_2/rustc.main.UnreachablePropagation.diff +++ b/src/test/mir-opt/unreachable_asm_2/rustc.main.UnreachablePropagation.diff @@ -40,7 +40,13 @@ } bb2: { - _0 = (); // bb2[0]: scope 0 at $DIR/unreachable_asm_2.rs:11:5: 25:6 + _0 = const (); // bb2[0]: scope 0 at $DIR/unreachable_asm_2.rs:11:5: 25:6 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/unreachable_asm_2.rs:11:5: 25:6 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_1); // bb2[1]: scope 0 at $DIR/unreachable_asm_2.rs:26:1: 26:2 return; // bb2[2]: scope 0 at $DIR/unreachable_asm_2.rs:26:2: 26:2 } @@ -64,7 +70,13 @@ bb4: { StorageLive(_8); // bb4[0]: scope 2 at $DIR/unreachable_asm_2.rs:20:13: 20:41 llvm_asm!(LlvmInlineAsmInner { asm: "NOP", asm_str_style: Cooked, outputs: [], inputs: [], clobbers: [], volatile: true, alignstack: false, dialect: Att } : [] : []); // bb4[1]: scope 4 at $DIR/unreachable_asm_2.rs:20:22: 20:39 - _8 = (); // bb4[2]: scope 4 at $DIR/unreachable_asm_2.rs:20:13: 20:41 + _8 = const (); // bb4[2]: scope 4 at $DIR/unreachable_asm_2.rs:20:13: 20:41 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/unreachable_asm_2.rs:20:13: 20:41 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_8); // bb4[3]: scope 2 at $DIR/unreachable_asm_2.rs:20:40: 20:41 _4 = const 42i32; // bb4[4]: scope 2 at $DIR/unreachable_asm_2.rs:21:13: 21:20 // ty::Const @@ -73,7 +85,13 @@ // mir::Constant // + span: $DIR/unreachable_asm_2.rs:21:18: 21:20 // + literal: Const { ty: i32, val: Value(Scalar(0x0000002a)) } - _5 = (); // bb4[5]: scope 2 at $DIR/unreachable_asm_2.rs:18:16: 22:10 + _5 = const (); // bb4[5]: scope 2 at $DIR/unreachable_asm_2.rs:18:16: 22:10 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/unreachable_asm_2.rs:18:16: 22:10 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } - goto -> bb6; // bb4[6]: scope 2 at $DIR/unreachable_asm_2.rs:14:9: 22:10 + unreachable; // bb4[6]: scope 2 at $DIR/unreachable_asm_2.rs:14:9: 22:10 } @@ -81,7 +99,13 @@ bb5: { StorageLive(_7); // bb5[0]: scope 2 at $DIR/unreachable_asm_2.rs:16:13: 16:41 llvm_asm!(LlvmInlineAsmInner { asm: "NOP", asm_str_style: Cooked, outputs: [], inputs: [], clobbers: [], volatile: true, alignstack: false, dialect: Att } : [] : []); // bb5[1]: scope 3 at $DIR/unreachable_asm_2.rs:16:22: 16:39 - _7 = (); // bb5[2]: scope 3 at $DIR/unreachable_asm_2.rs:16:13: 16:41 + _7 = const (); // bb5[2]: scope 3 at $DIR/unreachable_asm_2.rs:16:13: 16:41 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/unreachable_asm_2.rs:16:13: 16:41 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_7); // bb5[3]: scope 2 at $DIR/unreachable_asm_2.rs:16:40: 16:41 _4 = const 21i32; // bb5[4]: scope 2 at $DIR/unreachable_asm_2.rs:17:13: 17:20 // ty::Const @@ -90,7 +114,13 @@ // mir::Constant // + span: $DIR/unreachable_asm_2.rs:17:18: 17:20 // + literal: Const { ty: i32, val: Value(Scalar(0x00000015)) } - _5 = (); // bb5[5]: scope 2 at $DIR/unreachable_asm_2.rs:14:17: 18:10 + _5 = const (); // bb5[5]: scope 2 at $DIR/unreachable_asm_2.rs:14:17: 18:10 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/unreachable_asm_2.rs:14:17: 18:10 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } - goto -> bb6; // bb5[6]: scope 2 at $DIR/unreachable_asm_2.rs:14:9: 22:10 - } - diff --git a/src/test/mir-opt/unreachable_diverging/rustc.main.UnreachablePropagation.diff b/src/test/mir-opt/unreachable_diverging/rustc.main.UnreachablePropagation.diff index 8d1d137f192..2fe0c8dc1e7 100644 --- a/src/test/mir-opt/unreachable_diverging/rustc.main.UnreachablePropagation.diff +++ b/src/test/mir-opt/unreachable_diverging/rustc.main.UnreachablePropagation.diff @@ -42,7 +42,13 @@ } bb2: { - _0 = (); // bb2[0]: scope 1 at $DIR/unreachable_diverging.rs:14:5: 19:6 + _0 = const (); // bb2[0]: scope 1 at $DIR/unreachable_diverging.rs:14:5: 19:6 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/unreachable_diverging.rs:14:5: 19:6 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } StorageDead(_1); // bb2[1]: scope 0 at $DIR/unreachable_diverging.rs:20:1: 20:2 StorageDead(_2); // bb2[2]: scope 0 at $DIR/unreachable_diverging.rs:20:1: 20:2 return; // bb2[3]: scope 0 at $DIR/unreachable_diverging.rs:20:2: 20:2 @@ -59,14 +65,20 @@ } bb4: { -- _5 = (); // bb4[0]: scope 2 at $DIR/unreachable_diverging.rs:15:9: 17:10 +- _5 = const (); // bb4[0]: scope 2 at $DIR/unreachable_diverging.rs:15:9: 17:10 ++ _5 = const loop_forever() -> bb5; // bb4[0]: scope 2 at $DIR/unreachable_diverging.rs:16:13: 16:27 + // ty::Const +- // + ty: () +- // + val: Value(Scalar(<ZST>)) +- // mir::Constant +- // + span: $DIR/unreachable_diverging.rs:15:9: 17:10 +- // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } - goto -> bb6; // bb4[1]: scope 2 at $DIR/unreachable_diverging.rs:15:9: 17:10 - } - - bb5: { - _5 = const loop_forever() -> bb6; // bb5[0]: scope 2 at $DIR/unreachable_diverging.rs:16:13: 16:27 -+ _5 = const loop_forever() -> bb5; // bb4[0]: scope 2 at $DIR/unreachable_diverging.rs:16:13: 16:27 - // ty::Const +- // ty::Const // + ty: fn() {loop_forever} // + val: Value(Scalar(<ZST>)) // mir::Constant diff --git a/src/test/mir-opt/while-storage/rustc.while_loop.PreCodegen.after.mir b/src/test/mir-opt/while-storage/rustc.while_loop.PreCodegen.after.mir index 8fadcb8c12f..0ac7989166e 100644 --- a/src/test/mir-opt/while-storage/rustc.while_loop.PreCodegen.after.mir +++ b/src/test/mir-opt/while-storage/rustc.while_loop.PreCodegen.after.mir @@ -23,40 +23,58 @@ fn while_loop(_1: bool) -> () { bb1: { StorageDead(_3); // bb1[0]: scope 0 at $DIR/while-storage.rs:10:21: 10:22 - switchInt(_2) -> [false: bb6, otherwise: bb2]; // bb1[1]: scope 0 at $DIR/while-storage.rs:10:5: 14:6 + switchInt(_2) -> [false: bb2, otherwise: bb3]; // bb1[1]: scope 0 at $DIR/while-storage.rs:10:5: 14:6 } bb2: { - StorageLive(_4); // bb2[0]: scope 0 at $DIR/while-storage.rs:11:12: 11:23 - StorageLive(_5); // bb2[1]: scope 0 at $DIR/while-storage.rs:11:21: 11:22 - _5 = _1; // bb2[2]: scope 0 at $DIR/while-storage.rs:11:21: 11:22 - _4 = const get_bool(move _5) -> bb3; // bb2[3]: scope 0 at $DIR/while-storage.rs:11:12: 11:23 + _0 = const (); // bb2[0]: scope 0 at $DIR/while-storage.rs:10:5: 14:6 // ty::Const - // + ty: fn(bool) -> bool {get_bool} + // + ty: () // + val: Value(Scalar(<ZST>)) // mir::Constant - // + span: $DIR/while-storage.rs:11:12: 11:20 - // + literal: Const { ty: fn(bool) -> bool {get_bool}, val: Value(Scalar(<ZST>)) } + // + span: $DIR/while-storage.rs:10:5: 14:6 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } + goto -> bb7; // bb2[1]: scope 0 at $DIR/while-storage.rs:10:5: 14:6 } bb3: { - StorageDead(_5); // bb3[0]: scope 0 at $DIR/while-storage.rs:11:22: 11:23 - switchInt(_4) -> [false: bb4, otherwise: bb5]; // bb3[1]: scope 0 at $DIR/while-storage.rs:11:9: 13:10 + StorageLive(_4); // bb3[0]: scope 0 at $DIR/while-storage.rs:11:12: 11:23 + StorageLive(_5); // bb3[1]: scope 0 at $DIR/while-storage.rs:11:21: 11:22 + _5 = _1; // bb3[2]: scope 0 at $DIR/while-storage.rs:11:21: 11:22 + _4 = const get_bool(move _5) -> bb4; // bb3[3]: scope 0 at $DIR/while-storage.rs:11:12: 11:23 + // ty::Const + // + ty: fn(bool) -> bool {get_bool} + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/while-storage.rs:11:12: 11:20 + // + literal: Const { ty: fn(bool) -> bool {get_bool}, val: Value(Scalar(<ZST>)) } } bb4: { - StorageDead(_4); // bb4[0]: scope 0 at $DIR/while-storage.rs:14:5: 14:6 - StorageDead(_2); // bb4[1]: scope 0 at $DIR/while-storage.rs:10:21: 10:22 - goto -> bb0; // bb4[2]: scope 0 at $DIR/while-storage.rs:10:5: 14:6 + StorageDead(_5); // bb4[0]: scope 0 at $DIR/while-storage.rs:11:22: 11:23 + switchInt(_4) -> [false: bb5, otherwise: bb6]; // bb4[1]: scope 0 at $DIR/while-storage.rs:11:9: 13:10 } bb5: { StorageDead(_4); // bb5[0]: scope 0 at $DIR/while-storage.rs:14:5: 14:6 - goto -> bb6; // bb5[1]: scope 0 at $DIR/while-storage.rs:12:13: 12:18 + StorageDead(_2); // bb5[1]: scope 0 at $DIR/while-storage.rs:10:21: 10:22 + goto -> bb0; // bb5[2]: scope 0 at $DIR/while-storage.rs:10:5: 14:6 } bb6: { - StorageDead(_2); // bb6[0]: scope 0 at $DIR/while-storage.rs:10:21: 10:22 - return; // bb6[1]: scope 0 at $DIR/while-storage.rs:15:2: 15:2 + _0 = const (); // bb6[0]: scope 0 at $DIR/while-storage.rs:12:13: 12:18 + // ty::Const + // + ty: () + // + val: Value(Scalar(<ZST>)) + // mir::Constant + // + span: $DIR/while-storage.rs:12:13: 12:18 + // + literal: Const { ty: (), val: Value(Scalar(<ZST>)) } + StorageDead(_4); // bb6[1]: scope 0 at $DIR/while-storage.rs:14:5: 14:6 + goto -> bb7; // bb6[2]: scope 0 at $DIR/while-storage.rs:12:13: 12:18 + } + + bb7: { + StorageDead(_2); // bb7[0]: scope 0 at $DIR/while-storage.rs:10:21: 10:22 + return; // bb7[1]: scope 0 at $DIR/while-storage.rs:15:2: 15:2 } } diff --git a/src/test/ui/array-break-length.rs b/src/test/ui/array-break-length.rs index 959f4a2babb..60589f7c264 100644 --- a/src/test/ui/array-break-length.rs +++ b/src/test/ui/array-break-length.rs @@ -1,11 +1,9 @@ fn main() { loop { |_: [_; break]| {} //~ ERROR: `break` outside of a loop - //~^ ERROR mismatched types } loop { |_: [_; continue]| {} //~ ERROR: `continue` outside of a loop - //~^ ERROR mismatched types } } diff --git a/src/test/ui/array-break-length.stderr b/src/test/ui/array-break-length.stderr index 69c7599cce1..93f1c238bcc 100644 --- a/src/test/ui/array-break-length.stderr +++ b/src/test/ui/array-break-length.stderr @@ -5,30 +5,11 @@ LL | |_: [_; break]| {} | ^^^^^ cannot `break` outside of a loop error[E0268]: `continue` outside of a loop - --> $DIR/array-break-length.rs:8:17 + --> $DIR/array-break-length.rs:7:17 | LL | |_: [_; continue]| {} | ^^^^^^^^ cannot `continue` outside of a loop -error[E0308]: mismatched types - --> $DIR/array-break-length.rs:3:9 - | -LL | |_: [_; break]| {} - | ^^^^^^^^^^^^^^^^^^ expected `()`, found closure - | - = note: expected unit type `()` - found closure `[closure@$DIR/array-break-length.rs:3:9: 3:27]` - -error[E0308]: mismatched types - --> $DIR/array-break-length.rs:8:9 - | -LL | |_: [_; continue]| {} - | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found closure - | - = note: expected unit type `()` - found closure `[closure@$DIR/array-break-length.rs:8:9: 8:30]` - -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0268, E0308. -For more information about an error, try `rustc --explain E0268`. +For more information about this error, try `rustc --explain E0268`. diff --git a/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.rs b/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.rs index f1f82caf7d4..8fe79b97d9b 100644 --- a/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.rs +++ b/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.rs @@ -14,7 +14,7 @@ impl Foo for Def { pub fn test<A: Foo, B: Foo>() { let _array = [4; <A as Foo>::Y]; - //~^ ERROR the trait bound `A: Foo` is not satisfied [E0277] + //~^ ERROR constant expression depends on a generic parameter } fn main() { diff --git a/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.stderr b/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.stderr index 946a1f1a07a..0bc019b2dc8 100644 --- a/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.stderr +++ b/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.stderr @@ -1,17 +1,10 @@ -error[E0277]: the trait bound `A: Foo` is not satisfied +error: constant expression depends on a generic parameter --> $DIR/associated-const-type-parameter-arrays-2.rs:16:22 | -LL | const Y: usize; - | --------------- required by `Foo::Y` -... LL | let _array = [4; <A as Foo>::Y]; - | ^^^^^^^^^^^^^ the trait `Foo` is not implemented for `A` + | ^^^^^^^^^^^^^ | -help: consider further restricting this bound - | -LL | pub fn test<A: Foo + Foo, B: Foo>() { - | ^^^^^ + = note: this may fail depending on what value the parameter takes error: aborting due to previous error -For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/async-await/async-fn-nonsend.stderr b/src/test/ui/async-await/async-fn-nonsend.stderr index 04df6203e43..d36d59f1f68 100644 --- a/src/test/ui/async-await/async-fn-nonsend.stderr +++ b/src/test/ui/async-await/async-fn-nonsend.stderr @@ -12,7 +12,7 @@ note: future is not `Send` as this value is used across an await --> $DIR/async-fn-nonsend.rs:24:5 | LL | let x = non_send(); - | - has type `impl std::fmt::Debug` + | - has type `impl std::fmt::Debug` which is not `Send` LL | drop(x); LL | fut().await; | ^^^^^^^^^^^ await occurs here, with `x` maybe used later @@ -33,7 +33,7 @@ note: future is not `Send` as this value is used across an await --> $DIR/async-fn-nonsend.rs:33:20 | LL | match Some(non_send()) { - | ---------- has type `impl std::fmt::Debug` + | ---------- has type `impl std::fmt::Debug` which is not `Send` LL | Some(_) => fut().await, | ^^^^^^^^^^^ await occurs here, with `non_send()` maybe used later ... @@ -54,7 +54,7 @@ note: future is not `Send` as this value is used across an await --> $DIR/async-fn-nonsend.rs:42:9 | LL | let f: &mut std::fmt::Formatter = panic!(); - | - has type `&mut std::fmt::Formatter<'_>` + | - has type `&mut std::fmt::Formatter<'_>` which is not `Send` LL | if non_sync().fmt(f).unwrap() == () { LL | fut().await; | ^^^^^^^^^^^ await occurs here, with `f` maybe used later diff --git a/src/test/ui/async-await/issue-64130-1-sync.stderr b/src/test/ui/async-await/issue-64130-1-sync.stderr index b7a88c10e74..42e9e4642ce 100644 --- a/src/test/ui/async-await/issue-64130-1-sync.stderr +++ b/src/test/ui/async-await/issue-64130-1-sync.stderr @@ -12,7 +12,7 @@ note: future is not `Sync` as this value is used across an await --> $DIR/issue-64130-1-sync.rs:15:5 | LL | let x = Foo; - | - has type `Foo` + | - has type `Foo` which is not `Sync` LL | baz().await; | ^^^^^^^^^^^ await occurs here, with `x` maybe used later LL | } diff --git a/src/test/ui/async-await/issue-64130-2-send.stderr b/src/test/ui/async-await/issue-64130-2-send.stderr index ec183088771..f6f834618d3 100644 --- a/src/test/ui/async-await/issue-64130-2-send.stderr +++ b/src/test/ui/async-await/issue-64130-2-send.stderr @@ -12,7 +12,7 @@ note: future is not `Send` as this value is used across an await --> $DIR/issue-64130-2-send.rs:15:5 | LL | let x = Foo; - | - has type `Foo` + | - has type `Foo` which is not `Send` LL | baz().await; | ^^^^^^^^^^^ await occurs here, with `x` maybe used later LL | } diff --git a/src/test/ui/async-await/issue-64130-3-other.stderr b/src/test/ui/async-await/issue-64130-3-other.stderr index 6b40cc9184d..3475b66b375 100644 --- a/src/test/ui/async-await/issue-64130-3-other.stderr +++ b/src/test/ui/async-await/issue-64130-3-other.stderr @@ -16,7 +16,7 @@ note: future does not implement `Qux` as this value is used across an await --> $DIR/issue-64130-3-other.rs:18:5 | LL | let x = Foo; - | - has type `Foo` + | - has type `Foo` which does not implement `Qux` LL | baz().await; | ^^^^^^^^^^^ await occurs here, with `x` maybe used later LL | } diff --git a/src/test/ui/async-await/issue-64130-4-async-move.stderr b/src/test/ui/async-await/issue-64130-4-async-move.stderr index 1e52d74f155..fc231d394c1 100644 --- a/src/test/ui/async-await/issue-64130-4-async-move.stderr +++ b/src/test/ui/async-await/issue-64130-4-async-move.stderr @@ -2,7 +2,7 @@ error: future cannot be sent between threads safely --> $DIR/issue-64130-4-async-move.rs:15:17 | LL | pub fn foo() -> impl Future + Send { - | ^^^^^^^^^^^^^^^^^^ future returned by `foo` is not `Send` + | ^^^^^^^^^^^^^^^^^^ future created by async block is not `Send` ... LL | / async move { LL | | match client.status() { @@ -18,7 +18,7 @@ note: future is not `Send` as this value is used across an await --> $DIR/issue-64130-4-async-move.rs:21:26 | LL | match client.status() { - | ------ has type `&Client` + | ------ has type `&Client` which is not `Send` LL | 200 => { LL | let _x = get().await; | ^^^^^^^^^^^ await occurs here, with `client` maybe used later diff --git a/src/test/ui/async-await/issue-64130-non-send-future-diags.stderr b/src/test/ui/async-await/issue-64130-non-send-future-diags.stderr index 0f4441edb13..f72757339cc 100644 --- a/src/test/ui/async-await/issue-64130-non-send-future-diags.stderr +++ b/src/test/ui/async-await/issue-64130-non-send-future-diags.stderr @@ -12,7 +12,7 @@ note: future is not `Send` as this value is used across an await --> $DIR/issue-64130-non-send-future-diags.rs:15:5 | LL | let g = x.lock().unwrap(); - | - has type `std::sync::MutexGuard<'_, u32>` + | - has type `std::sync::MutexGuard<'_, u32>` which is not `Send` LL | baz().await; | ^^^^^^^^^^^ await occurs here, with `g` maybe used later LL | } diff --git a/src/test/ui/async-await/issue-67252-unnamed-future.stderr b/src/test/ui/async-await/issue-67252-unnamed-future.stderr index cbcc3cf5d78..b43478ee207 100644 --- a/src/test/ui/async-await/issue-67252-unnamed-future.stderr +++ b/src/test/ui/async-await/issue-67252-unnamed-future.stderr @@ -5,14 +5,14 @@ LL | fn spawn<T: Send>(_: T) {} | ---- required by this bound in `spawn` ... LL | spawn(async { - | ^^^^^ future is not `Send` + | ^^^^^ future created by async block is not `Send` | = help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `*mut ()` note: future is not `Send` as this value is used across an await --> $DIR/issue-67252-unnamed-future.rs:20:9 | LL | let _a = std::ptr::null_mut::<()>(); // `*mut ()` is not `Send` - | -- has type `*mut ()` + | -- has type `*mut ()` which is not `Send` LL | AFuture.await; | ^^^^^^^^^^^^^ await occurs here, with `_a` maybe used later LL | }); diff --git a/src/test/ui/async-await/issue-68112.rs b/src/test/ui/async-await/issue-68112.rs new file mode 100644 index 00000000000..11b17836808 --- /dev/null +++ b/src/test/ui/async-await/issue-68112.rs @@ -0,0 +1,64 @@ +// edition:2018 + +use std::{ + future::Future, + cell::RefCell, + sync::Arc, + pin::Pin, + task::{Context, Poll}, +}; + +fn require_send(_: impl Send) {} + +struct Ready<T>(Option<T>); +impl<T> Future for Ready<T> { + type Output = T; + fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<T> { + Poll::Ready(self.0.take().unwrap()) + } +} +fn ready<T>(t: T) -> Ready<T> { + Ready(Some(t)) +} + +fn make_non_send_future1() -> impl Future<Output = Arc<RefCell<i32>>> { + ready(Arc::new(RefCell::new(0))) +} + +fn test1() { + let send_fut = async { + let non_send_fut = make_non_send_future1(); + let _ = non_send_fut.await; + ready(0).await; + }; + require_send(send_fut); + //~^ ERROR future cannot be sent between threads +} + +fn test1_no_let() { + let send_fut = async { + let _ = make_non_send_future1().await; + ready(0).await; + }; + require_send(send_fut); + //~^ ERROR future cannot be sent between threads +} + +async fn ready2<T>(t: T) -> T { t } +fn make_non_send_future2() -> impl Future<Output = Arc<RefCell<i32>>> { + ready2(Arc::new(RefCell::new(0))) +} + +// Ideally this test would have diagnostics similar to the test above, but right +// now it doesn't. +fn test2() { + let send_fut = async { + let non_send_fut = make_non_send_future2(); + let _ = non_send_fut.await; + ready(0).await; + }; + require_send(send_fut); + //~^ ERROR `std::cell::RefCell<i32>` cannot be shared between threads safely +} + +fn main() {} diff --git a/src/test/ui/async-await/issue-68112.stderr b/src/test/ui/async-await/issue-68112.stderr new file mode 100644 index 00000000000..6ded3e475bc --- /dev/null +++ b/src/test/ui/async-await/issue-68112.stderr @@ -0,0 +1,56 @@ +error: future cannot be sent between threads safely + --> $DIR/issue-68112.rs:34:5 + | +LL | fn require_send(_: impl Send) {} + | ---- required by this bound in `require_send` +... +LL | require_send(send_fut); + | ^^^^^^^^^^^^ future created by async block is not `Send` + | + = help: the trait `std::marker::Sync` is not implemented for `std::cell::RefCell<i32>` +note: future is not `Send` as it awaits another future which is not `Send` + --> $DIR/issue-68112.rs:31:17 + | +LL | let _ = non_send_fut.await; + | ^^^^^^^^^^^^ await occurs here on type `impl std::future::Future`, which is not `Send` + +error: future cannot be sent between threads safely + --> $DIR/issue-68112.rs:43:5 + | +LL | fn require_send(_: impl Send) {} + | ---- required by this bound in `require_send` +... +LL | require_send(send_fut); + | ^^^^^^^^^^^^ future created by async block is not `Send` + | + = help: the trait `std::marker::Sync` is not implemented for `std::cell::RefCell<i32>` +note: future is not `Send` as it awaits another future which is not `Send` + --> $DIR/issue-68112.rs:40:17 + | +LL | let _ = make_non_send_future1().await; + | ^^^^^^^^^^^^^^^^^^^^^^^ await occurs here on type `impl std::future::Future`, which is not `Send` + +error[E0277]: `std::cell::RefCell<i32>` cannot be shared between threads safely + --> $DIR/issue-68112.rs:60:5 + | +LL | fn require_send(_: impl Send) {} + | ---- required by this bound in `require_send` +... +LL | require_send(send_fut); + | ^^^^^^^^^^^^ `std::cell::RefCell<i32>` cannot be shared between threads safely + | + = help: the trait `std::marker::Sync` is not implemented for `std::cell::RefCell<i32>` + = note: required because of the requirements on the impl of `std::marker::Send` for `std::sync::Arc<std::cell::RefCell<i32>>` + = note: required because it appears within the type `[static generator@$DIR/issue-68112.rs:47:31: 47:36 t:std::sync::Arc<std::cell::RefCell<i32>> {}]` + = note: required because it appears within the type `std::future::from_generator::GenFuture<[static generator@$DIR/issue-68112.rs:47:31: 47:36 t:std::sync::Arc<std::cell::RefCell<i32>> {}]>` + = note: required because it appears within the type `impl std::future::Future` + = note: required because it appears within the type `impl std::future::Future` + = note: required because it appears within the type `impl std::future::Future` + = note: required because it appears within the type `{std::future::ResumeTy, impl std::future::Future, (), i32, Ready<i32>}` + = note: required because it appears within the type `[static generator@$DIR/issue-68112.rs:55:26: 59:6 {std::future::ResumeTy, impl std::future::Future, (), i32, Ready<i32>}]` + = note: required because it appears within the type `std::future::from_generator::GenFuture<[static generator@$DIR/issue-68112.rs:55:26: 59:6 {std::future::ResumeTy, impl std::future::Future, (), i32, Ready<i32>}]>` + = note: required because it appears within the type `impl std::future::Future` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/async-await/issue-70594.stderr b/src/test/ui/async-await/issue-70594.stderr index d2fa7e58f6a..496ca506c60 100644 --- a/src/test/ui/async-await/issue-70594.stderr +++ b/src/test/ui/async-await/issue-70594.stderr @@ -32,11 +32,8 @@ error[E0277]: the trait bound `(): std::future::Future` is not satisfied | LL | [1; ().await]; | ^^^^^^^^ the trait `std::future::Future` is not implemented for `()` - | - ::: $SRC_DIR/libcore/future/mod.rs:LL:COL | -LL | F: Future, - | ------ required by this bound in `std::future::poll_with_context` + = note: required by `std::future::Future::poll` error: aborting due to 5 previous errors diff --git a/src/test/ui/async-await/issues/auxiliary/issue_67893.rs b/src/test/ui/async-await/issues/auxiliary/issue_67893.rs new file mode 100644 index 00000000000..387966a5064 --- /dev/null +++ b/src/test/ui/async-await/issues/auxiliary/issue_67893.rs @@ -0,0 +1,10 @@ +// edition:2018 + +use std::sync::{Arc, Mutex}; + +pub async fn f(_: ()) {} + +pub async fn run() { + let x: Arc<Mutex<()>> = unimplemented!(); + f(*x.lock().unwrap()).await; +} diff --git a/src/test/ui/async-await/issues/issue-62009-1.stderr b/src/test/ui/async-await/issues/issue-62009-1.stderr index 2417b592c7d..ec4e9e397a8 100644 --- a/src/test/ui/async-await/issues/issue-62009-1.stderr +++ b/src/test/ui/async-await/issues/issue-62009-1.stderr @@ -32,11 +32,8 @@ error[E0277]: the trait bound `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]: std: | LL | (|_| 2333).await; | ^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]` - | - ::: $SRC_DIR/libcore/future/mod.rs:LL:COL | -LL | F: Future, - | ------ required by this bound in `std::future::poll_with_context` + = note: required by `std::future::Future::poll` error: aborting due to 4 previous errors diff --git a/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr b/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr index 73e2a92d815..49cd30e11a0 100644 --- a/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr +++ b/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr @@ -5,7 +5,7 @@ LL | fn assert_send<T: Send>(_: T) {} | ---- required by this bound in `assert_send` ... LL | assert_send(async { - | ^^^^^^^^^^^ future returned by `main` is not `Send` + | ^^^^^^^^^^^ future created by async block is not `Send` | = help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `*const u8` note: future is not `Send` as this value is used across an await @@ -14,7 +14,7 @@ note: future is not `Send` as this value is used across an await LL | bar(Foo(std::ptr::null())).await; | ^^^^^^^^----------------^^^^^^^^- `std::ptr::null()` is later dropped here | | | - | | has type `*const u8` + | | has type `*const u8` which is not `Send` | await occurs here, with `std::ptr::null()` maybe used later help: consider moving this into a `let` binding to create a shorter lived borrow --> $DIR/issue-65436-raw-ptr-not-send.rs:14:13 diff --git a/src/test/ui/async-await/issues/issue-67893.rs b/src/test/ui/async-await/issues/issue-67893.rs new file mode 100644 index 00000000000..d52303ac1ce --- /dev/null +++ b/src/test/ui/async-await/issues/issue-67893.rs @@ -0,0 +1,13 @@ +// aux-build: issue_67893.rs +// edition:2018 +// dont-check-compiler-stderr +// FIXME(#71222): Add above flag because of the difference of stderrs on some env. + +extern crate issue_67893; + +fn g(_: impl Send) {} + +fn main() { + g(issue_67893::run()) + //~^ ERROR: `std::sync::MutexGuard<'_, ()>` cannot be sent between threads safely +} diff --git a/src/test/ui/async-await/no-params-non-move-async-closure.stderr b/src/test/ui/async-await/no-params-non-move-async-closure.stderr index 04c8c325fe7..1f589c516a9 100644 --- a/src/test/ui/async-await/no-params-non-move-async-closure.stderr +++ b/src/test/ui/async-await/no-params-non-move-async-closure.stderr @@ -8,3 +8,4 @@ LL | let _ = async |x: u8| {}; error: aborting due to previous error +For more information about this error, try `rustc --explain E0708`. diff --git a/src/test/ui/closures/closure-array-break-length.rs b/src/test/ui/closures/closure-array-break-length.rs index f3567db1fac..fda590fda02 100644 --- a/src/test/ui/closures/closure-array-break-length.rs +++ b/src/test/ui/closures/closure-array-break-length.rs @@ -2,8 +2,6 @@ fn main() { |_: [_; continue]| {}; //~ ERROR: `continue` outside of a loop while |_: [_; continue]| {} {} //~ ERROR: `continue` outside of a loop - //~^ ERROR mismatched types while |_: [_; break]| {} {} //~ ERROR: `break` outside of a loop - //~^ ERROR mismatched types } diff --git a/src/test/ui/closures/closure-array-break-length.stderr b/src/test/ui/closures/closure-array-break-length.stderr index f6991a23f4d..2b8ab9bfc44 100644 --- a/src/test/ui/closures/closure-array-break-length.stderr +++ b/src/test/ui/closures/closure-array-break-length.stderr @@ -11,30 +11,11 @@ LL | while |_: [_; continue]| {} {} | ^^^^^^^^ cannot `continue` outside of a loop error[E0268]: `break` outside of a loop - --> $DIR/closure-array-break-length.rs:7:19 + --> $DIR/closure-array-break-length.rs:6:19 | LL | while |_: [_; break]| {} {} | ^^^^^ cannot `break` outside of a loop -error[E0308]: mismatched types - --> $DIR/closure-array-break-length.rs:4:11 - | -LL | while |_: [_; continue]| {} {} - | ^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found closure - | - = note: expected type `bool` - found closure `[closure@$DIR/closure-array-break-length.rs:4:11: 4:32]` - -error[E0308]: mismatched types - --> $DIR/closure-array-break-length.rs:7:11 - | -LL | while |_: [_; break]| {} {} - | ^^^^^^^^^^^^^^^^^^ expected `bool`, found closure - | - = note: expected type `bool` - found closure `[closure@$DIR/closure-array-break-length.rs:7:11: 7:29]` - -error: aborting due to 5 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0268, E0308. -For more information about an error, try `rustc --explain E0268`. +For more information about this error, try `rustc --explain E0268`. diff --git a/src/test/ui/const-generics/const-fn-with-const-param.rs b/src/test/ui/const-generics/const-fn-with-const-param.rs index e9e236be556..3d8b77bcf7b 100644 --- a/src/test/ui/const-generics/const-fn-with-const-param.rs +++ b/src/test/ui/const-generics/const-fn-with-const-param.rs @@ -1,11 +1,11 @@ +// run-pass #![feature(const_generics)] //~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash const fn const_u32_identity<const X: u32>() -> u32 { - //~^ ERROR const parameters are not permitted in const functions X } fn main() { - println!("{:?}", const_u32_identity::<18>()); + assert_eq!(const_u32_identity::<18>(), 18); } diff --git a/src/test/ui/const-generics/const-fn-with-const-param.stderr b/src/test/ui/const-generics/const-fn-with-const-param.stderr index e944b02101e..64b9c18a8f5 100644 --- a/src/test/ui/const-generics/const-fn-with-const-param.stderr +++ b/src/test/ui/const-generics/const-fn-with-const-param.stderr @@ -1,23 +1,10 @@ -error: const parameters are not permitted in const functions - --> $DIR/const-fn-with-const-param.rs:4:1 - | -LL | const fn const_u32_identity<const X: u32>() -> u32 { - | ^---- - | | - | _`const` because of this - | | -LL | | -LL | | X -LL | | } - | |_^ - warning: the feature `const_generics` is incomplete and may cause the compiler to crash - --> $DIR/const-fn-with-const-param.rs:1:12 + --> $DIR/const-fn-with-const-param.rs:2:12 | LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ | = note: `#[warn(incomplete_features)]` on by default -error: aborting due to previous error; 1 warning emitted +warning: 1 warning emitted diff --git a/src/test/ui/const-generics/issues/issue-62456.rs b/src/test/ui/const-generics/issues/issue-62456.rs index 14b1190df0f..5d068eb7fc8 100644 --- a/src/test/ui/const-generics/issues/issue-62456.rs +++ b/src/test/ui/const-generics/issues/issue-62456.rs @@ -1,10 +1,9 @@ #![feature(const_generics)] //~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash -// build-pass - fn foo<const N: usize>() { let _ = [0u64; N + 1]; + //~^ ERROR constant expression depends on a generic parameter } fn main() {} diff --git a/src/test/ui/const-generics/issues/issue-62456.stderr b/src/test/ui/const-generics/issues/issue-62456.stderr index fc26f68d235..96a07110e73 100644 --- a/src/test/ui/const-generics/issues/issue-62456.stderr +++ b/src/test/ui/const-generics/issues/issue-62456.stderr @@ -6,5 +6,13 @@ LL | #![feature(const_generics)] | = note: `#[warn(incomplete_features)]` on by default -warning: 1 warning emitted +error: constant expression depends on a generic parameter + --> $DIR/issue-62456.rs:5:20 + | +LL | let _ = [0u64; N + 1]; + | ^^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/const-generics/issues/issue-62504.rs b/src/test/ui/const-generics/issues/issue-62504.rs index 212e16253f6..264e693a008 100644 --- a/src/test/ui/const-generics/issues/issue-62504.rs +++ b/src/test/ui/const-generics/issues/issue-62504.rs @@ -17,6 +17,7 @@ impl<const X: usize> ArrayHolder<X> { pub const fn new() -> Self { ArrayHolder([0; Self::SIZE]) //~^ ERROR: mismatched types + //~| ERROR constant expression depends on a generic parameter } } diff --git a/src/test/ui/const-generics/issues/issue-62504.stderr b/src/test/ui/const-generics/issues/issue-62504.stderr index 4482389bbdd..a3a864f770c 100644 --- a/src/test/ui/const-generics/issues/issue-62504.stderr +++ b/src/test/ui/const-generics/issues/issue-62504.stderr @@ -7,6 +7,14 @@ LL | ArrayHolder([0; Self::SIZE]) = note: expected array `[u32; _]` found array `[u32; _]` -error: aborting due to previous error +error: constant expression depends on a generic parameter + --> $DIR/issue-62504.rs:18:25 + | +LL | ArrayHolder([0; Self::SIZE]) + | ^^^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/const-generics/issues/issue-66205.rs b/src/test/ui/const-generics/issues/issue-66205.rs index 2e47b4d1882..73ba4fa6aae 100644 --- a/src/test/ui/const-generics/issues/issue-66205.rs +++ b/src/test/ui/const-generics/issues/issue-66205.rs @@ -1,10 +1,9 @@ -// check-pass - #![allow(incomplete_features, dead_code, unconditional_recursion)] #![feature(const_generics)] fn fact<const N: usize>() { fact::<{ N - 1 }>(); + //~^ ERROR constant expression depends on a generic parameter } fn main() {} diff --git a/src/test/ui/const-generics/issues/issue-66205.stderr b/src/test/ui/const-generics/issues/issue-66205.stderr new file mode 100644 index 00000000000..2bd013e8b41 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-66205.stderr @@ -0,0 +1,10 @@ +error: constant expression depends on a generic parameter + --> $DIR/issue-66205.rs:5:12 + | +LL | fact::<{ N - 1 }>(); + | ^^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: aborting due to previous error + diff --git a/src/test/ui/const-generics/issues/issue-67739.rs b/src/test/ui/const-generics/issues/issue-67739.rs index 3d657b0947b..c8ee1821239 100644 --- a/src/test/ui/const-generics/issues/issue-67739.rs +++ b/src/test/ui/const-generics/issues/issue-67739.rs @@ -1,7 +1,5 @@ // Regression test for #67739 -// check-pass - #![allow(incomplete_features)] #![feature(const_generics)] @@ -12,6 +10,7 @@ pub trait Trait { fn associated_size(&self) -> usize { [0u8; mem::size_of::<Self::Associated>()]; + //~^ ERROR constant expression depends on a generic parameter 0 } } diff --git a/src/test/ui/const-generics/issues/issue-67739.stderr b/src/test/ui/const-generics/issues/issue-67739.stderr new file mode 100644 index 00000000000..27a56b8eb02 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-67739.stderr @@ -0,0 +1,10 @@ +error: constant expression depends on a generic parameter + --> $DIR/issue-67739.rs:12:15 + | +LL | [0u8; mem::size_of::<Self::Associated>()]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: aborting due to previous error + diff --git a/src/test/ui/consts/const-eval/const-eval-overflow-3.rs b/src/test/ui/consts/const-eval/const-eval-overflow-3.rs index 3ae55ebdbaf..6fd8e9cbc80 100644 --- a/src/test/ui/consts/const-eval/const-eval-overflow-3.rs +++ b/src/test/ui/consts/const-eval/const-eval-overflow-3.rs @@ -19,7 +19,6 @@ const A_I8_I : [u32; (i8::MAX as usize) + 1] = [0; (i8::MAX + 1) as usize]; //~^ ERROR evaluation of constant value failed -//~| ERROR mismatched types fn main() { foo(&A_I8_I[..]); diff --git a/src/test/ui/consts/const-eval/const-eval-overflow-3.stderr b/src/test/ui/consts/const-eval/const-eval-overflow-3.stderr index 94b7c12fc1a..2c5b4607aa4 100644 --- a/src/test/ui/consts/const-eval/const-eval-overflow-3.stderr +++ b/src/test/ui/consts/const-eval/const-eval-overflow-3.stderr @@ -4,16 +4,6 @@ error[E0080]: evaluation of constant value failed LL | = [0; (i8::MAX + 1) as usize]; | ^^^^^^^^^^^^^ attempt to add with overflow -error[E0308]: mismatched types - --> $DIR/const-eval-overflow-3.rs:20:7 - | -LL | = [0; (i8::MAX + 1) as usize]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `128usize`, found `(i8::MAX + 1) as usize` - | - = note: expected array `[u32; 128]` - found array `[u32; _]` - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0080, E0308. -For more information about an error, try `rustc --explain E0080`. +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/const-eval-overflow-3b.rs b/src/test/ui/consts/const-eval/const-eval-overflow-3b.rs index e7b88e00feb..db6f17a671a 100644 --- a/src/test/ui/consts/const-eval/const-eval-overflow-3b.rs +++ b/src/test/ui/consts/const-eval/const-eval-overflow-3b.rs @@ -18,7 +18,6 @@ const A_I8_I = [0; (i8::MAX + 1u8) as usize]; //~^ ERROR mismatched types //~| ERROR cannot add `u8` to `i8` -//~| ERROR mismatched types fn main() { foo(&A_I8_I[..]); diff --git a/src/test/ui/consts/const-eval/const-eval-overflow-3b.stderr b/src/test/ui/consts/const-eval/const-eval-overflow-3b.stderr index aebe4feef8d..3da34fe9af7 100644 --- a/src/test/ui/consts/const-eval/const-eval-overflow-3b.stderr +++ b/src/test/ui/consts/const-eval/const-eval-overflow-3b.stderr @@ -12,16 +12,7 @@ LL | = [0; (i8::MAX + 1u8) as usize]; | = help: the trait `std::ops::Add<u8>` is not implemented for `i8` -error[E0308]: mismatched types - --> $DIR/const-eval-overflow-3b.rs:18:7 - | -LL | = [0; (i8::MAX + 1u8) as usize]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `128usize`, found `(i8::MAX + 1u8) as usize` - | - = note: expected array `[u32; 128]` - found array `[u32; _]` - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors Some errors have detailed explanations: E0277, E0308. For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/consts/const-eval/issue-52442.rs b/src/test/ui/consts/const-eval/issue-52442.rs index df4cc8e3026..07fb491015a 100644 --- a/src/test/ui/consts/const-eval/issue-52442.rs +++ b/src/test/ui/consts/const-eval/issue-52442.rs @@ -1,4 +1,6 @@ fn main() { [(); { &loop { break } as *const _ as usize } ]; //~^ ERROR `loop` is not allowed in a `const` + //~| ERROR casting pointers to integers in constants is unstable + //~| ERROR evaluation of constant value failed } diff --git a/src/test/ui/consts/const-eval/issue-52442.stderr b/src/test/ui/consts/const-eval/issue-52442.stderr index 0ea974f1f66..eda2dbf0b6b 100644 --- a/src/test/ui/consts/const-eval/issue-52442.stderr +++ b/src/test/ui/consts/const-eval/issue-52442.stderr @@ -7,6 +7,22 @@ LL | [(); { &loop { break } as *const _ as usize } ]; = note: see issue #52000 <https://github.com/rust-lang/rust/issues/52000> for more information = help: add `#![feature(const_loop)]` to the crate attributes to enable -error: aborting due to previous error +error[E0658]: casting pointers to integers in constants is unstable + --> $DIR/issue-52442.rs:2:13 + | +LL | [(); { &loop { break } as *const _ as usize } ]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #51910 <https://github.com/rust-lang/rust/issues/51910> for more information + = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable + +error[E0080]: evaluation of constant value failed + --> $DIR/issue-52442.rs:2:13 + | +LL | [(); { &loop { break } as *const _ as usize } ]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ "pointer-to-integer cast" needs an rfc before being allowed inside constants + +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0658`. +Some errors have detailed explanations: E0080, E0658. +For more information about an error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/match-test-ptr-null.rs b/src/test/ui/consts/const-eval/match-test-ptr-null.rs index 5cfe36f57e6..80494d16629 100644 --- a/src/test/ui/consts/const-eval/match-test-ptr-null.rs +++ b/src/test/ui/consts/const-eval/match-test-ptr-null.rs @@ -2,7 +2,7 @@ fn main() { // Make sure match uses the usual pointer comparison code path -- i.e., it should complain // that pointer comparison is disallowed, not that parts of a pointer are accessed as raw // bytes. - let _: [u8; 0] = [4; { //~ ERROR mismatched types + let _: [u8; 0] = [4; { match &1 as *const i32 as usize { //~^ ERROR casting pointers to integers in constants //~| ERROR `match` is not allowed in a `const` diff --git a/src/test/ui/consts/const-eval/match-test-ptr-null.stderr b/src/test/ui/consts/const-eval/match-test-ptr-null.stderr index 7c4da5e7d86..b47f6d5f845 100644 --- a/src/test/ui/consts/const-eval/match-test-ptr-null.stderr +++ b/src/test/ui/consts/const-eval/match-test-ptr-null.stderr @@ -28,30 +28,7 @@ error[E0080]: evaluation of constant value failed LL | match &1 as *const i32 as usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^ "pointer-to-integer cast" needs an rfc before being allowed inside constants -error[E0308]: mismatched types - --> $DIR/match-test-ptr-null.rs:5:22 - | -LL | let _: [u8; 0] = [4; { - | ____________-------___^ - | | | - | | expected due to this -LL | | match &1 as *const i32 as usize { -LL | | -LL | | -... | -LL | | } -LL | | }]; - | |______^ expected `0usize`, found `{ - match &1 as *const i32 as usize { - 0 => 42, - n => n, - } - }` - | - = note: expected array `[u8; 0]` - found array `[u8; _]` - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0080, E0308, E0658. +Some errors have detailed explanations: E0080, E0658. For more information about an error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/ub-int-array.rs b/src/test/ui/consts/const-eval/ub-int-array.rs new file mode 100644 index 00000000000..8907b0c160f --- /dev/null +++ b/src/test/ui/consts/const-eval/ub-int-array.rs @@ -0,0 +1,65 @@ +#![feature(const_transmute)] +#![allow(const_err)] // make sure we cannot allow away the errors tested here + +//! Test the "array of int" fast path in validity checking, and in particular whether it +//! points at the right array element. + +use std::mem; + +#[repr(C)] +union MaybeUninit<T: Copy> { + uninit: (), + init: T, +} + +const UNINIT_INT_0: [u32; 3] = unsafe { +//~^ ERROR it is undefined behavior to use this value +//~| type validation failed: encountered uninitialized bytes at [0] + [ + MaybeUninit { uninit: () }.init, + 1, + 2, + ] +}; +const UNINIT_INT_1: [u32; 3] = unsafe { +//~^ ERROR it is undefined behavior to use this value +//~| type validation failed: encountered uninitialized bytes at [1] + mem::transmute( + [ + 0u8, + 0u8, + 0u8, + 0u8, + 1u8, + MaybeUninit { uninit: () }.init, + 1u8, + 1u8, + 2u8, + 2u8, + MaybeUninit { uninit: () }.init, + 2u8, + ] + ) +}; +const UNINIT_INT_2: [u32; 3] = unsafe { +//~^ ERROR it is undefined behavior to use this value +//~| type validation failed: encountered uninitialized bytes at [2] + mem::transmute( + [ + 0u8, + 0u8, + 0u8, + 0u8, + 1u8, + 1u8, + 1u8, + 1u8, + 2u8, + 2u8, + 2u8, + MaybeUninit { uninit: () }.init, + ] + ) +}; + +fn main() {} diff --git a/src/test/ui/consts/const-eval/ub-int-array.stderr b/src/test/ui/consts/const-eval/ub-int-array.stderr new file mode 100644 index 00000000000..b4a3c63b5a1 --- /dev/null +++ b/src/test/ui/consts/const-eval/ub-int-array.stderr @@ -0,0 +1,45 @@ +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-int-array.rs:15:1 + | +LL | / const UNINIT_INT_0: [u32; 3] = unsafe { +LL | | +LL | | +LL | | [ +... | +LL | | ] +LL | | }; + | |__^ type validation failed: encountered uninitialized bytes at [0] + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-int-array.rs:24:1 + | +LL | / const UNINIT_INT_1: [u32; 3] = unsafe { +LL | | +LL | | +LL | | mem::transmute( +... | +LL | | ) +LL | | }; + | |__^ type validation failed: encountered uninitialized bytes at [1] + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + +error[E0080]: it is undefined behavior to use this value + --> $DIR/ub-int-array.rs:44:1 + | +LL | / const UNINIT_INT_2: [u32; 3] = unsafe { +LL | | +LL | | +LL | | mem::transmute( +... | +LL | | ) +LL | | }; + | |__^ type validation failed: encountered uninitialized bytes at [2] + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/ub-ref.rs b/src/test/ui/consts/const-eval/ub-ref.rs index 562ec99111b..10f4c8c0333 100644 --- a/src/test/ui/consts/const-eval/ub-ref.rs +++ b/src/test/ui/consts/const-eval/ub-ref.rs @@ -6,11 +6,11 @@ use std::mem; const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) }; //~^ ERROR it is undefined behavior to use this value -//~^^ type validation failed: encountered an unaligned reference (required 2 byte alignment but found 1) +//~| type validation failed: encountered an unaligned reference (required 2 byte alignment but found 1) const UNALIGNED_BOX: Box<u16> = unsafe { mem::transmute(&[0u8; 4]) }; //~^ ERROR it is undefined behavior to use this value -//~^^ type validation failed: encountered an unaligned box (required 2 byte alignment but found 1) +//~| type validation failed: encountered an unaligned box (required 2 byte alignment but found 1) const NULL: &u16 = unsafe { mem::transmute(0usize) }; //~^ ERROR it is undefined behavior to use this value diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.stderr index 80e60dbb58a..f12753e5dca 100644 --- a/src/test/ui/consts/const-eval/ub-wide-ptr.stderr +++ b/src/test/ui/consts/const-eval/ub-wide-ptr.stderr @@ -62,7 +62,7 @@ LL | | LL | | let uninit_len = MaybeUninit::<usize> { uninit: () }; LL | | mem::transmute((42, uninit_len)) LL | | }; - | |__^ type validation failed: encountered undefined pointer + | |__^ type validation failed: encountered uninitialized reference | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. @@ -130,7 +130,7 @@ LL | | LL | | let uninit_len = MaybeUninit::<usize> { uninit: () }; LL | | mem::transmute((42, uninit_len)) LL | | }; - | |__^ type validation failed: encountered undefined pointer + | |__^ type validation failed: encountered uninitialized raw pointer | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. diff --git a/src/test/ui/consts/const-eval/union-ice.stderr b/src/test/ui/consts/const-eval/union-ice.stderr index 476f3651740..2545167aa02 100644 --- a/src/test/ui/consts/const-eval/union-ice.stderr +++ b/src/test/ui/consts/const-eval/union-ice.stderr @@ -27,7 +27,7 @@ LL | | unsafe { UNION.field3 }, ... | LL | | a: 42, LL | | }; - | |__^ type validation failed: encountered undefined bytes at .b[1] + | |__^ type validation failed: encountered uninitialized bytes at .b[1] | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. diff --git a/src/test/ui/consts/const-integer-bool-ops.rs b/src/test/ui/consts/const-integer-bool-ops.rs index 6924956bdf7..35915a7a606 100644 --- a/src/test/ui/consts/const-integer-bool-ops.rs +++ b/src/test/ui/consts/const-integer-bool-ops.rs @@ -6,7 +6,6 @@ const X: usize = 42 && 39; //~| ERROR mismatched types //~| expected `usize`, found `bool` const ARR: [i32; X] = [99; 34]; -//~^ ERROR evaluation of constant value failed const X1: usize = 42 || 39; //~^ ERROR mismatched types @@ -16,7 +15,6 @@ const X1: usize = 42 || 39; //~| ERROR mismatched types //~| expected `usize`, found `bool` const ARR1: [i32; X1] = [99; 47]; -//~^ ERROR evaluation of constant value failed const X2: usize = -42 || -39; //~^ ERROR mismatched types @@ -26,7 +24,6 @@ const X2: usize = -42 || -39; //~| ERROR mismatched types //~| expected `usize`, found `bool` const ARR2: [i32; X2] = [99; 18446744073709551607]; -//~^ ERROR evaluation of constant value failed const X3: usize = -42 && -39; //~^ ERROR mismatched types @@ -36,43 +33,36 @@ const X3: usize = -42 && -39; //~| ERROR mismatched types //~| expected `usize`, found `bool` const ARR3: [i32; X3] = [99; 6]; -//~^ ERROR evaluation of constant value failed const Y: usize = 42.0 == 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR: [i32; Y] = [99; 1]; -//~^ ERROR evaluation of constant value failed const Y1: usize = 42.0 >= 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR1: [i32; Y1] = [99; 1]; -//~^ ERROR evaluation of constant value failed const Y2: usize = 42.0 <= 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR2: [i32; Y2] = [99; 1]; -//~^ ERROR evaluation of constant value failed const Y3: usize = 42.0 > 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR3: [i32; Y3] = [99; 0]; -//~^ ERROR evaluation of constant value failed const Y4: usize = 42.0 < 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR4: [i32; Y4] = [99; 0]; -//~^ ERROR evaluation of constant value failed const Y5: usize = 42.0 != 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR5: [i32; Y5] = [99; 0]; -//~^ ERROR evaluation of constant value failed fn main() { let _ = ARR; diff --git a/src/test/ui/consts/const-integer-bool-ops.stderr b/src/test/ui/consts/const-integer-bool-ops.stderr index 9001fefd102..4e503e5a5c0 100644 --- a/src/test/ui/consts/const-integer-bool-ops.stderr +++ b/src/test/ui/consts/const-integer-bool-ops.stderr @@ -16,157 +16,96 @@ error[E0308]: mismatched types LL | const X: usize = 42 && 39; | ^^^^^^^^ expected `usize`, found `bool` -error[E0080]: evaluation of constant value failed - --> $DIR/const-integer-bool-ops.rs:8:18 - | -LL | const ARR: [i32; X] = [99; 34]; - | ^ referenced constant has errors - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:11:19 + --> $DIR/const-integer-bool-ops.rs:10:19 | LL | const X1: usize = 42 || 39; | ^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:11:25 + --> $DIR/const-integer-bool-ops.rs:10:25 | LL | const X1: usize = 42 || 39; | ^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:11:19 + --> $DIR/const-integer-bool-ops.rs:10:19 | LL | const X1: usize = 42 || 39; | ^^^^^^^^ expected `usize`, found `bool` -error[E0080]: evaluation of constant value failed - --> $DIR/const-integer-bool-ops.rs:18:19 - | -LL | const ARR1: [i32; X1] = [99; 47]; - | ^^ referenced constant has errors - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:21:19 + --> $DIR/const-integer-bool-ops.rs:19:19 | LL | const X2: usize = -42 || -39; | ^^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:21:26 + --> $DIR/const-integer-bool-ops.rs:19:26 | LL | const X2: usize = -42 || -39; | ^^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:21:19 + --> $DIR/const-integer-bool-ops.rs:19:19 | LL | const X2: usize = -42 || -39; | ^^^^^^^^^^ expected `usize`, found `bool` -error[E0080]: evaluation of constant value failed - --> $DIR/const-integer-bool-ops.rs:28:19 - | -LL | const ARR2: [i32; X2] = [99; 18446744073709551607]; - | ^^ referenced constant has errors - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:31:19 + --> $DIR/const-integer-bool-ops.rs:28:19 | LL | const X3: usize = -42 && -39; | ^^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:31:26 + --> $DIR/const-integer-bool-ops.rs:28:26 | LL | const X3: usize = -42 && -39; | ^^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:31:19 + --> $DIR/const-integer-bool-ops.rs:28:19 | LL | const X3: usize = -42 && -39; | ^^^^^^^^^^ expected `usize`, found `bool` -error[E0080]: evaluation of constant value failed - --> $DIR/const-integer-bool-ops.rs:38:19 - | -LL | const ARR3: [i32; X3] = [99; 6]; - | ^^ referenced constant has errors - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:41:18 + --> $DIR/const-integer-bool-ops.rs:37:18 | LL | const Y: usize = 42.0 == 42.0; | ^^^^^^^^^^^^ expected `usize`, found `bool` -error[E0080]: evaluation of constant value failed - --> $DIR/const-integer-bool-ops.rs:44:19 - | -LL | const ARRR: [i32; Y] = [99; 1]; - | ^ referenced constant has errors - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:47:19 + --> $DIR/const-integer-bool-ops.rs:42:19 | LL | const Y1: usize = 42.0 >= 42.0; | ^^^^^^^^^^^^ expected `usize`, found `bool` -error[E0080]: evaluation of constant value failed - --> $DIR/const-integer-bool-ops.rs:50:20 - | -LL | const ARRR1: [i32; Y1] = [99; 1]; - | ^^ referenced constant has errors - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:53:19 + --> $DIR/const-integer-bool-ops.rs:47:19 | LL | const Y2: usize = 42.0 <= 42.0; | ^^^^^^^^^^^^ expected `usize`, found `bool` -error[E0080]: evaluation of constant value failed - --> $DIR/const-integer-bool-ops.rs:56:20 - | -LL | const ARRR2: [i32; Y2] = [99; 1]; - | ^^ referenced constant has errors - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:59:19 + --> $DIR/const-integer-bool-ops.rs:52:19 | LL | const Y3: usize = 42.0 > 42.0; | ^^^^^^^^^^^ expected `usize`, found `bool` -error[E0080]: evaluation of constant value failed - --> $DIR/const-integer-bool-ops.rs:62:20 - | -LL | const ARRR3: [i32; Y3] = [99; 0]; - | ^^ referenced constant has errors - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:65:19 + --> $DIR/const-integer-bool-ops.rs:57:19 | LL | const Y4: usize = 42.0 < 42.0; | ^^^^^^^^^^^ expected `usize`, found `bool` -error[E0080]: evaluation of constant value failed - --> $DIR/const-integer-bool-ops.rs:68:20 - | -LL | const ARRR4: [i32; Y4] = [99; 0]; - | ^^ referenced constant has errors - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:71:19 + --> $DIR/const-integer-bool-ops.rs:62:19 | LL | const Y5: usize = 42.0 != 42.0; | ^^^^^^^^^^^^ expected `usize`, found `bool` -error[E0080]: evaluation of constant value failed - --> $DIR/const-integer-bool-ops.rs:74:20 - | -LL | const ARRR5: [i32; Y5] = [99; 0]; - | ^^ referenced constant has errors - -error: aborting due to 28 previous errors +error: aborting due to 18 previous errors -Some errors have detailed explanations: E0080, E0308. -For more information about an error, try `rustc --explain E0080`. +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/consts/const-tup-index-span.rs b/src/test/ui/consts/const-tup-index-span.rs index 763263c6aeb..8057d64369a 100644 --- a/src/test/ui/consts/const-tup-index-span.rs +++ b/src/test/ui/consts/const-tup-index-span.rs @@ -4,7 +4,6 @@ const TUP: (usize,) = 5usize << 64; //~^ ERROR mismatched types //~| expected tuple, found `usize` const ARR: [i32; TUP.0] = []; -//~^ ERROR evaluation of constant value failed fn main() { } diff --git a/src/test/ui/consts/const-tup-index-span.stderr b/src/test/ui/consts/const-tup-index-span.stderr index 8e4a092e40f..6724984d8d7 100644 --- a/src/test/ui/consts/const-tup-index-span.stderr +++ b/src/test/ui/consts/const-tup-index-span.stderr @@ -7,13 +7,6 @@ LL | const TUP: (usize,) = 5usize << 64; = note: expected tuple `(usize,)` found type `usize` -error[E0080]: evaluation of constant value failed - --> $DIR/const-tup-index-span.rs:6:18 - | -LL | const ARR: [i32; TUP.0] = []; - | ^^^ referenced constant has errors - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0080, E0308. -For more information about an error, try `rustc --explain E0080`. +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/consts/issue-52432.rs b/src/test/ui/consts/issue-52432.rs index ded79458e63..d719bf1b971 100644 --- a/src/test/ui/consts/issue-52432.rs +++ b/src/test/ui/consts/issue-52432.rs @@ -6,4 +6,5 @@ fn main() { //~| ERROR: type annotations needed [(); &(static || {}) as *const _ as usize]; //~^ ERROR: closures cannot be static + //~| ERROR evaluation of constant value failed } diff --git a/src/test/ui/consts/issue-52432.stderr b/src/test/ui/consts/issue-52432.stderr index d25c11138f4..e9539d24118 100644 --- a/src/test/ui/consts/issue-52432.stderr +++ b/src/test/ui/consts/issue-52432.stderr @@ -16,7 +16,13 @@ error[E0282]: type annotations needed LL | [(); &(static |x| {}) as *const _ as usize]; | ^ consider giving this closure parameter a type -error: aborting due to 3 previous errors +error[E0080]: evaluation of constant value failed + --> $DIR/issue-52432.rs:7:10 + | +LL | [(); &(static || {}) as *const _ as usize]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ "pointer-to-integer cast" needs an rfc before being allowed inside constants + +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0282, E0697. -For more information about an error, try `rustc --explain E0282`. +Some errors have detailed explanations: E0080, E0282, E0697. +For more information about an error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/issue-70773-mir-typeck-lt-norm.rs b/src/test/ui/consts/issue-70773-mir-typeck-lt-norm.rs new file mode 100644 index 00000000000..07af8310424 --- /dev/null +++ b/src/test/ui/consts/issue-70773-mir-typeck-lt-norm.rs @@ -0,0 +1,15 @@ +// run-pass + +const HASH_LEN: usize = 20; +struct Hash([u8; HASH_LEN]); +fn init_hash(_: &mut [u8; HASH_LEN]) {} + +fn foo<'a>() -> &'a () { + Hash([0; HASH_LEN]); + init_hash(&mut [0; HASH_LEN]); + &() +} + +fn main() { + foo(); +} diff --git a/src/test/ui/consts/miri_unleashed/box.rs b/src/test/ui/consts/miri_unleashed/box.rs new file mode 100644 index 00000000000..049727684d0 --- /dev/null +++ b/src/test/ui/consts/miri_unleashed/box.rs @@ -0,0 +1,14 @@ +// compile-flags: -Zunleash-the-miri-inside-of-you +#![feature(const_mut_refs, box_syntax)] +#![deny(const_err)] + +use std::mem::ManuallyDrop; + +fn main() {} + +static TEST_BAD: &mut i32 = { + &mut *(box 0) + //~^ WARN skipping const check + //~| ERROR could not evaluate static initializer + //~| NOTE heap allocations +}; diff --git a/src/test/ui/consts/miri_unleashed/box.stderr b/src/test/ui/consts/miri_unleashed/box.stderr new file mode 100644 index 00000000000..d1b404ea737 --- /dev/null +++ b/src/test/ui/consts/miri_unleashed/box.stderr @@ -0,0 +1,15 @@ +warning: skipping const checks + --> $DIR/box.rs:10:11 + | +LL | &mut *(box 0) + | ^^^^^^^ + +error[E0080]: could not evaluate static initializer + --> $DIR/box.rs:10:11 + | +LL | &mut *(box 0) + | ^^^^^^^ "heap allocations via `box` keyword" needs an rfc before being allowed inside constants + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/too_generic_eval_ice.rs b/src/test/ui/consts/too_generic_eval_ice.rs index 7e4d4dbe446..3ea5f88f07d 100644 --- a/src/test/ui/consts/too_generic_eval_ice.rs +++ b/src/test/ui/consts/too_generic_eval_ice.rs @@ -4,10 +4,9 @@ impl<A, B> Foo<A, B> { const HOST_SIZE: usize = std::mem::size_of::<B>(); pub fn crash() -> bool { - [5; Self::HOST_SIZE] == [6; 0] //~ ERROR no associated item named `HOST_SIZE` - //~^ the size for values of type `A` cannot be known - //~| the size for values of type `B` cannot be known - //~| binary operation `==` cannot be applied to type `[{integer}; _]` + [5; Self::HOST_SIZE] == [6; 0] + //~^ ERROR constant expression depends on a generic parameter + //~| ERROR binary operation `==` cannot be applied to type `[{integer}; _]` } } diff --git a/src/test/ui/consts/too_generic_eval_ice.stderr b/src/test/ui/consts/too_generic_eval_ice.stderr index 8b57d237516..8b29c533bcc 100644 --- a/src/test/ui/consts/too_generic_eval_ice.stderr +++ b/src/test/ui/consts/too_generic_eval_ice.stderr @@ -1,45 +1,10 @@ -error[E0599]: no associated item named `HOST_SIZE` found for struct `Foo<A, B>` in the current scope - --> $DIR/too_generic_eval_ice.rs:7:19 - | -LL | pub struct Foo<A, B>(A, B); - | --------------------------- associated item `HOST_SIZE` not found for this -... -LL | [5; Self::HOST_SIZE] == [6; 0] - | ^^^^^^^^^ associated item not found in `Foo<A, B>` - | - = note: the method `HOST_SIZE` exists but the following trait bounds were not satisfied: - `A: std::marker::Sized` - `B: std::marker::Sized` - -error[E0277]: the size for values of type `A` cannot be known at compilation time - --> $DIR/too_generic_eval_ice.rs:7:13 - | -LL | pub struct Foo<A, B>(A, B); - | - required by this bound in `Foo` -LL | -LL | impl<A, B> Foo<A, B> { - | - this type parameter needs to be `std::marker::Sized` -... -LL | [5; Self::HOST_SIZE] == [6; 0] - | ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `std::marker::Sized` is not implemented for `A` - = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait> - -error[E0277]: the size for values of type `B` cannot be known at compilation time +error: constant expression depends on a generic parameter --> $DIR/too_generic_eval_ice.rs:7:13 | -LL | pub struct Foo<A, B>(A, B); - | - required by this bound in `Foo` -LL | -LL | impl<A, B> Foo<A, B> { - | - this type parameter needs to be `std::marker::Sized` -... LL | [5; Self::HOST_SIZE] == [6; 0] - | ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | ^^^^^^^^^^^^^^^ | - = help: the trait `std::marker::Sized` is not implemented for `B` - = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait> + = note: this may fail depending on what value the parameter takes error[E0369]: binary operation `==` cannot be applied to type `[{integer}; _]` --> $DIR/too_generic_eval_ice.rs:7:30 @@ -49,7 +14,6 @@ LL | [5; Self::HOST_SIZE] == [6; 0] | | | [{integer}; _] -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0277, E0369, E0599. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0369`. diff --git a/src/test/ui/consts/transmute-size-mismatch-before-typeck.stderr b/src/test/ui/consts/transmute-size-mismatch-before-typeck.stderr index 5a477714596..b4970c82adb 100644 --- a/src/test/ui/consts/transmute-size-mismatch-before-typeck.stderr +++ b/src/test/ui/consts/transmute-size-mismatch-before-typeck.stderr @@ -4,7 +4,7 @@ error: any use of this value will cause an error LL | const ZST: &[u8] = unsafe { std::mem::transmute(1usize) }; | ----------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^--- | | - | tried to transmute from usize to &[u8], but their sizes differed + | transmuting `usize` to `&[u8]` is not possible, because these types do not have the same size | = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/error-codes/E0034.stderr b/src/test/ui/error-codes/E0034.stderr index 7977e529a11..471512ca8f7 100644 --- a/src/test/ui/error-codes/E0034.stderr +++ b/src/test/ui/error-codes/E0034.stderr @@ -14,11 +14,11 @@ note: candidate #2 is defined in an impl of the trait `Trait2` for the type `Tes | LL | fn foo() {} | ^^^^^^^^ -help: disambiguate the method call for candidate #1 +help: disambiguate the associated function for candidate #1 | LL | Trait1::foo() | ^^^^^^^^^^^ -help: disambiguate the method call for candidate #2 +help: disambiguate the associated function for candidate #2 | LL | Trait2::foo() | ^^^^^^^^^^^ diff --git a/src/test/ui/error-codes/E0657.stderr b/src/test/ui/error-codes/E0657.stderr index b24b413600c..df76b45a589 100644 --- a/src/test/ui/error-codes/E0657.stderr +++ b/src/test/ui/error-codes/E0657.stderr @@ -12,3 +12,4 @@ LL | -> Box<for<'a> Id<impl Lt<'a>>> error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0657`. diff --git a/src/test/ui/generator/issue-68112.rs b/src/test/ui/generator/issue-68112.rs new file mode 100644 index 00000000000..9ab2abf7405 --- /dev/null +++ b/src/test/ui/generator/issue-68112.rs @@ -0,0 +1,56 @@ +#![feature(generators, generator_trait)] + +use std::{ + cell::RefCell, + sync::Arc, + pin::Pin, + ops::{Generator, GeneratorState}, +}; + +pub struct Ready<T>(Option<T>); +impl<T> Generator<()> for Ready<T> { + type Return = T; + type Yield = (); + fn resume(mut self: Pin<&mut Self>, _args: ()) -> GeneratorState<(), T> { + GeneratorState::Complete(self.0.take().unwrap()) + } +} +pub fn make_gen1<T>(t: T) -> Ready<T> { + Ready(Some(t)) +} + +fn require_send(_: impl Send) {} + +fn make_non_send_generator() -> impl Generator<Return = Arc<RefCell<i32>>> { + make_gen1(Arc::new(RefCell::new(0))) +} + +fn test1() { + let send_gen = || { + let _non_send_gen = make_non_send_generator(); + yield; + }; + require_send(send_gen); + //~^ ERROR generator cannot be sent between threads +} + +pub fn make_gen2<T>(t: T) -> impl Generator<Return = T> { + || { + yield; + t + } +} +fn make_non_send_generator2() -> impl Generator<Return = Arc<RefCell<i32>>> { + make_gen2(Arc::new(RefCell::new(0))) +} + +fn test2() { + let send_gen = || { + let _non_send_gen = make_non_send_generator2(); + yield; + }; + require_send(send_gen); + //~^ ERROR `std::cell::RefCell<i32>` cannot be shared between threads safely +} + +fn main() {} diff --git a/src/test/ui/generator/issue-68112.stderr b/src/test/ui/generator/issue-68112.stderr new file mode 100644 index 00000000000..83536f2af14 --- /dev/null +++ b/src/test/ui/generator/issue-68112.stderr @@ -0,0 +1,40 @@ +error: generator cannot be sent between threads safely + --> $DIR/issue-68112.rs:33:5 + | +LL | fn require_send(_: impl Send) {} + | ---- required by this bound in `require_send` +... +LL | require_send(send_gen); + | ^^^^^^^^^^^^ generator is not `Send` + | + = help: the trait `std::marker::Sync` is not implemented for `std::cell::RefCell<i32>` +note: generator is not `Send` as this value is used across a yield + --> $DIR/issue-68112.rs:31:9 + | +LL | let _non_send_gen = make_non_send_generator(); + | ------------- has type `impl std::ops::Generator` which is not `Send` +LL | yield; + | ^^^^^ yield occurs here, with `_non_send_gen` maybe used later +LL | }; + | - `_non_send_gen` is later dropped here + +error[E0277]: `std::cell::RefCell<i32>` cannot be shared between threads safely + --> $DIR/issue-68112.rs:52:5 + | +LL | fn require_send(_: impl Send) {} + | ---- required by this bound in `require_send` +... +LL | require_send(send_gen); + | ^^^^^^^^^^^^ `std::cell::RefCell<i32>` cannot be shared between threads safely + | + = help: the trait `std::marker::Sync` is not implemented for `std::cell::RefCell<i32>` + = note: required because of the requirements on the impl of `std::marker::Send` for `std::sync::Arc<std::cell::RefCell<i32>>` + = note: required because it appears within the type `[generator@$DIR/issue-68112.rs:38:5: 41:6 t:std::sync::Arc<std::cell::RefCell<i32>> {()}]` + = note: required because it appears within the type `impl std::ops::Generator` + = note: required because it appears within the type `impl std::ops::Generator` + = note: required because it appears within the type `{impl std::ops::Generator, ()}` + = note: required because it appears within the type `[generator@$DIR/issue-68112.rs:48:20: 51:6 {impl std::ops::Generator, ()}]` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/generator/not-send-sync.rs b/src/test/ui/generator/not-send-sync.rs index 0db01c6f756..8ca5565fb2a 100644 --- a/src/test/ui/generator/not-send-sync.rs +++ b/src/test/ui/generator/not-send-sync.rs @@ -7,7 +7,7 @@ fn main() { fn assert_send<T: Send>(_: T) {} assert_sync(|| { - //~^ ERROR: future cannot be shared between threads safely + //~^ ERROR: generator cannot be shared between threads safely let a = Cell::new(2); yield; }); diff --git a/src/test/ui/generator/not-send-sync.stderr b/src/test/ui/generator/not-send-sync.stderr index 5f5211b5092..5df2c1b52fb 100644 --- a/src/test/ui/generator/not-send-sync.stderr +++ b/src/test/ui/generator/not-send-sync.stderr @@ -11,21 +11,21 @@ LL | assert_send(|| { = note: required because of the requirements on the impl of `std::marker::Send` for `&std::cell::Cell<i32>` = note: required because it appears within the type `[generator@$DIR/not-send-sync.rs:16:17: 20:6 a:&std::cell::Cell<i32> _]` -error: future cannot be shared between threads safely +error: generator cannot be shared between threads safely --> $DIR/not-send-sync.rs:9:5 | LL | fn assert_sync<T: Sync>(_: T) {} | ---- required by this bound in `main::assert_sync` ... LL | assert_sync(|| { - | ^^^^^^^^^^^ future returned by `main` is not `Sync` + | ^^^^^^^^^^^ generator is not `Sync` | = help: within `[generator@$DIR/not-send-sync.rs:9:17: 13:6 {std::cell::Cell<i32>, ()}]`, the trait `std::marker::Sync` is not implemented for `std::cell::Cell<i32>` -note: future is not `Sync` as this value is used across an yield +note: generator is not `Sync` as this value is used across a yield --> $DIR/not-send-sync.rs:12:9 | LL | let a = Cell::new(2); - | - has type `std::cell::Cell<i32>` + | - has type `std::cell::Cell<i32>` which is not `Sync` LL | yield; | ^^^^^ yield occurs here, with `a` maybe used later LL | }); diff --git a/src/test/ui/inference/inference_unstable_featured.stderr b/src/test/ui/inference/inference_unstable_featured.stderr index fa908440e41..e23b934ac18 100644 --- a/src/test/ui/inference/inference_unstable_featured.stderr +++ b/src/test/ui/inference/inference_unstable_featured.stderr @@ -6,11 +6,11 @@ LL | assert_eq!('x'.ipu_flatten(), 0); | = note: candidate #1 is defined in an impl of the trait `inference_unstable_iterator::IpuIterator` for the type `char` = note: candidate #2 is defined in an impl of the trait `inference_unstable_itertools::IpuItertools` for the type `char` -help: disambiguate the method call for candidate #1 +help: disambiguate the associated function for candidate #1 | LL | assert_eq!(inference_unstable_iterator::IpuIterator::ipu_flatten(&'x'), 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: disambiguate the method call for candidate #2 +help: disambiguate the associated function for candidate #2 | LL | assert_eq!(inference_unstable_itertools::IpuItertools::ipu_flatten(&'x'), 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/integer-literal-suffix-inference.rs b/src/test/ui/integer-literal-suffix-inference.rs index 3f4bedc4c22..c320f2bb7b4 100644 --- a/src/test/ui/integer-literal-suffix-inference.rs +++ b/src/test/ui/integer-literal-suffix-inference.rs @@ -16,6 +16,7 @@ fn main() { fn id_i16(n: i16) -> i16 { n } fn id_i32(n: i32) -> i32 { n } fn id_i64(n: i64) -> i64 { n } + fn id_isize(n: isize) -> isize { n } // the smallest values that need these types let b8: u8 = 16; @@ -27,6 +28,11 @@ fn main() { fn id_u16(n: u16) -> u16 { n } fn id_u32(n: u32) -> u32 { n } fn id_u64(n: u64) -> u64 { n } + fn id_usize(n: usize) -> usize { n } + + // Values for testing *size + let asize: isize = 1; + let bsize: usize = 3; id_i8(a8); // ok id_i8(a16); @@ -38,6 +44,9 @@ fn main() { id_i8(a64); //~^ ERROR mismatched types //~| expected `i8`, found `i64` + id_i8(asize); + //~^ ERROR mismatched types + //~| expected `i8`, found `isize` id_i16(a8); //~^ ERROR mismatched types @@ -49,6 +58,9 @@ fn main() { id_i16(a64); //~^ ERROR mismatched types //~| expected `i16`, found `i64` + id_i16(asize); + //~^ ERROR mismatched types + //~| expected `i16`, found `isize` id_i32(a8); //~^ ERROR mismatched types @@ -60,6 +72,9 @@ fn main() { id_i32(a64); //~^ ERROR mismatched types //~| expected `i32`, found `i64` + id_i32(asize); + //~^ ERROR mismatched types + //~| expected `i32`, found `isize` id_i64(a8); //~^ ERROR mismatched types @@ -71,6 +86,23 @@ fn main() { //~^ ERROR mismatched types //~| expected `i64`, found `i32` id_i64(a64); // ok + id_i64(asize); + //~^ ERROR mismatched types + //~| expected `i64`, found `isize` + + id_isize(a8); + //~^ ERROR mismatched types + //~| expected `isize`, found `i8` + id_isize(a16); + //~^ ERROR mismatched types + //~| expected `isize`, found `i16` + id_isize(a32); + //~^ ERROR mismatched types + //~| expected `isize`, found `i32` + id_isize(a64); + //~^ ERROR mismatched types + //~| expected `isize`, found `i64` + id_isize(asize); //ok id_i8(c8); // ok id_i8(c16); @@ -126,6 +158,9 @@ fn main() { id_u8(b64); //~^ ERROR mismatched types //~| expected `u8`, found `u64` + id_u8(bsize); + //~^ ERROR mismatched types + //~| expected `u8`, found `usize` id_u16(b8); //~^ ERROR mismatched types @@ -137,6 +172,9 @@ fn main() { id_u16(b64); //~^ ERROR mismatched types //~| expected `u16`, found `u64` + id_u16(bsize); + //~^ ERROR mismatched types + //~| expected `u16`, found `usize` id_u32(b8); //~^ ERROR mismatched types @@ -148,6 +186,9 @@ fn main() { id_u32(b64); //~^ ERROR mismatched types //~| expected `u32`, found `u64` + id_u32(bsize); + //~^ ERROR mismatched types + //~| expected `u32`, found `usize` id_u64(b8); //~^ ERROR mismatched types @@ -159,4 +200,21 @@ fn main() { //~^ ERROR mismatched types //~| expected `u64`, found `u32` id_u64(b64); // ok + id_u64(bsize); + //~^ ERROR mismatched types + //~| expected `u64`, found `usize` + + id_usize(b8); + //~^ ERROR mismatched types + //~| expected `usize`, found `u8` + id_usize(b16); + //~^ ERROR mismatched types + //~| expected `usize`, found `u16` + id_usize(b32); + //~^ ERROR mismatched types + //~| expected `usize`, found `u32` + id_usize(b64); + //~^ ERROR mismatched types + //~| expected `usize`, found `u64` + id_usize(bsize); //ok } diff --git a/src/test/ui/integer-literal-suffix-inference.stderr b/src/test/ui/integer-literal-suffix-inference.stderr index a34f0645c6b..b8502768e1d 100644 --- a/src/test/ui/integer-literal-suffix-inference.stderr +++ b/src/test/ui/integer-literal-suffix-inference.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:32:11 + --> $DIR/integer-literal-suffix-inference.rs:38:11 | LL | id_i8(a16); | ^^^ expected `i8`, found `i16` @@ -10,7 +10,7 @@ LL | id_i8(a16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:35:11 + --> $DIR/integer-literal-suffix-inference.rs:41:11 | LL | id_i8(a32); | ^^^ expected `i8`, found `i32` @@ -21,7 +21,7 @@ LL | id_i8(a32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:38:11 + --> $DIR/integer-literal-suffix-inference.rs:44:11 | LL | id_i8(a64); | ^^^ expected `i8`, found `i64` @@ -32,7 +32,18 @@ LL | id_i8(a64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:42:12 + --> $DIR/integer-literal-suffix-inference.rs:47:11 + | +LL | id_i8(asize); + | ^^^^^ expected `i8`, found `isize` + | +help: you can convert an `isize` to `i8` and panic if the converted value wouldn't fit + | +LL | id_i8(asize.try_into().unwrap()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/integer-literal-suffix-inference.rs:51:12 | LL | id_i16(a8); | ^^ @@ -41,7 +52,7 @@ LL | id_i16(a8); | help: you can convert an `i8` to `i16`: `a8.into()` error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:46:12 + --> $DIR/integer-literal-suffix-inference.rs:55:12 | LL | id_i16(a32); | ^^^ expected `i16`, found `i32` @@ -52,7 +63,7 @@ LL | id_i16(a32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:49:12 + --> $DIR/integer-literal-suffix-inference.rs:58:12 | LL | id_i16(a64); | ^^^ expected `i16`, found `i64` @@ -63,7 +74,18 @@ LL | id_i16(a64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:53:12 + --> $DIR/integer-literal-suffix-inference.rs:61:12 + | +LL | id_i16(asize); + | ^^^^^ expected `i16`, found `isize` + | +help: you can convert an `isize` to `i16` and panic if the converted value wouldn't fit + | +LL | id_i16(asize.try_into().unwrap()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/integer-literal-suffix-inference.rs:65:12 | LL | id_i32(a8); | ^^ @@ -72,7 +94,7 @@ LL | id_i32(a8); | help: you can convert an `i8` to `i32`: `a8.into()` error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:56:12 + --> $DIR/integer-literal-suffix-inference.rs:68:12 | LL | id_i32(a16); | ^^^ @@ -81,7 +103,7 @@ LL | id_i32(a16); | help: you can convert an `i16` to `i32`: `a16.into()` error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:60:12 + --> $DIR/integer-literal-suffix-inference.rs:72:12 | LL | id_i32(a64); | ^^^ expected `i32`, found `i64` @@ -92,7 +114,18 @@ LL | id_i32(a64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:64:12 + --> $DIR/integer-literal-suffix-inference.rs:75:12 + | +LL | id_i32(asize); + | ^^^^^ expected `i32`, found `isize` + | +help: you can convert an `isize` to `i32` and panic if the converted value wouldn't fit + | +LL | id_i32(asize.try_into().unwrap()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/integer-literal-suffix-inference.rs:79:12 | LL | id_i64(a8); | ^^ @@ -101,7 +134,7 @@ LL | id_i64(a8); | help: you can convert an `i8` to `i64`: `a8.into()` error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:67:12 + --> $DIR/integer-literal-suffix-inference.rs:82:12 | LL | id_i64(a16); | ^^^ @@ -110,7 +143,7 @@ LL | id_i64(a16); | help: you can convert an `i16` to `i64`: `a16.into()` error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:70:12 + --> $DIR/integer-literal-suffix-inference.rs:85:12 | LL | id_i64(a32); | ^^^ @@ -119,7 +152,58 @@ LL | id_i64(a32); | help: you can convert an `i32` to `i64`: `a32.into()` error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:76:11 + --> $DIR/integer-literal-suffix-inference.rs:89:12 + | +LL | id_i64(asize); + | ^^^^^ expected `i64`, found `isize` + | +help: you can convert an `isize` to `i64` and panic if the converted value wouldn't fit + | +LL | id_i64(asize.try_into().unwrap()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/integer-literal-suffix-inference.rs:93:14 + | +LL | id_isize(a8); + | ^^ + | | + | expected `isize`, found `i8` + | help: you can convert an `i8` to `isize`: `a8.into()` + +error[E0308]: mismatched types + --> $DIR/integer-literal-suffix-inference.rs:96:14 + | +LL | id_isize(a16); + | ^^^ + | | + | expected `isize`, found `i16` + | help: you can convert an `i16` to `isize`: `a16.into()` + +error[E0308]: mismatched types + --> $DIR/integer-literal-suffix-inference.rs:99:14 + | +LL | id_isize(a32); + | ^^^ expected `isize`, found `i32` + | +help: you can convert an `i32` to `isize` and panic if the converted value wouldn't fit + | +LL | id_isize(a32.try_into().unwrap()); + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/integer-literal-suffix-inference.rs:102:14 + | +LL | id_isize(a64); + | ^^^ expected `isize`, found `i64` + | +help: you can convert an `i64` to `isize` and panic if the converted value wouldn't fit + | +LL | id_isize(a64.try_into().unwrap()); + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/integer-literal-suffix-inference.rs:108:11 | LL | id_i8(c16); | ^^^ expected `i8`, found `i16` @@ -130,7 +214,7 @@ LL | id_i8(c16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:79:11 + --> $DIR/integer-literal-suffix-inference.rs:111:11 | LL | id_i8(c32); | ^^^ expected `i8`, found `i32` @@ -141,7 +225,7 @@ LL | id_i8(c32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:82:11 + --> $DIR/integer-literal-suffix-inference.rs:114:11 | LL | id_i8(c64); | ^^^ expected `i8`, found `i64` @@ -152,7 +236,7 @@ LL | id_i8(c64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:86:12 + --> $DIR/integer-literal-suffix-inference.rs:118:12 | LL | id_i16(c8); | ^^ @@ -161,7 +245,7 @@ LL | id_i16(c8); | help: you can convert an `i8` to `i16`: `c8.into()` error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:90:12 + --> $DIR/integer-literal-suffix-inference.rs:122:12 | LL | id_i16(c32); | ^^^ expected `i16`, found `i32` @@ -172,7 +256,7 @@ LL | id_i16(c32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:93:12 + --> $DIR/integer-literal-suffix-inference.rs:125:12 | LL | id_i16(c64); | ^^^ expected `i16`, found `i64` @@ -183,7 +267,7 @@ LL | id_i16(c64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:97:12 + --> $DIR/integer-literal-suffix-inference.rs:129:12 | LL | id_i32(c8); | ^^ @@ -192,7 +276,7 @@ LL | id_i32(c8); | help: you can convert an `i8` to `i32`: `c8.into()` error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:100:12 + --> $DIR/integer-literal-suffix-inference.rs:132:12 | LL | id_i32(c16); | ^^^ @@ -201,7 +285,7 @@ LL | id_i32(c16); | help: you can convert an `i16` to `i32`: `c16.into()` error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:104:12 + --> $DIR/integer-literal-suffix-inference.rs:136:12 | LL | id_i32(c64); | ^^^ expected `i32`, found `i64` @@ -212,7 +296,7 @@ LL | id_i32(c64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:108:12 + --> $DIR/integer-literal-suffix-inference.rs:140:12 | LL | id_i64(a8); | ^^ @@ -221,7 +305,7 @@ LL | id_i64(a8); | help: you can convert an `i8` to `i64`: `a8.into()` error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:111:12 + --> $DIR/integer-literal-suffix-inference.rs:143:12 | LL | id_i64(a16); | ^^^ @@ -230,7 +314,7 @@ LL | id_i64(a16); | help: you can convert an `i16` to `i64`: `a16.into()` error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:114:12 + --> $DIR/integer-literal-suffix-inference.rs:146:12 | LL | id_i64(a32); | ^^^ @@ -239,7 +323,7 @@ LL | id_i64(a32); | help: you can convert an `i32` to `i64`: `a32.into()` error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:120:11 + --> $DIR/integer-literal-suffix-inference.rs:152:11 | LL | id_u8(b16); | ^^^ expected `u8`, found `u16` @@ -250,7 +334,7 @@ LL | id_u8(b16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:123:11 + --> $DIR/integer-literal-suffix-inference.rs:155:11 | LL | id_u8(b32); | ^^^ expected `u8`, found `u32` @@ -261,7 +345,7 @@ LL | id_u8(b32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:126:11 + --> $DIR/integer-literal-suffix-inference.rs:158:11 | LL | id_u8(b64); | ^^^ expected `u8`, found `u64` @@ -272,7 +356,18 @@ LL | id_u8(b64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:130:12 + --> $DIR/integer-literal-suffix-inference.rs:161:11 + | +LL | id_u8(bsize); + | ^^^^^ expected `u8`, found `usize` + | +help: you can convert an `usize` to `u8` and panic if the converted value wouldn't fit + | +LL | id_u8(bsize.try_into().unwrap()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/integer-literal-suffix-inference.rs:165:12 | LL | id_u16(b8); | ^^ @@ -281,7 +376,7 @@ LL | id_u16(b8); | help: you can convert an `u8` to `u16`: `b8.into()` error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:134:12 + --> $DIR/integer-literal-suffix-inference.rs:169:12 | LL | id_u16(b32); | ^^^ expected `u16`, found `u32` @@ -292,7 +387,7 @@ LL | id_u16(b32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:137:12 + --> $DIR/integer-literal-suffix-inference.rs:172:12 | LL | id_u16(b64); | ^^^ expected `u16`, found `u64` @@ -303,7 +398,18 @@ LL | id_u16(b64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:141:12 + --> $DIR/integer-literal-suffix-inference.rs:175:12 + | +LL | id_u16(bsize); + | ^^^^^ expected `u16`, found `usize` + | +help: you can convert an `usize` to `u16` and panic if the converted value wouldn't fit + | +LL | id_u16(bsize.try_into().unwrap()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/integer-literal-suffix-inference.rs:179:12 | LL | id_u32(b8); | ^^ @@ -312,7 +418,7 @@ LL | id_u32(b8); | help: you can convert an `u8` to `u32`: `b8.into()` error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:144:12 + --> $DIR/integer-literal-suffix-inference.rs:182:12 | LL | id_u32(b16); | ^^^ @@ -321,7 +427,7 @@ LL | id_u32(b16); | help: you can convert an `u16` to `u32`: `b16.into()` error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:148:12 + --> $DIR/integer-literal-suffix-inference.rs:186:12 | LL | id_u32(b64); | ^^^ expected `u32`, found `u64` @@ -332,7 +438,18 @@ LL | id_u32(b64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:152:12 + --> $DIR/integer-literal-suffix-inference.rs:189:12 + | +LL | id_u32(bsize); + | ^^^^^ expected `u32`, found `usize` + | +help: you can convert an `usize` to `u32` and panic if the converted value wouldn't fit + | +LL | id_u32(bsize.try_into().unwrap()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/integer-literal-suffix-inference.rs:193:12 | LL | id_u64(b8); | ^^ @@ -341,7 +458,7 @@ LL | id_u64(b8); | help: you can convert an `u8` to `u64`: `b8.into()` error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:155:12 + --> $DIR/integer-literal-suffix-inference.rs:196:12 | LL | id_u64(b16); | ^^^ @@ -350,7 +467,7 @@ LL | id_u64(b16); | help: you can convert an `u16` to `u64`: `b16.into()` error[E0308]: mismatched types - --> $DIR/integer-literal-suffix-inference.rs:158:12 + --> $DIR/integer-literal-suffix-inference.rs:199:12 | LL | id_u64(b32); | ^^^ @@ -358,6 +475,57 @@ LL | id_u64(b32); | expected `u64`, found `u32` | help: you can convert an `u32` to `u64`: `b32.into()` -error: aborting due to 36 previous errors +error[E0308]: mismatched types + --> $DIR/integer-literal-suffix-inference.rs:203:12 + | +LL | id_u64(bsize); + | ^^^^^ expected `u64`, found `usize` + | +help: you can convert an `usize` to `u64` and panic if the converted value wouldn't fit + | +LL | id_u64(bsize.try_into().unwrap()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/integer-literal-suffix-inference.rs:207:14 + | +LL | id_usize(b8); + | ^^ + | | + | expected `usize`, found `u8` + | help: you can convert an `u8` to `usize`: `b8.into()` + +error[E0308]: mismatched types + --> $DIR/integer-literal-suffix-inference.rs:210:14 + | +LL | id_usize(b16); + | ^^^ + | | + | expected `usize`, found `u16` + | help: you can convert an `u16` to `usize`: `b16.into()` + +error[E0308]: mismatched types + --> $DIR/integer-literal-suffix-inference.rs:213:14 + | +LL | id_usize(b32); + | ^^^ expected `usize`, found `u32` + | +help: you can convert an `u32` to `usize` and panic if the converted value wouldn't fit + | +LL | id_usize(b32.try_into().unwrap()); + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/integer-literal-suffix-inference.rs:216:14 + | +LL | id_usize(b64); + | ^^^ expected `usize`, found `u64` + | +help: you can convert an `u64` to `usize` and panic if the converted value wouldn't fit + | +LL | id_usize(b64.try_into().unwrap()); + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 52 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/intrinsics/issue-28575.rs b/src/test/ui/intrinsics/issue-28575.rs new file mode 100644 index 00000000000..141136d25b2 --- /dev/null +++ b/src/test/ui/intrinsics/issue-28575.rs @@ -0,0 +1,9 @@ +#![feature(intrinsics)] + +extern "C" { + pub static FOO: extern "rust-intrinsic" fn(); +} + +fn main() { + FOO() //~ ERROR: use of extern static is unsafe +} diff --git a/src/test/ui/intrinsics/issue-28575.stderr b/src/test/ui/intrinsics/issue-28575.stderr new file mode 100644 index 00000000000..66369decf42 --- /dev/null +++ b/src/test/ui/intrinsics/issue-28575.stderr @@ -0,0 +1,11 @@ +error[E0133]: use of extern static is unsafe and requires unsafe function or block + --> $DIR/issue-28575.rs:8:5 + | +LL | FOO() + | ^^^ use of extern static + | + = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/issues/issue-18446.stderr b/src/test/ui/issues/issue-18446.stderr index 3422add9dd9..11c8cfdcf66 100644 --- a/src/test/ui/issues/issue-18446.stderr +++ b/src/test/ui/issues/issue-18446.stderr @@ -5,9 +5,9 @@ LL | x.foo(); | --^^^-- | | | | | multiple `foo` found - | help: disambiguate the method call for candidate #2: `T::foo(&x)` + | help: disambiguate the associated function for candidate #2: `T::foo(&x)` | -note: candidate #1 is defined in an impl for the type `dyn T` +note: candidate #1 is defined in an impl for the type `(dyn T + 'a)` --> $DIR/issue-18446.rs:9:5 | LL | fn foo(&self) {} diff --git a/src/test/ui/issues/issue-3702-2.stderr b/src/test/ui/issues/issue-3702-2.stderr index b18e407c3d4..6d8d17292f2 100644 --- a/src/test/ui/issues/issue-3702-2.stderr +++ b/src/test/ui/issues/issue-3702-2.stderr @@ -14,11 +14,11 @@ note: candidate #2 is defined in an impl of the trait `Add` for the type `isize` | LL | fn to_int(&self) -> isize { *self } | ^^^^^^^^^^^^^^^^^^^^^^^^^ -help: disambiguate the method call for candidate #1 +help: disambiguate the associated function for candidate #1 | LL | ToPrimitive::to_int(&self) + other.to_int() | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: disambiguate the method call for candidate #2 +help: disambiguate the associated function for candidate #2 | LL | Add::to_int(&self) + other.to_int() | ^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/issues/issue-39211.rs b/src/test/ui/issues/issue-39211.rs index db101ae248c..c7b6f1d58f3 100644 --- a/src/test/ui/issues/issue-39211.rs +++ b/src/test/ui/issues/issue-39211.rs @@ -8,7 +8,8 @@ trait Mat { } fn m<M: Mat>() { - let a = [3; M::Row::DIM]; //~ ERROR associated type `Row` not found for `M` + let a = [3; M::Row::DIM]; + //~^ ERROR constant expression depends on a generic parameter } fn main() { } diff --git a/src/test/ui/issues/issue-39211.stderr b/src/test/ui/issues/issue-39211.stderr index c14c663e5a1..c555983ea68 100644 --- a/src/test/ui/issues/issue-39211.stderr +++ b/src/test/ui/issues/issue-39211.stderr @@ -1,9 +1,10 @@ -error[E0220]: associated type `Row` not found for `M` - --> $DIR/issue-39211.rs:11:20 +error: constant expression depends on a generic parameter + --> $DIR/issue-39211.rs:11:17 | LL | let a = [3; M::Row::DIM]; - | ^^^ associated type `Row` not found + | ^^^^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes error: aborting due to previous error -For more information about this error, try `rustc --explain E0220`. diff --git a/src/test/ui/issues/issue-39559-2.rs b/src/test/ui/issues/issue-39559-2.rs index ec0275b2d6c..3a52e4d6216 100644 --- a/src/test/ui/issues/issue-39559-2.rs +++ b/src/test/ui/issues/issue-39559-2.rs @@ -17,5 +17,4 @@ fn main() { = [0; Dim3::dim()]; //~^ ERROR E0015 //~| ERROR E0080 - //~| ERROR mismatched types } diff --git a/src/test/ui/issues/issue-39559-2.stderr b/src/test/ui/issues/issue-39559-2.stderr index 7cbf63c2da0..586debbbe53 100644 --- a/src/test/ui/issues/issue-39559-2.stderr +++ b/src/test/ui/issues/issue-39559-2.stderr @@ -22,19 +22,7 @@ error[E0080]: evaluation of constant value failed LL | = [0; Dim3::dim()]; | ^^^^^^^^^^^ calling non-const function `<Dim3 as Dim>::dim` -error[E0308]: mismatched types - --> $DIR/issue-39559-2.rs:17:11 - | -LL | let array: [usize; Dim3::dim()] - | -------------------- expected due to this -... -LL | = [0; Dim3::dim()]; - | ^^^^^^^^^^^^^^^^ expected `Dim3::dim()`, found `Dim3::dim()` - | - = note: expected array `[usize; _]` - found array `[usize; _]` - -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0015, E0080, E0308. +Some errors have detailed explanations: E0015, E0080. For more information about an error, try `rustc --explain E0015`. diff --git a/src/test/ui/issues/issue-41394.rs b/src/test/ui/issues/issue-41394.rs index 64873ac35a0..06a33081340 100644 --- a/src/test/ui/issues/issue-41394.rs +++ b/src/test/ui/issues/issue-41394.rs @@ -5,7 +5,6 @@ enum Foo { enum Bar { A = Foo::A as isize - //~^ ERROR evaluation of constant value failed } fn main() {} diff --git a/src/test/ui/issues/issue-41394.stderr b/src/test/ui/issues/issue-41394.stderr index 47a24547d45..fa95ca9c18a 100644 --- a/src/test/ui/issues/issue-41394.stderr +++ b/src/test/ui/issues/issue-41394.stderr @@ -6,13 +6,6 @@ LL | A = "" + 1 | | | &str -error[E0080]: evaluation of constant value failed - --> $DIR/issue-41394.rs:7:9 - | -LL | A = Foo::A as isize - | ^^^^^^^^^^^^^^^ referenced constant has errors - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0080, E0369. -For more information about an error, try `rustc --explain E0080`. +For more information about this error, try `rustc --explain E0369`. diff --git a/src/test/ui/issues/issue-50599.rs b/src/test/ui/issues/issue-50599.rs index 78a20cf8ebb..00588735b9a 100644 --- a/src/test/ui/issues/issue-50599.rs +++ b/src/test/ui/issues/issue-50599.rs @@ -2,5 +2,4 @@ fn main() { const N: u32 = 1_000; const M: usize = (f64::from(N) * std::f64::LOG10_2) as usize; //~ ERROR cannot find value let mut digits = [0u32; M]; - //~^ ERROR evaluation of constant value failed } diff --git a/src/test/ui/issues/issue-50599.stderr b/src/test/ui/issues/issue-50599.stderr index 5c8cac44438..378c57011ac 100644 --- a/src/test/ui/issues/issue-50599.stderr +++ b/src/test/ui/issues/issue-50599.stderr @@ -11,13 +11,6 @@ LL | use std::f32::consts::LOG10_2; LL | use std::f64::consts::LOG10_2; | -error[E0080]: evaluation of constant value failed - --> $DIR/issue-50599.rs:4:29 - | -LL | let mut digits = [0u32; M]; - | ^ referenced constant has errors - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0080, E0425. -For more information about an error, try `rustc --explain E0080`. +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/issues/issue-52060.rs b/src/test/ui/issues/issue-52060.rs index 2688049fcc9..fed08902c8b 100644 --- a/src/test/ui/issues/issue-52060.rs +++ b/src/test/ui/issues/issue-52060.rs @@ -4,6 +4,5 @@ static A: &'static [u32] = &[1]; static B: [u32; 1] = [0; A.len()]; //~^ ERROR [E0013] //~| ERROR evaluation of constant value failed -//~| ERROR mismatched types fn main() {} diff --git a/src/test/ui/issues/issue-52060.stderr b/src/test/ui/issues/issue-52060.stderr index e076e183937..502825e9766 100644 --- a/src/test/ui/issues/issue-52060.stderr +++ b/src/test/ui/issues/issue-52060.stderr @@ -12,16 +12,7 @@ error[E0080]: evaluation of constant value failed LL | static B: [u32; 1] = [0; A.len()]; | ^ constant accesses static -error[E0308]: mismatched types - --> $DIR/issue-52060.rs:4:22 - | -LL | static B: [u32; 1] = [0; A.len()]; - | ^^^^^^^^^^^^ expected `1usize`, found `A.len()` - | - = note: expected array `[u32; 1]` - found array `[u32; _]` - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0013, E0080, E0308. +Some errors have detailed explanations: E0013, E0080. For more information about an error, try `rustc --explain E0013`. diff --git a/src/test/ui/issues/issue-54954.rs b/src/test/ui/issues/issue-54954.rs index 3d6355f5c59..00805eb5dc9 100644 --- a/src/test/ui/issues/issue-54954.rs +++ b/src/test/ui/issues/issue-54954.rs @@ -11,8 +11,6 @@ trait Tt { } fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] { - //~^ ERROR evaluation of constant value failed - //~| ERROR evaluation of constant value failed z } diff --git a/src/test/ui/issues/issue-54954.stderr b/src/test/ui/issues/issue-54954.stderr index 01ed1383ca2..29d439b457f 100644 --- a/src/test/ui/issues/issue-54954.stderr +++ b/src/test/ui/issues/issue-54954.stderr @@ -15,19 +15,7 @@ LL | const fn const_val<T: Sized>() -> usize { | = note: cannot satisfy `_: Tt` -error[E0080]: evaluation of constant value failed - --> $DIR/issue-54954.rs:13:15 - | -LL | fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] { - | ^^^^^^^ referenced constant has errors - -error[E0080]: evaluation of constant value failed - --> $DIR/issue-54954.rs:13:34 - | -LL | fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] { - | ^^^^^^^ referenced constant has errors - -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0080, E0283, E0379. -For more information about an error, try `rustc --explain E0080`. +Some errors have detailed explanations: E0283, E0379. +For more information about an error, try `rustc --explain E0283`. diff --git a/src/test/ui/issues/issue-65634-raw-ident-suggestion.stderr b/src/test/ui/issues/issue-65634-raw-ident-suggestion.stderr index feaf3dc753f..83d8770b2e0 100644 --- a/src/test/ui/issues/issue-65634-raw-ident-suggestion.stderr +++ b/src/test/ui/issues/issue-65634-raw-ident-suggestion.stderr @@ -14,11 +14,11 @@ note: candidate #2 is defined in an impl of the trait `await` for the type `r#fn | LL | fn r#struct(&self) { | ^^^^^^^^^^^^^^^^^^ -help: disambiguate the method call for candidate #1 +help: disambiguate the associated function for candidate #1 | LL | async::r#struct(&r#fn {}); | ^^^^^^^^^^^^^^^^^^^^^^^^^ -help: disambiguate the method call for candidate #2 +help: disambiguate the associated function for candidate #2 | LL | await::r#struct(&r#fn {}); | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/issues/issue-66706.rs b/src/test/ui/issues/issue-66706.rs index 5e64f63d533..02305191f6e 100644 --- a/src/test/ui/issues/issue-66706.rs +++ b/src/test/ui/issues/issue-66706.rs @@ -10,4 +10,17 @@ fn b() { //~^ ERROR expected identifier, found reserved identifier `_` } +fn c() { + [0; [|&_: _ &_| {}; 0 ].len()] + //~^ ERROR expected `,`, found `&` + //~| ERROR mismatched types +} + +fn d() { + [0; match [|f @ &ref _| () ] {} ] + //~^ ERROR expected identifier, found reserved identifier `_` + //~| ERROR `match` is not allowed in a `const` + //~| ERROR mismatched types +} + fn main() {} diff --git a/src/test/ui/issues/issue-66706.stderr b/src/test/ui/issues/issue-66706.stderr index 6d290bccc7d..ea461cc5d03 100644 --- a/src/test/ui/issues/issue-66706.stderr +++ b/src/test/ui/issues/issue-66706.stderr @@ -12,6 +12,29 @@ error: expected identifier, found reserved identifier `_` LL | [0; [|f @ &ref _| {} ; 0 ].len() ]; | ^ expected identifier, found reserved identifier +error: expected `,`, found `&` + --> $DIR/issue-66706.rs:14:17 + | +LL | [0; [|&_: _ &_| {}; 0 ].len()] + | -^ expected `,` + | | + | help: missing `,` + +error: expected identifier, found reserved identifier `_` + --> $DIR/issue-66706.rs:20:26 + | +LL | [0; match [|f @ &ref _| () ] {} ] + | ^ expected identifier, found reserved identifier + +error[E0658]: `match` is not allowed in a `const` + --> $DIR/issue-66706.rs:20:9 + | +LL | [0; match [|f @ &ref _| () ] {} ] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #49146 <https://github.com/rust-lang/rust/issues/49146> for more information + = help: add `#![feature(const_if_match)]` to the crate attributes to enable + error[E0282]: type annotations needed --> $DIR/issue-66706.rs:2:11 | @@ -26,7 +49,23 @@ LL | fn a() { LL | [0; [|_: _ &_| ()].len()] | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]` -error: aborting due to 4 previous errors +error[E0308]: mismatched types + --> $DIR/issue-66706.rs:14:5 + | +LL | fn c() { + | - help: try adding a return type: `-> [{integer}; _]` +LL | [0; [|&_: _ &_| {}; 0 ].len()] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]` + +error[E0308]: mismatched types + --> $DIR/issue-66706.rs:20:5 + | +LL | fn d() { + | - help: try adding a return type: `-> [{integer}; _]` +LL | [0; match [|f @ &ref _| () ] {} ] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]` + +error: aborting due to 9 previous errors -Some errors have detailed explanations: E0282, E0308. +Some errors have detailed explanations: E0282, E0308, E0658. For more information about an error, try `rustc --explain E0282`. diff --git a/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs index 2c5257ce063..6ac3eb53cb3 100644 --- a/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs +++ b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs @@ -19,4 +19,5 @@ impl TraitB for B { //~ ERROR not all trait items implemented, missing: `MyA` fn main() { let _ = [0; B::VALUE]; + //~^ ERROR constant expression depends on a generic parameter } diff --git a/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr index 8ae0f8b804c..175e6b0eaa0 100644 --- a/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr +++ b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr @@ -13,7 +13,15 @@ LL | type MyA: TraitA; LL | impl TraitB for B { | ^^^^^^^^^^^^^^^^^ missing `MyA` in implementation -error: aborting due to 2 previous errors +error: constant expression depends on a generic parameter + --> $DIR/issue-69602-type-err-during-codegen-ice.rs:21:17 + | +LL | let _ = [0; B::VALUE]; + | ^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: aborting due to 3 previous errors Some errors have detailed explanations: E0046, E0437. For more information about an error, try `rustc --explain E0046`. diff --git a/src/test/ui/issues/issue-69841.rs b/src/test/ui/issues/issue-69841.rs index 942b99b742b..1aca16ca804 100644 --- a/src/test/ui/issues/issue-69841.rs +++ b/src/test/ui/issues/issue-69841.rs @@ -2,6 +2,7 @@ // LLVM bug which needed a fix to be backported. // run-pass +// no-system-llvm fn main() { let buffer = [49u8, 10]; diff --git a/src/test/ui/layout/debug.stderr b/src/test/ui/layout/debug.stderr index 153dec594d3..cd8ebdffb73 100644 --- a/src/test/ui/layout/debug.stderr +++ b/src/test/ui/layout/debug.stderr @@ -316,9 +316,7 @@ LL | type Test = Result<i32, i32>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: layout_of(i32) = Layout { - fields: Union( - 0, - ), + fields: Primitive, variants: Single { index: 0, }, diff --git a/src/test/ui/lifetimes/issue-70917-lifetimes-in-fn-def.rs b/src/test/ui/lifetimes/issue-70917-lifetimes-in-fn-def.rs new file mode 100644 index 00000000000..b9aab27142e --- /dev/null +++ b/src/test/ui/lifetimes/issue-70917-lifetimes-in-fn-def.rs @@ -0,0 +1,13 @@ +// check-pass + +fn assert_static<T: 'static>(_: T) {} + +// NOTE(eddyb) the `'a: 'a` may look a bit strange, but we *really* want +// `'a` to be an *early-bound* parameter, otherwise it doesn't matter anyway. +fn capture_lifetime<'a: 'a>() {} + +fn test_lifetime<'a>() { + assert_static(capture_lifetime::<'a>); +} + +fn main() {} diff --git a/src/test/ui/lint/lint-exceeding-bitshifts.noopt.stderr b/src/test/ui/lint/lint-exceeding-bitshifts.noopt.stderr index ce9b02b6d82..a2fb5ad8b8b 100644 --- a/src/test/ui/lint/lint-exceeding-bitshifts.noopt.stderr +++ b/src/test/ui/lint/lint-exceeding-bitshifts.noopt.stderr @@ -1,146 +1,152 @@ -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:22:13 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:18:20 | -LL | let _ = x << 42; - | ^^^^^^^ attempt to shift left with overflow +LL | const N: i32 = T::N << 42; + | ^^^^^^^^^^ attempt to shift left with overflow | note: the lint level is defined here --> $DIR/lint-exceeding-bitshifts.rs:9:9 | -LL | #![deny(arithmetic_overflow, const_err)] +LL | #![warn(arithmetic_overflow, const_err)] | ^^^^^^^^^^^^^^^^^^^ -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:22:13 + | +LL | let _ = x << 42; + | ^^^^^^^ attempt to shift left with overflow + +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:27:15 | LL | let n = 1u8 << 8; | ^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:29:15 | LL | let n = 1u16 << 16; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:31:15 | LL | let n = 1u32 << 32; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:33:15 | LL | let n = 1u64 << 64; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:35:15 | LL | let n = 1i8 << 8; | ^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:37:15 | LL | let n = 1i16 << 16; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:39:15 | LL | let n = 1i32 << 32; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:41:15 | LL | let n = 1i64 << 64; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:44:15 | LL | let n = 1u8 >> 8; | ^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:46:15 | LL | let n = 1u16 >> 16; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:48:15 | LL | let n = 1u32 >> 32; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:50:15 | LL | let n = 1u64 >> 64; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:52:15 | LL | let n = 1i8 >> 8; | ^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:54:15 | LL | let n = 1i16 >> 16; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:56:15 | LL | let n = 1i32 >> 32; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:58:15 | LL | let n = 1i64 >> 64; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:62:15 | LL | let n = n << 8; | ^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:64:15 | LL | let n = 1u8 << -8; | ^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:69:15 | LL | let n = 1u8 << (4+4); | ^^^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:71:15 | LL | let n = 1i64 >> [64][0]; | ^^^^^^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:77:15 | LL | let n = 1_isize << BITS; | ^^^^^^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:78:15 | LL | let n = 1_usize << BITS; | ^^^^^^^^^^^^^^^ attempt to shift left with overflow -error: aborting due to 23 previous errors +warning: 24 warnings emitted diff --git a/src/test/ui/lint/lint-exceeding-bitshifts.opt.stderr b/src/test/ui/lint/lint-exceeding-bitshifts.opt.stderr index ce9b02b6d82..a2fb5ad8b8b 100644 --- a/src/test/ui/lint/lint-exceeding-bitshifts.opt.stderr +++ b/src/test/ui/lint/lint-exceeding-bitshifts.opt.stderr @@ -1,146 +1,152 @@ -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:22:13 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:18:20 | -LL | let _ = x << 42; - | ^^^^^^^ attempt to shift left with overflow +LL | const N: i32 = T::N << 42; + | ^^^^^^^^^^ attempt to shift left with overflow | note: the lint level is defined here --> $DIR/lint-exceeding-bitshifts.rs:9:9 | -LL | #![deny(arithmetic_overflow, const_err)] +LL | #![warn(arithmetic_overflow, const_err)] | ^^^^^^^^^^^^^^^^^^^ -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:22:13 + | +LL | let _ = x << 42; + | ^^^^^^^ attempt to shift left with overflow + +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:27:15 | LL | let n = 1u8 << 8; | ^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:29:15 | LL | let n = 1u16 << 16; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:31:15 | LL | let n = 1u32 << 32; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:33:15 | LL | let n = 1u64 << 64; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:35:15 | LL | let n = 1i8 << 8; | ^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:37:15 | LL | let n = 1i16 << 16; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:39:15 | LL | let n = 1i32 << 32; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:41:15 | LL | let n = 1i64 << 64; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:44:15 | LL | let n = 1u8 >> 8; | ^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:46:15 | LL | let n = 1u16 >> 16; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:48:15 | LL | let n = 1u32 >> 32; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:50:15 | LL | let n = 1u64 >> 64; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:52:15 | LL | let n = 1i8 >> 8; | ^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:54:15 | LL | let n = 1i16 >> 16; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:56:15 | LL | let n = 1i32 >> 32; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:58:15 | LL | let n = 1i64 >> 64; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:62:15 | LL | let n = n << 8; | ^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:64:15 | LL | let n = 1u8 << -8; | ^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:69:15 | LL | let n = 1u8 << (4+4); | ^^^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:71:15 | LL | let n = 1i64 >> [64][0]; | ^^^^^^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:77:15 | LL | let n = 1_isize << BITS; | ^^^^^^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:78:15 | LL | let n = 1_usize << BITS; | ^^^^^^^^^^^^^^^ attempt to shift left with overflow -error: aborting due to 23 previous errors +warning: 24 warnings emitted diff --git a/src/test/ui/lint/lint-exceeding-bitshifts.opt_with_overflow_checks.stderr b/src/test/ui/lint/lint-exceeding-bitshifts.opt_with_overflow_checks.stderr index ce9b02b6d82..a2fb5ad8b8b 100644 --- a/src/test/ui/lint/lint-exceeding-bitshifts.opt_with_overflow_checks.stderr +++ b/src/test/ui/lint/lint-exceeding-bitshifts.opt_with_overflow_checks.stderr @@ -1,146 +1,152 @@ -error: this arithmetic operation will overflow - --> $DIR/lint-exceeding-bitshifts.rs:22:13 +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:18:20 | -LL | let _ = x << 42; - | ^^^^^^^ attempt to shift left with overflow +LL | const N: i32 = T::N << 42; + | ^^^^^^^^^^ attempt to shift left with overflow | note: the lint level is defined here --> $DIR/lint-exceeding-bitshifts.rs:9:9 | -LL | #![deny(arithmetic_overflow, const_err)] +LL | #![warn(arithmetic_overflow, const_err)] | ^^^^^^^^^^^^^^^^^^^ -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow + --> $DIR/lint-exceeding-bitshifts.rs:22:13 + | +LL | let _ = x << 42; + | ^^^^^^^ attempt to shift left with overflow + +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:27:15 | LL | let n = 1u8 << 8; | ^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:29:15 | LL | let n = 1u16 << 16; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:31:15 | LL | let n = 1u32 << 32; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:33:15 | LL | let n = 1u64 << 64; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:35:15 | LL | let n = 1i8 << 8; | ^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:37:15 | LL | let n = 1i16 << 16; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:39:15 | LL | let n = 1i32 << 32; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:41:15 | LL | let n = 1i64 << 64; | ^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:44:15 | LL | let n = 1u8 >> 8; | ^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:46:15 | LL | let n = 1u16 >> 16; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:48:15 | LL | let n = 1u32 >> 32; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:50:15 | LL | let n = 1u64 >> 64; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:52:15 | LL | let n = 1i8 >> 8; | ^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:54:15 | LL | let n = 1i16 >> 16; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:56:15 | LL | let n = 1i32 >> 32; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:58:15 | LL | let n = 1i64 >> 64; | ^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:62:15 | LL | let n = n << 8; | ^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:64:15 | LL | let n = 1u8 << -8; | ^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:69:15 | LL | let n = 1u8 << (4+4); | ^^^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:71:15 | LL | let n = 1i64 >> [64][0]; | ^^^^^^^^^^^^^^^ attempt to shift right with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:77:15 | LL | let n = 1_isize << BITS; | ^^^^^^^^^^^^^^^ attempt to shift left with overflow -error: this arithmetic operation will overflow +warning: this arithmetic operation will overflow --> $DIR/lint-exceeding-bitshifts.rs:78:15 | LL | let n = 1_usize << BITS; | ^^^^^^^^^^^^^^^ attempt to shift left with overflow -error: aborting due to 23 previous errors +warning: 24 warnings emitted diff --git a/src/test/ui/lint/lint-exceeding-bitshifts.rs b/src/test/ui/lint/lint-exceeding-bitshifts.rs index 7deee5320a8..5d0cfd3ab78 100644 --- a/src/test/ui/lint/lint-exceeding-bitshifts.rs +++ b/src/test/ui/lint/lint-exceeding-bitshifts.rs @@ -3,10 +3,10 @@ //[opt]compile-flags: -O //[opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O -// build-fail +// build-pass #![crate_type="lib"] -#![deny(arithmetic_overflow, const_err)] +#![warn(arithmetic_overflow, const_err)] #![allow(unused_variables)] #![allow(dead_code)] @@ -15,65 +15,65 @@ pub trait Foo { } impl<T: Foo> Foo for Vec<T> { - const N: i32 = T::N << 42; // FIXME this should warn + const N: i32 = T::N << 42; //~ WARN: arithmetic operation will overflow } pub fn foo(x: i32) { - let _ = x << 42; //~ ERROR: arithmetic operation will overflow + let _ = x << 42; //~ WARN: arithmetic operation will overflow } pub fn main() { let n = 1u8 << 7; - let n = 1u8 << 8; //~ ERROR: arithmetic operation will overflow + let n = 1u8 << 8; //~ WARN: arithmetic operation will overflow let n = 1u16 << 15; - let n = 1u16 << 16; //~ ERROR: arithmetic operation will overflow + let n = 1u16 << 16; //~ WARN: arithmetic operation will overflow let n = 1u32 << 31; - let n = 1u32 << 32; //~ ERROR: arithmetic operation will overflow + let n = 1u32 << 32; //~ WARN: arithmetic operation will overflow let n = 1u64 << 63; - let n = 1u64 << 64; //~ ERROR: arithmetic operation will overflow + let n = 1u64 << 64; //~ WARN: arithmetic operation will overflow let n = 1i8 << 7; - let n = 1i8 << 8; //~ ERROR: arithmetic operation will overflow + let n = 1i8 << 8; //~ WARN: arithmetic operation will overflow let n = 1i16 << 15; - let n = 1i16 << 16; //~ ERROR: arithmetic operation will overflow + let n = 1i16 << 16; //~ WARN: arithmetic operation will overflow let n = 1i32 << 31; - let n = 1i32 << 32; //~ ERROR: arithmetic operation will overflow + let n = 1i32 << 32; //~ WARN: arithmetic operation will overflow let n = 1i64 << 63; - let n = 1i64 << 64; //~ ERROR: arithmetic operation will overflow + let n = 1i64 << 64; //~ WARN: arithmetic operation will overflow let n = 1u8 >> 7; - let n = 1u8 >> 8; //~ ERROR: arithmetic operation will overflow + let n = 1u8 >> 8; //~ WARN: arithmetic operation will overflow let n = 1u16 >> 15; - let n = 1u16 >> 16; //~ ERROR: arithmetic operation will overflow + let n = 1u16 >> 16; //~ WARN: arithmetic operation will overflow let n = 1u32 >> 31; - let n = 1u32 >> 32; //~ ERROR: arithmetic operation will overflow + let n = 1u32 >> 32; //~ WARN: arithmetic operation will overflow let n = 1u64 >> 63; - let n = 1u64 >> 64; //~ ERROR: arithmetic operation will overflow + let n = 1u64 >> 64; //~ WARN: arithmetic operation will overflow let n = 1i8 >> 7; - let n = 1i8 >> 8; //~ ERROR: arithmetic operation will overflow + let n = 1i8 >> 8; //~ WARN: arithmetic operation will overflow let n = 1i16 >> 15; - let n = 1i16 >> 16; //~ ERROR: arithmetic operation will overflow + let n = 1i16 >> 16; //~ WARN: arithmetic operation will overflow let n = 1i32 >> 31; - let n = 1i32 >> 32; //~ ERROR: arithmetic operation will overflow + let n = 1i32 >> 32; //~ WARN: arithmetic operation will overflow let n = 1i64 >> 63; - let n = 1i64 >> 64; //~ ERROR: arithmetic operation will overflow + let n = 1i64 >> 64; //~ WARN: arithmetic operation will overflow let n = 1u8; let n = n << 7; - let n = n << 8; //~ ERROR: arithmetic operation will overflow + let n = n << 8; //~ WARN: arithmetic operation will overflow - let n = 1u8 << -8; //~ ERROR: arithmetic operation will overflow + let n = 1u8 << -8; //~ WARN: arithmetic operation will overflow let n = 1i8<<(1isize+-1); let n = 1u8 << (4+3); - let n = 1u8 << (4+4); //~ ERROR: arithmetic operation will overflow + let n = 1u8 << (4+4); //~ WARN: arithmetic operation will overflow let n = 1i64 >> [63][0]; - let n = 1i64 >> [64][0]; //~ ERROR: arithmetic operation will overflow + let n = 1i64 >> [64][0]; //~ WARN: arithmetic operation will overflow #[cfg(target_pointer_width = "32")] const BITS: usize = 32; #[cfg(target_pointer_width = "64")] const BITS: usize = 64; - let n = 1_isize << BITS; //~ ERROR: arithmetic operation will overflow - let n = 1_usize << BITS; //~ ERROR: arithmetic operation will overflow + let n = 1_isize << BITS; //~ WARN: arithmetic operation will overflow + let n = 1_usize << BITS; //~ WARN: arithmetic operation will overflow } diff --git a/src/test/ui/asm/issue-51431.rs b/src/test/ui/llvm-asm/issue-51431.rs index ca06bdab27b..ca06bdab27b 100644 --- a/src/test/ui/asm/issue-51431.rs +++ b/src/test/ui/llvm-asm/issue-51431.rs diff --git a/src/test/ui/asm/issue-51431.stderr b/src/test/ui/llvm-asm/issue-51431.stderr index b4b39a2a44e..b4b39a2a44e 100644 --- a/src/test/ui/asm/issue-51431.stderr +++ b/src/test/ui/llvm-asm/issue-51431.stderr diff --git a/src/test/ui/llvm-asm/issue-54067.rs b/src/test/ui/llvm-asm/issue-54067.rs new file mode 100644 index 00000000000..f2e097222bd --- /dev/null +++ b/src/test/ui/llvm-asm/issue-54067.rs @@ -0,0 +1,12 @@ +// check-pass +// ignore-emscripten no llvm_asm! support + +#![feature(llvm_asm)] + +pub fn boot(addr: Option<u32>) { + unsafe { + llvm_asm!("mov sp, $0"::"r" (addr)); + } +} + +fn main() {} diff --git a/src/test/ui/asm/issue-62046.rs b/src/test/ui/llvm-asm/issue-62046.rs index fd4d9bdd23d..fd4d9bdd23d 100644 --- a/src/test/ui/asm/issue-62046.rs +++ b/src/test/ui/llvm-asm/issue-62046.rs diff --git a/src/test/ui/asm/issue-62046.stderr b/src/test/ui/llvm-asm/issue-62046.stderr index cf27052df05..cf27052df05 100644 --- a/src/test/ui/asm/issue-62046.stderr +++ b/src/test/ui/llvm-asm/issue-62046.stderr diff --git a/src/test/ui/asm/issue-69092.rs b/src/test/ui/llvm-asm/issue-69092.rs index ecce7bfdf5b..ecce7bfdf5b 100644 --- a/src/test/ui/asm/issue-69092.rs +++ b/src/test/ui/llvm-asm/issue-69092.rs diff --git a/src/test/ui/asm/issue-69092.stderr b/src/test/ui/llvm-asm/issue-69092.stderr index 35f77edc3c4..35f77edc3c4 100644 --- a/src/test/ui/asm/issue-69092.stderr +++ b/src/test/ui/llvm-asm/issue-69092.stderr diff --git a/src/test/ui/asm/asm-bad-clobber.rs b/src/test/ui/llvm-asm/llvm-asm-bad-clobber.rs index 9f5662cbd1e..9f5662cbd1e 100644 --- a/src/test/ui/asm/asm-bad-clobber.rs +++ b/src/test/ui/llvm-asm/llvm-asm-bad-clobber.rs diff --git a/src/test/ui/asm/asm-bad-clobber.stderr b/src/test/ui/llvm-asm/llvm-asm-bad-clobber.stderr index 8c5d04694c4..9ecd12caa0e 100644 --- a/src/test/ui/asm/asm-bad-clobber.stderr +++ b/src/test/ui/llvm-asm/llvm-asm-bad-clobber.stderr @@ -1,5 +1,5 @@ error[E0664]: clobber should not be surrounded by braces - --> $DIR/asm-bad-clobber.rs:22:42 + --> $DIR/llvm-asm-bad-clobber.rs:22:42 | LL | llvm_asm!("xor %eax, %eax" : : : "{eax}"); | ^^^^^^^ diff --git a/src/test/ui/asm/asm-in-bad-modifier.rs b/src/test/ui/llvm-asm/llvm-asm-in-bad-modifier.rs index b791ec3e8c8..b791ec3e8c8 100644 --- a/src/test/ui/asm/asm-in-bad-modifier.rs +++ b/src/test/ui/llvm-asm/llvm-asm-in-bad-modifier.rs diff --git a/src/test/ui/asm/asm-in-bad-modifier.stderr b/src/test/ui/llvm-asm/llvm-asm-in-bad-modifier.stderr index f1624f74a70..e94ac94f59f 100644 --- a/src/test/ui/asm/asm-in-bad-modifier.stderr +++ b/src/test/ui/llvm-asm/llvm-asm-in-bad-modifier.stderr @@ -1,11 +1,11 @@ error[E0662]: input operand constraint contains '=' - --> $DIR/asm-in-bad-modifier.rs:23:44 + --> $DIR/llvm-asm-in-bad-modifier.rs:23:44 | LL | llvm_asm!("mov $1, $0" : "=r"(x) : "=r"(5)); | ^^^^ error[E0663]: input operand constraint contains '+' - --> $DIR/asm-in-bad-modifier.rs:24:44 + --> $DIR/llvm-asm-in-bad-modifier.rs:24:44 | LL | llvm_asm!("mov $1, $0" : "=r"(y) : "+r"(5)); | ^^^^ diff --git a/src/test/ui/asm/asm-literal-escaping.rs b/src/test/ui/llvm-asm/llvm-asm-literal-escaping.rs index 5d45f5084c5..5d45f5084c5 100644 --- a/src/test/ui/asm/asm-literal-escaping.rs +++ b/src/test/ui/llvm-asm/llvm-asm-literal-escaping.rs diff --git a/src/test/ui/asm/asm-misplaced-option.rs b/src/test/ui/llvm-asm/llvm-asm-misplaced-option.rs index 3c44fc90ef3..3c44fc90ef3 100644 --- a/src/test/ui/asm/asm-misplaced-option.rs +++ b/src/test/ui/llvm-asm/llvm-asm-misplaced-option.rs diff --git a/src/test/ui/asm/asm-misplaced-option.stderr b/src/test/ui/llvm-asm/llvm-asm-misplaced-option.stderr index ea155b91c5d..21fd27825a1 100644 --- a/src/test/ui/asm/asm-misplaced-option.stderr +++ b/src/test/ui/llvm-asm/llvm-asm-misplaced-option.stderr @@ -1,11 +1,11 @@ warning: unrecognized option - --> $DIR/asm-misplaced-option.rs:24:69 + --> $DIR/llvm-asm-misplaced-option.rs:24:69 | LL | llvm_asm!("mov $1, $0" : "=r"(x) : "r"(5_usize), "0"(x) : : "cc"); | ^^^^ warning: expected a clobber, found an option - --> $DIR/asm-misplaced-option.rs:31:85 + --> $DIR/llvm-asm-misplaced-option.rs:31:85 | LL | llvm_asm!("add $2, $1; mov $1, $0" : "=r"(x) : "r"(x), "r"(8_usize) : "cc", "volatile"); | ^^^^^^^^^^ diff --git a/src/test/ui/asm/asm-out-assign-imm.rs b/src/test/ui/llvm-asm/llvm-asm-out-assign-imm.rs index 1a46879f9f2..1a46879f9f2 100644 --- a/src/test/ui/asm/asm-out-assign-imm.rs +++ b/src/test/ui/llvm-asm/llvm-asm-out-assign-imm.rs diff --git a/src/test/ui/asm/asm-out-assign-imm.stderr b/src/test/ui/llvm-asm/llvm-asm-out-assign-imm.stderr index feec61b4fc6..e110aec2209 100644 --- a/src/test/ui/asm/asm-out-assign-imm.stderr +++ b/src/test/ui/llvm-asm/llvm-asm-out-assign-imm.stderr @@ -1,5 +1,5 @@ error[E0384]: cannot assign twice to immutable variable `x` - --> $DIR/asm-out-assign-imm.rs:24:39 + --> $DIR/llvm-asm-out-assign-imm.rs:24:39 | LL | let x: isize; | - help: make this binding mutable: `mut x` diff --git a/src/test/ui/asm/asm-out-no-modifier.rs b/src/test/ui/llvm-asm/llvm-asm-out-no-modifier.rs index d198437c508..d198437c508 100644 --- a/src/test/ui/asm/asm-out-no-modifier.rs +++ b/src/test/ui/llvm-asm/llvm-asm-out-no-modifier.rs diff --git a/src/test/ui/asm/asm-out-no-modifier.stderr b/src/test/ui/llvm-asm/llvm-asm-out-no-modifier.stderr index 1c9e108f910..1f2b2727924 100644 --- a/src/test/ui/asm/asm-out-no-modifier.stderr +++ b/src/test/ui/llvm-asm/llvm-asm-out-no-modifier.stderr @@ -1,5 +1,5 @@ error[E0661]: output operand constraint lacks '=' or '+' - --> $DIR/asm-out-no-modifier.rs:22:34 + --> $DIR/llvm-asm-out-no-modifier.rs:22:34 | LL | llvm_asm!("mov $1, $0" : "r"(x) : "r"(5)); | ^^^ diff --git a/src/test/ui/asm/asm-out-read-uninit.rs b/src/test/ui/llvm-asm/llvm-asm-out-read-uninit.rs index d45498d4bb4..d45498d4bb4 100644 --- a/src/test/ui/asm/asm-out-read-uninit.rs +++ b/src/test/ui/llvm-asm/llvm-asm-out-read-uninit.rs diff --git a/src/test/ui/asm/asm-out-read-uninit.stderr b/src/test/ui/llvm-asm/llvm-asm-out-read-uninit.stderr index 3c3f3a6febb..a22ebe4e4d9 100644 --- a/src/test/ui/asm/asm-out-read-uninit.stderr +++ b/src/test/ui/llvm-asm/llvm-asm-out-read-uninit.stderr @@ -1,5 +1,5 @@ error[E0381]: use of possibly-uninitialized variable: `x` - --> $DIR/asm-out-read-uninit.rs:22:48 + --> $DIR/llvm-asm-out-read-uninit.rs:22:48 | LL | llvm_asm!("mov $1, $0" : "=r"(x) : "r"(x)); | ^ use of possibly-uninitialized `x` diff --git a/src/test/ui/asm/asm-parse-errors.rs b/src/test/ui/llvm-asm/llvm-asm-parse-errors.rs index d458be81529..d458be81529 100644 --- a/src/test/ui/asm/asm-parse-errors.rs +++ b/src/test/ui/llvm-asm/llvm-asm-parse-errors.rs diff --git a/src/test/ui/asm/asm-parse-errors.stderr b/src/test/ui/llvm-asm/llvm-asm-parse-errors.stderr index 64f295c3b36..1fd46809f3e 100644 --- a/src/test/ui/asm/asm-parse-errors.stderr +++ b/src/test/ui/llvm-asm/llvm-asm-parse-errors.stderr @@ -1,65 +1,65 @@ error: macro requires a string literal as an argument - --> $DIR/asm-parse-errors.rs:4:5 + --> $DIR/llvm-asm-parse-errors.rs:4:5 | LL | llvm_asm!(); | ^^^^^^^^^^^^ string literal required error: expected string literal - --> $DIR/asm-parse-errors.rs:5:23 + --> $DIR/llvm-asm-parse-errors.rs:5:23 | LL | llvm_asm!("nop" : struct); | ^^^^^^ not a string literal error: expected string literal - --> $DIR/asm-parse-errors.rs:6:35 + --> $DIR/llvm-asm-parse-errors.rs:6:35 | LL | llvm_asm!("mov %eax, $$0x2" : struct); | ^^^^^^ not a string literal error: expected `(`, found keyword `struct` - --> $DIR/asm-parse-errors.rs:7:44 + --> $DIR/llvm-asm-parse-errors.rs:7:44 | LL | llvm_asm!("mov %eax, $$0x2" : "={eax}" struct); | ^^^^^^ expected `(` error: expected expression, found keyword `struct` - --> $DIR/asm-parse-errors.rs:8:44 + --> $DIR/llvm-asm-parse-errors.rs:8:44 | LL | llvm_asm!("mov %eax, $$0x2" : "={eax}"(struct)); | ^^^^^^ expected expression error: expected string literal - --> $DIR/asm-parse-errors.rs:9:49 + --> $DIR/llvm-asm-parse-errors.rs:9:49 | LL | llvm_asm!("in %dx, %al" : "={al}"(result) : struct); | ^^^^^^ not a string literal error: expected `(`, found keyword `struct` - --> $DIR/asm-parse-errors.rs:10:56 + --> $DIR/llvm-asm-parse-errors.rs:10:56 | LL | llvm_asm!("in %dx, %al" : "={al}"(result) : "{dx}" struct); | ^^^^^^ expected `(` error: expected expression, found keyword `struct` - --> $DIR/asm-parse-errors.rs:11:56 + --> $DIR/llvm-asm-parse-errors.rs:11:56 | LL | llvm_asm!("in %dx, %al" : "={al}"(result) : "{dx}"(struct)); | ^^^^^^ expected expression error: expected string literal - --> $DIR/asm-parse-errors.rs:12:41 + --> $DIR/llvm-asm-parse-errors.rs:12:41 | LL | llvm_asm!("mov $$0x200, %eax" : : : struct); | ^^^^^^ not a string literal error: expected string literal - --> $DIR/asm-parse-errors.rs:13:50 + --> $DIR/llvm-asm-parse-errors.rs:13:50 | LL | llvm_asm!("mov eax, 2" : "={eax}"(foo) : : : struct); | ^^^^^^ not a string literal error: inline assembly must be a string literal - --> $DIR/asm-parse-errors.rs:14:15 + --> $DIR/llvm-asm-parse-errors.rs:14:15 | LL | llvm_asm!(123); | ^^^ diff --git a/src/test/ui/methods/method-ambig-two-traits-cross-crate.stderr b/src/test/ui/methods/method-ambig-two-traits-cross-crate.stderr index fa3add81a28..1b354fc697a 100644 --- a/src/test/ui/methods/method-ambig-two-traits-cross-crate.stderr +++ b/src/test/ui/methods/method-ambig-two-traits-cross-crate.stderr @@ -10,11 +10,11 @@ note: candidate #1 is defined in an impl of the trait `Me2` for the type `usize` LL | impl Me2 for usize { fn me(&self) -> usize { *self } } | ^^^^^^^^^^^^^^^^^^^^^ = note: candidate #2 is defined in an impl of the trait `ambig_impl_2_lib::Me` for the type `usize` -help: disambiguate the method call for candidate #1 +help: disambiguate the associated function for candidate #1 | LL | fn main() { Me2::me(&1_usize); } | ^^^^^^^^^^^^^^^^^ -help: disambiguate the method call for candidate #2 +help: disambiguate the associated function for candidate #2 | LL | fn main() { ambig_impl_2_lib::Me::me(&1_usize); } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/methods/method-ambig-two-traits-from-bounds.stderr b/src/test/ui/methods/method-ambig-two-traits-from-bounds.stderr index b6c81c2377e..5cbed652b0a 100644 --- a/src/test/ui/methods/method-ambig-two-traits-from-bounds.stderr +++ b/src/test/ui/methods/method-ambig-two-traits-from-bounds.stderr @@ -14,11 +14,11 @@ note: candidate #2 is defined in the trait `B` | LL | trait B { fn foo(&self); } | ^^^^^^^^^^^^^^ -help: disambiguate the method call for candidate #1 +help: disambiguate the associated function for candidate #1 | LL | A::foo(t); | ^^^^^^^^^ -help: disambiguate the method call for candidate #2 +help: disambiguate the associated function for candidate #2 | LL | B::foo(t); | ^^^^^^^^^ diff --git a/src/test/ui/methods/method-ambig-two-traits-from-impls.stderr b/src/test/ui/methods/method-ambig-two-traits-from-impls.stderr index 71c65f7ccc6..8585929934e 100644 --- a/src/test/ui/methods/method-ambig-two-traits-from-impls.stderr +++ b/src/test/ui/methods/method-ambig-two-traits-from-impls.stderr @@ -14,11 +14,11 @@ note: candidate #2 is defined in an impl of the trait `B` for the type `AB` | LL | fn foo(self) {} | ^^^^^^^^^^^^ -help: disambiguate the method call for candidate #1 +help: disambiguate the associated function for candidate #1 | LL | A::foo(AB {}); | ^^^^^^^^^^^^^ -help: disambiguate the method call for candidate #2 +help: disambiguate the associated function for candidate #2 | LL | B::foo(AB {}); | ^^^^^^^^^^^^^ diff --git a/src/test/ui/methods/method-ambig-two-traits-from-impls2.stderr b/src/test/ui/methods/method-ambig-two-traits-from-impls2.stderr index 24946410887..85b39647885 100644 --- a/src/test/ui/methods/method-ambig-two-traits-from-impls2.stderr +++ b/src/test/ui/methods/method-ambig-two-traits-from-impls2.stderr @@ -14,11 +14,11 @@ note: candidate #2 is defined in an impl of the trait `B` for the type `AB` | LL | fn foo() {} | ^^^^^^^^ -help: disambiguate the method call for candidate #1 +help: disambiguate the associated function for candidate #1 | LL | A::foo(); | ^^^^^^ -help: disambiguate the method call for candidate #2 +help: disambiguate the associated function for candidate #2 | LL | B::foo(); | ^^^^^^ diff --git a/src/test/ui/methods/method-ambig-two-traits-with-default-method.stderr b/src/test/ui/methods/method-ambig-two-traits-with-default-method.stderr index 3dbb1737100..4ce7236ed96 100644 --- a/src/test/ui/methods/method-ambig-two-traits-with-default-method.stderr +++ b/src/test/ui/methods/method-ambig-two-traits-with-default-method.stderr @@ -14,11 +14,11 @@ note: candidate #2 is defined in an impl of the trait `Bar` for the type `usize` | LL | trait Bar { fn method(&self) {} } | ^^^^^^^^^^^^^^^^ -help: disambiguate the method call for candidate #1 +help: disambiguate the associated function for candidate #1 | LL | Foo::method(&1_usize); | ^^^^^^^^^^^^^^^^^^^^^ -help: disambiguate the method call for candidate #2 +help: disambiguate the associated function for candidate #2 | LL | Bar::method(&1_usize); | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr b/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr index e7f295df8c4..1bc7f30d04d 100644 --- a/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr +++ b/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr @@ -20,12 +20,12 @@ error[E0034]: multiple applicable items in scope LL | let z = x.foo(); | ^^^ multiple `foo` found | -note: candidate #1 is defined in an impl of the trait `internal::X` for the type `_` +note: candidate #1 is defined in an impl of the trait `internal::X` for the type `T` --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:43:9 | LL | fn foo(self: Smaht<Self, u64>) -> u64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: candidate #2 is defined in an impl of the trait `nuisance_foo::NuisanceFoo` for the type `_` +note: candidate #2 is defined in an impl of the trait `nuisance_foo::NuisanceFoo` for the type `T` --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:70:9 | LL | fn foo(self) {} @@ -35,15 +35,15 @@ note: candidate #3 is defined in the trait `FinalFoo` | LL | fn foo(&self) -> u8; | ^^^^^^^^^^^^^^^^^^^^ -help: disambiguate the method call for candidate #1 +help: disambiguate the associated function for candidate #1 | LL | let z = internal::X::foo(x); | ^^^^^^^^^^^^^^^^^^^ -help: disambiguate the method call for candidate #2 +help: disambiguate the associated function for candidate #2 | LL | let z = nuisance_foo::NuisanceFoo::foo(x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: disambiguate the method call for candidate #3 +help: disambiguate the associated function for candidate #3 | LL | let z = FinalFoo::foo(x); | ^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/numeric/numeric-cast.fixed b/src/test/ui/numeric/numeric-cast.fixed index 6f78228a85d..31acdb8faf6 100644 --- a/src/test/ui/numeric/numeric-cast.fixed +++ b/src/test/ui/numeric/numeric-cast.fixed @@ -24,9 +24,9 @@ fn main() { //~^ ERROR mismatched types foo::<usize>(x_u32.try_into().unwrap()); //~^ ERROR mismatched types - foo::<usize>(x_u16.try_into().unwrap()); + foo::<usize>(x_u16.into()); //~^ ERROR mismatched types - foo::<usize>(x_u8.try_into().unwrap()); + foo::<usize>(x_u8.into()); //~^ ERROR mismatched types foo::<usize>(x_isize.try_into().unwrap()); //~^ ERROR mismatched types @@ -56,9 +56,9 @@ fn main() { //~^ ERROR mismatched types foo::<isize>(x_i32.try_into().unwrap()); //~^ ERROR mismatched types - foo::<isize>(x_i16.try_into().unwrap()); + foo::<isize>(x_i16.into()); //~^ ERROR mismatched types - foo::<isize>(x_i8.try_into().unwrap()); + foo::<isize>(x_i8.into()); //~^ ERROR mismatched types // foo::<isize>(x_f64); // foo::<isize>(x_f32); diff --git a/src/test/ui/numeric/numeric-cast.stderr b/src/test/ui/numeric/numeric-cast.stderr index eef40cbdbe4..ff92a86c3a7 100644 --- a/src/test/ui/numeric/numeric-cast.stderr +++ b/src/test/ui/numeric/numeric-cast.stderr @@ -24,23 +24,19 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:27:18 | LL | foo::<usize>(x_u16); - | ^^^^^ expected `usize`, found `u16` - | -help: you can convert an `u16` to `usize` and panic if the converted value wouldn't fit - | -LL | foo::<usize>(x_u16.try_into().unwrap()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^ + | | + | expected `usize`, found `u16` + | help: you can convert an `u16` to `usize`: `x_u16.into()` error[E0308]: mismatched types --> $DIR/numeric-cast.rs:29:18 | LL | foo::<usize>(x_u8); - | ^^^^ expected `usize`, found `u8` - | -help: you can convert an `u8` to `usize` and panic if the converted value wouldn't fit - | -LL | foo::<usize>(x_u8.try_into().unwrap()); - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^ + | | + | expected `usize`, found `u8` + | help: you can convert an `u8` to `usize`: `x_u8.into()` error[E0308]: mismatched types --> $DIR/numeric-cast.rs:31:18 @@ -178,23 +174,19 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:59:18 | LL | foo::<isize>(x_i16); - | ^^^^^ expected `isize`, found `i16` - | -help: you can convert an `i16` to `isize` and panic if the converted value wouldn't fit - | -LL | foo::<isize>(x_i16.try_into().unwrap()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^ + | | + | expected `isize`, found `i16` + | help: you can convert an `i16` to `isize`: `x_i16.into()` error[E0308]: mismatched types --> $DIR/numeric-cast.rs:61:18 | LL | foo::<isize>(x_i8); - | ^^^^ expected `isize`, found `i8` - | -help: you can convert an `i8` to `isize` and panic if the converted value wouldn't fit - | -LL | foo::<isize>(x_i8.try_into().unwrap()); - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^ + | | + | expected `isize`, found `i8` + | help: you can convert an `i8` to `isize`: `x_i8.into()` error[E0308]: mismatched types --> $DIR/numeric-cast.rs:66:16 diff --git a/src/test/ui/option-to-result.rs b/src/test/ui/option-to-result.rs new file mode 100644 index 00000000000..00e8b5244c5 --- /dev/null +++ b/src/test/ui/option-to-result.rs @@ -0,0 +1,13 @@ +fn main(){ } + +fn test_result() -> Result<(),()> { + let a:Option<()> = Some(()); + a?;//~ ERROR `?` couldn't convert the error + Ok(()) +} + +fn test_option() -> Option<i32>{ + let a:Result<i32, i32> = Ok(5); + a?;//~ ERROR `?` couldn't convert the error + Some(5) +} diff --git a/src/test/ui/option-to-result.stderr b/src/test/ui/option-to-result.stderr new file mode 100644 index 00000000000..f673ef7fc1e --- /dev/null +++ b/src/test/ui/option-to-result.stderr @@ -0,0 +1,29 @@ +error[E0277]: `?` couldn't convert the error to `()` + --> $DIR/option-to-result.rs:5:6 + | +LL | a?; + | ^ the trait `std::convert::From<std::option::NoneError>` is not implemented for `()` + | + = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait + = note: required by `std::convert::From::from` +help: consider converting the `Option<T>` into a `Result<T, _>` using `Option::ok_or` or `Option::ok_or_else` + | +LL | a.ok_or_else(|| /* error value */)?; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: `?` couldn't convert the error to `std::option::NoneError` + --> $DIR/option-to-result.rs:11:6 + | +LL | a?; + | ^ the trait `std::convert::From<i32>` is not implemented for `std::option::NoneError` + | + = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait + = note: required by `std::convert::From::from` +help: consider converting the `Result<T, _>` into an `Option<T>` using `Result::ok` + | +LL | a.ok()?; + | ^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.rs b/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.rs new file mode 100644 index 00000000000..87222ef4b59 --- /dev/null +++ b/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.rs @@ -0,0 +1,35 @@ +mod a { + use std::marker::PhantomData; + + enum Bug { + V = [PhantomData; { [ () ].len() ].len() as isize, + //~^ ERROR mismatched closing delimiter: `]` + //~| ERROR mismatched closing delimiter: `]` + //~| ERROR mismatched closing delimiter: `]` + //~| ERROR mismatched closing delimiter: `]` + } +} + +mod b { + enum Bug { + V = [Vec::new; { [].len() ].len() as isize, + //~^ ERROR mismatched closing delimiter: `]` + //~| ERROR mismatched closing delimiter: `]` + //~| ERROR mismatched closing delimiter: `]` + //~| ERROR mismatched closing delimiter: `]` + //~| ERROR type annotations needed + } +} + +mod c { + enum Bug { + V = [Vec::new; { [0].len() ].len() as isize, + //~^ ERROR mismatched closing delimiter: `]` + //~| ERROR mismatched closing delimiter: `]` + //~| ERROR mismatched closing delimiter: `]` + //~| ERROR mismatched closing delimiter: `]` + //~| ERROR type annotations needed + } +} + +fn main() {} diff --git a/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.stderr b/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.stderr new file mode 100644 index 00000000000..f20ec755353 --- /dev/null +++ b/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.stderr @@ -0,0 +1,123 @@ +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:42 + | +LL | V = [PhantomData; { [ () ].len() ].len() as isize, + | - - ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:36 + | +LL | V = [Vec::new; { [].len() ].len() as isize, + | - - ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:36 + | +LL | V = [Vec::new; { [0].len() ].len() as isize, + | - - ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:42 + | +LL | V = [PhantomData; { [ () ].len() ].len() as isize, + | - - ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:36 + | +LL | V = [Vec::new; { [].len() ].len() as isize, + | - - ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:36 + | +LL | V = [Vec::new; { [0].len() ].len() as isize, + | - - ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:42 + | +LL | V = [PhantomData; { [ () ].len() ].len() as isize, + | - - ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:36 + | +LL | V = [Vec::new; { [].len() ].len() as isize, + | - - ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:36 + | +LL | V = [Vec::new; { [0].len() ].len() as isize, + | - - ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:42 + | +LL | V = [PhantomData; { [ () ].len() ].len() as isize, + | - - ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:36 + | +LL | V = [Vec::new; { [].len() ].len() as isize, + | - - ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error: mismatched closing delimiter: `]` + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:36 + | +LL | V = [Vec::new; { [0].len() ].len() as isize, + | - - ^ mismatched closing delimiter + | | | + | | unclosed delimiter + | closing delimiter possibly meant for this + +error[E0282]: type annotations needed + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:29 + | +LL | V = [Vec::new; { [].len() ].len() as isize, + | ^^^ cannot infer type for type parameter `T` + +error[E0282]: type annotations needed + --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:14 + | +LL | V = [Vec::new; { [0].len() ].len() as isize, + | ^^^^^^^^ cannot infer type for type parameter `T` + +error: aborting due to 14 previous errors + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/resolve/issue-65035-static-with-parent-generics.rs b/src/test/ui/resolve/issue-65035-static-with-parent-generics.rs index 708d72a2df7..b6a08351609 100644 --- a/src/test/ui/resolve/issue-65035-static-with-parent-generics.rs +++ b/src/test/ui/resolve/issue-65035-static-with-parent-generics.rs @@ -23,8 +23,7 @@ fn h<const N: usize>() { fn i<const N: usize>() { static a: [u8; N] = [0; N]; //~^ ERROR can't use generic parameters from outer function - //~^^ ERROR can't use generic parameters from outer function - //~| ERROR mismatched types + //~| ERROR can't use generic parameters from outer function } fn main() {} diff --git a/src/test/ui/resolve/issue-65035-static-with-parent-generics.stderr b/src/test/ui/resolve/issue-65035-static-with-parent-generics.stderr index 18e13d30f76..6076328b12f 100644 --- a/src/test/ui/resolve/issue-65035-static-with-parent-generics.stderr +++ b/src/test/ui/resolve/issue-65035-static-with-parent-generics.stderr @@ -48,16 +48,6 @@ LL | #![feature(const_generics)] | = note: `#[warn(incomplete_features)]` on by default -error[E0308]: mismatched types - --> $DIR/issue-65035-static-with-parent-generics.rs:24:25 - | -LL | static a: [u8; N] = [0; N]; - | ^^^^^^ expected `N`, found `N` - | - = note: expected array `[u8; _]` - found array `[u8; _]` - -error: aborting due to 6 previous errors; 1 warning emitted +error: aborting due to 5 previous errors; 1 warning emitted -Some errors have detailed explanations: E0308, E0401. -For more information about an error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0401`. diff --git a/src/test/ui/rfc-2632-const-trait-impl/hir-const-check.rs b/src/test/ui/rfc-2632-const-trait-impl/hir-const-check.rs new file mode 100644 index 00000000000..f7af1b506f0 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/hir-const-check.rs @@ -0,0 +1,16 @@ +// Regression test for #69615. + +#![feature(const_trait_impl, const_fn)] +#![allow(incomplete_features)] + +pub trait MyTrait { + fn method(&self); +} + +impl const MyTrait for () { + fn method(&self) { + match *self {} //~ ERROR `match` is not allowed in a `const fn` + } +} + +fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/hir-const-check.stderr b/src/test/ui/rfc-2632-const-trait-impl/hir-const-check.stderr new file mode 100644 index 00000000000..563a9afe5bb --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/hir-const-check.stderr @@ -0,0 +1,12 @@ +error[E0658]: `match` is not allowed in a `const fn` + --> $DIR/hir-const-check.rs:12:9 + | +LL | match *self {} + | ^^^^^^^^^^^^^^ + | + = note: see issue #49146 <https://github.com/rust-lang/rust/issues/49146> for more information + = help: add `#![feature(const_if_match)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/simd/simd-intrinsic-generic-arithmetic-saturating.rs b/src/test/ui/simd/simd-intrinsic-generic-arithmetic-saturating.rs index b2ddcf023eb..e664ecadda2 100644 --- a/src/test/ui/simd/simd-intrinsic-generic-arithmetic-saturating.rs +++ b/src/test/ui/simd/simd-intrinsic-generic-arithmetic-saturating.rs @@ -1,6 +1,5 @@ // run-pass // ignore-emscripten -// min-llvm-version 8.0 #![allow(non_camel_case_types)] #![feature(repr_simd, platform_intrinsics)] diff --git a/src/test/ui/span/issue-37767.stderr b/src/test/ui/span/issue-37767.stderr index 9ed6c8b826f..fc6c556c16d 100644 --- a/src/test/ui/span/issue-37767.stderr +++ b/src/test/ui/span/issue-37767.stderr @@ -14,11 +14,11 @@ note: candidate #2 is defined in the trait `B` | LL | fn foo(&mut self) {} | ^^^^^^^^^^^^^^^^^ -help: disambiguate the method call for candidate #1 +help: disambiguate the associated function for candidate #1 | LL | A::foo(&a) | ^^^^^^^^^^ -help: disambiguate the method call for candidate #2 +help: disambiguate the associated function for candidate #2 | LL | B::foo(&a) | ^^^^^^^^^^ @@ -39,11 +39,11 @@ note: candidate #2 is defined in the trait `D` | LL | fn foo(&self) {} | ^^^^^^^^^^^^^ -help: disambiguate the method call for candidate #1 +help: disambiguate the associated function for candidate #1 | LL | C::foo(&a) | ^^^^^^^^^^ -help: disambiguate the method call for candidate #2 +help: disambiguate the associated function for candidate #2 | LL | D::foo(&a) | ^^^^^^^^^^ @@ -64,11 +64,11 @@ note: candidate #2 is defined in the trait `F` | LL | fn foo(self) {} | ^^^^^^^^^^^^ -help: disambiguate the method call for candidate #1 +help: disambiguate the associated function for candidate #1 | LL | E::foo(a) | ^^^^^^^^^ -help: disambiguate the method call for candidate #2 +help: disambiguate the associated function for candidate #2 | LL | F::foo(a) | ^^^^^^^^^ diff --git a/src/test/ui/span/issue-7575.stderr b/src/test/ui/span/issue-7575.stderr index 89b36848a28..16a1ac6d718 100644 --- a/src/test/ui/span/issue-7575.stderr +++ b/src/test/ui/span/issue-7575.stderr @@ -25,15 +25,15 @@ LL | fn f9(_: usize) -> usize; candidate #1: `CtxtFn` candidate #2: `OtherTrait` candidate #3: `UnusedTrait` -help: disambiguate the method call for candidate #1 +help: disambiguate the associated function for candidate #1 | LL | u.f8(42) + CtxtFn::f9(u, 342) + m.fff(42) | ^^^^^^^^^^^^^^^^^^ -help: disambiguate the method call for candidate #2 +help: disambiguate the associated function for candidate #2 | LL | u.f8(42) + OtherTrait::f9(u, 342) + m.fff(42) | ^^^^^^^^^^^^^^^^^^^^^^ -help: disambiguate the method call for candidate #3 +help: disambiguate the associated function for candidate #3 | LL | u.f8(42) + UnusedTrait::f9(u, 342) + m.fff(42) | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -64,7 +64,7 @@ LL | t.is_str() | --^^^^^^-- | | | | | this is an associated function, not a method - | help: disambiguate the method call for the candidate: `ManyImplTrait::is_str(t)` + | help: disambiguate the associated function for the candidate: `ManyImplTrait::is_str(t)` | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter note: the candidate is defined in the trait `ManyImplTrait` diff --git a/src/test/ui/static/auxiliary/issue_24843.rs b/src/test/ui/static/auxiliary/issue_24843.rs new file mode 100644 index 00000000000..6ca04f86060 --- /dev/null +++ b/src/test/ui/static/auxiliary/issue_24843.rs @@ -0,0 +1 @@ +pub static TEST_STR: &'static str = "Hello world"; diff --git a/src/test/ui/static/issue-24843.rs b/src/test/ui/static/issue-24843.rs new file mode 100644 index 00000000000..0b3397e210d --- /dev/null +++ b/src/test/ui/static/issue-24843.rs @@ -0,0 +1,8 @@ +// aux-build: issue_24843.rs +// check-pass + +extern crate issue_24843; + +static _TEST_STR_2: &'static str = &issue_24843::TEST_STR; + +fn main() {} diff --git a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr index dfc1887d3af..f1c0cd6b543 100644 --- a/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr +++ b/src/test/ui/suggestions/suggest-assoc-fn-call-with-turbofish.stderr @@ -11,7 +11,7 @@ LL | x.default_hello(); | help: use associated function syntax instead: `GenericAssocMethod::<i32>::default_hello` | = note: found the following associated functions; to be used as methods, functions must have a `self` parameter -note: the candidate is defined in an impl for the type `GenericAssocMethod<_>` +note: the candidate is defined in an impl for the type `GenericAssocMethod<T>` --> $DIR/suggest-assoc-fn-call-with-turbofish.rs:4:5 | LL | fn default_hello() {} diff --git a/src/test/ui/traits/trait-alias-ambiguous.stderr b/src/test/ui/traits/trait-alias-ambiguous.stderr index 48a029104ae..7c00bb5207b 100644 --- a/src/test/ui/traits/trait-alias-ambiguous.stderr +++ b/src/test/ui/traits/trait-alias-ambiguous.stderr @@ -14,11 +14,11 @@ note: candidate #2 is defined in an impl of the trait `inner::B` for the type `u | LL | fn foo(&self) {} | ^^^^^^^^^^^^^ -help: disambiguate the method call for candidate #1 +help: disambiguate the associated function for candidate #1 | LL | inner::A::foo(&t); | ^^^^^^^^^^^^^^^^^ -help: disambiguate the method call for candidate #2 +help: disambiguate the associated function for candidate #2 | LL | inner::B::foo(&t); | ^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/try-block/try-block-in-match.rs b/src/test/ui/try-block/try-block-in-match.rs index bce0d0340b6..cd0b967e79d 100644 --- a/src/test/ui/try-block/try-block-in-match.rs +++ b/src/test/ui/try-block/try-block-in-match.rs @@ -1,7 +1,11 @@ +// run-pass // compile-flags: --edition 2018 #![feature(try_blocks)] fn main() { - match try { false } { _ => {} } //~ ERROR expected expression, found reserved keyword `try` + match try { } { + Err(()) => (), + Ok(()) => (), + } } diff --git a/src/test/ui/try-block/try-block-in-match.stderr b/src/test/ui/try-block/try-block-in-match.stderr deleted file mode 100644 index 936e0fe19ba..00000000000 --- a/src/test/ui/try-block/try-block-in-match.stderr +++ /dev/null @@ -1,10 +0,0 @@ -error: expected expression, found reserved keyword `try` - --> $DIR/try-block-in-match.rs:6:11 - | -LL | match try { false } { _ => {} } - | ----- ^^^ expected expression - | | - | while parsing this match expression - -error: aborting due to previous error - diff --git a/src/test/ui/try-block/try-block-in-while.rs b/src/test/ui/try-block/try-block-in-while.rs index 98af796dd37..33d27236519 100644 --- a/src/test/ui/try-block/try-block-in-while.rs +++ b/src/test/ui/try-block/try-block-in-while.rs @@ -3,5 +3,6 @@ #![feature(try_blocks)] fn main() { - while try { false } {} //~ ERROR expected expression, found reserved keyword `try` + while try { false } {} + //~^ ERROR the trait bound `bool: std::ops::Try` is not satisfied } diff --git a/src/test/ui/try-block/try-block-in-while.stderr b/src/test/ui/try-block/try-block-in-while.stderr index 026df15eb87..ac41ddfd8c0 100644 --- a/src/test/ui/try-block/try-block-in-while.stderr +++ b/src/test/ui/try-block/try-block-in-while.stderr @@ -1,8 +1,11 @@ -error: expected expression, found reserved keyword `try` - --> $DIR/try-block-in-while.rs:6:11 +error[E0277]: the trait bound `bool: std::ops::Try` is not satisfied + --> $DIR/try-block-in-while.rs:6:15 | LL | while try { false } {} - | ^^^ expected expression + | ^^^^^^^^^ the trait `std::ops::Try` is not implemented for `bool` + | + = note: required by `std::ops::Try::from_ok` error: aborting due to previous error +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/try-block/try-block-unused-delims.rs b/src/test/ui/try-block/try-block-unused-delims.rs new file mode 100644 index 00000000000..0b767eb2dad --- /dev/null +++ b/src/test/ui/try-block/try-block-unused-delims.rs @@ -0,0 +1,28 @@ +// check-pass +// compile-flags: --edition 2018 + +#![feature(try_blocks)] +#![warn(unused_parens, unused_braces)] + +fn consume<T>(_: Result<T, T>) -> T { todo!() } + +fn main() { + consume((try {})); + //~^ WARN unnecessary parentheses + + consume({ try {} }); + //~^ WARN unnecessary braces + + match (try {}) { + //~^ WARN unnecessary parentheses + Ok(()) | Err(()) => (), + } + + if let Err(()) = (try {}) {} + //~^ WARN unnecessary parentheses + + match (try {}) { + //~^ WARN unnecessary parentheses + Ok(()) | Err(()) => (), + } +} diff --git a/src/test/ui/try-block/try-block-unused-delims.stderr b/src/test/ui/try-block/try-block-unused-delims.stderr new file mode 100644 index 00000000000..5c7602ee0ab --- /dev/null +++ b/src/test/ui/try-block/try-block-unused-delims.stderr @@ -0,0 +1,44 @@ +warning: unnecessary parentheses around function argument + --> $DIR/try-block-unused-delims.rs:10:13 + | +LL | consume((try {})); + | ^^^^^^^^ help: remove these parentheses + | +note: the lint level is defined here + --> $DIR/try-block-unused-delims.rs:5:9 + | +LL | #![warn(unused_parens, unused_braces)] + | ^^^^^^^^^^^^^ + +warning: unnecessary braces around function argument + --> $DIR/try-block-unused-delims.rs:13:13 + | +LL | consume({ try {} }); + | ^^^^^^^^^^ help: remove these braces + | +note: the lint level is defined here + --> $DIR/try-block-unused-delims.rs:5:24 + | +LL | #![warn(unused_parens, unused_braces)] + | ^^^^^^^^^^^^^ + +warning: unnecessary parentheses around `match` scrutinee expression + --> $DIR/try-block-unused-delims.rs:16:11 + | +LL | match (try {}) { + | ^^^^^^^^ help: remove these parentheses + +warning: unnecessary parentheses around `let` scrutinee expression + --> $DIR/try-block-unused-delims.rs:21:22 + | +LL | if let Err(()) = (try {}) {} + | ^^^^^^^^ help: remove these parentheses + +warning: unnecessary parentheses around `match` scrutinee expression + --> $DIR/try-block-unused-delims.rs:24:11 + | +LL | match (try {}) { + | ^^^^^^^^ help: remove these parentheses + +warning: 5 warnings emitted + diff --git a/src/test/ui/try-macro-suggestion.rs b/src/test/ui/try-macro-suggestion.rs new file mode 100644 index 00000000000..635ceac0b19 --- /dev/null +++ b/src/test/ui/try-macro-suggestion.rs @@ -0,0 +1,9 @@ +// compile-flags: --edition 2018 +fn foo() -> Result<(), ()> { + Ok(try!()); //~ ERROR use of deprecated `try` macro + Ok(try!(Ok(()))) //~ ERROR use of deprecated `try` macro +} + +fn main() { + let _ = foo(); +} diff --git a/src/test/ui/try-macro-suggestion.stderr b/src/test/ui/try-macro-suggestion.stderr new file mode 100644 index 00000000000..9d833ef5ed9 --- /dev/null +++ b/src/test/ui/try-macro-suggestion.stderr @@ -0,0 +1,30 @@ +error: use of deprecated `try` macro + --> $DIR/try-macro-suggestion.rs:3:8 + | +LL | Ok(try!()); + | ^^^^^^ + | + = note: in the 2018 edition `try` is a reserved keyword, and the `try!()` macro is deprecated +help: you can still access the deprecated `try!()` macro using the "raw identifier" syntax + | +LL | Ok(r#try!()); + | ^^ + +error: use of deprecated `try` macro + --> $DIR/try-macro-suggestion.rs:4:8 + | +LL | Ok(try!(Ok(()))) + | ^^^^^^^^^^^^ + | + = note: in the 2018 edition `try` is a reserved keyword, and the `try!()` macro is deprecated +help: you can use the `?` operator instead + | +LL | Ok(Ok(())?) + | -- ^ +help: alternatively, you can still access the deprecated `try!()` macro using the "raw identifier" syntax + | +LL | Ok(r#try!(Ok(()))) + | ^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/try-on-option.stderr b/src/test/ui/try-on-option.stderr index 07615b52a48..7a4bb75967b 100644 --- a/src/test/ui/try-on-option.stderr +++ b/src/test/ui/try-on-option.stderr @@ -6,6 +6,10 @@ LL | x?; | = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait = note: required by `std::convert::From::from` +help: consider converting the `Option<T>` into a `Result<T, _>` using `Option::ok_or` or `Option::ok_or_else` + | +LL | x.ok_or_else(|| /* error value */)?; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `std::ops::Try`) --> $DIR/try-on-option.rs:13:5 diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-sized.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-sized.rs new file mode 100644 index 00000000000..c54df664243 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-sized.rs @@ -0,0 +1,17 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +type A = impl Sized; +fn f1() -> A { 0 } + +type B = impl ?Sized; +fn f2() -> &'static B { &[0] } + +type C = impl ?Sized + 'static; +fn f3() -> &'static C { &[0] } + +type D = impl ?Sized; +fn f4() -> &'static D { &1 } + +fn main() {} diff --git a/src/test/ui/type/type-dependent-def-issue-49241.rs b/src/test/ui/type/type-dependent-def-issue-49241.rs index a25e3ba5fa8..4b6bc6124db 100644 --- a/src/test/ui/type/type-dependent-def-issue-49241.rs +++ b/src/test/ui/type/type-dependent-def-issue-49241.rs @@ -2,6 +2,4 @@ fn main() { let v = vec![0]; const l: usize = v.count(); //~ ERROR attempt to use a non-constant value in a constant let s: [u32; l] = v.into_iter().collect(); - //~^ ERROR evaluation of constant value failed - //~^^ ERROR a value of type } diff --git a/src/test/ui/type/type-dependent-def-issue-49241.stderr b/src/test/ui/type/type-dependent-def-issue-49241.stderr index 18a69c50ebd..c5dcfa7a431 100644 --- a/src/test/ui/type/type-dependent-def-issue-49241.stderr +++ b/src/test/ui/type/type-dependent-def-issue-49241.stderr @@ -4,21 +4,6 @@ error[E0435]: attempt to use a non-constant value in a constant LL | const l: usize = v.count(); | ^ non-constant value -error[E0080]: evaluation of constant value failed - --> $DIR/type-dependent-def-issue-49241.rs:4:18 - | -LL | let s: [u32; l] = v.into_iter().collect(); - | ^ referenced constant has errors - -error[E0277]: a value of type `[u32; _]` cannot be built from an iterator over elements of type `{integer}` - --> $DIR/type-dependent-def-issue-49241.rs:4:37 - | -LL | let s: [u32; l] = v.into_iter().collect(); - | ^^^^^^^ value of type `[u32; _]` cannot be built from `std::iter::Iterator<Item={integer}>` - | - = help: the trait `std::iter::FromIterator<{integer}>` is not implemented for `[u32; _]` - -error: aborting due to 3 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0080, E0277, E0435. -For more information about an error, try `rustc --explain E0080`. +For more information about this error, try `rustc --explain E0435`. diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index f075d3e22d6..6de07d3e5cf 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -139,6 +139,7 @@ static TARGETS: &[&str] = &[ "x86_64-pc-solaris", "x86_64-unknown-cloudabi", "x86_64-unknown-freebsd", + "x86_64-unknown-illumos", "x86_64-unknown-linux-gnu", "x86_64-unknown-linux-gnux32", "x86_64-unknown-linux-musl", diff --git a/src/tools/cargo b/src/tools/cargo -Subproject 390e8f245ef2cd7ac698b8a76abf029f9abcab0 +Subproject ebda5065ee8a1e46801380abcbac21a25bc7e75 diff --git a/src/tools/clippy b/src/tools/clippy -Subproject af5940b73153b2a4ea2922aa803abac45d02998 +Subproject 891e1a859b52486936e021235fdc36fbdd9b410 diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 2944864abbf..61a7d8ee5c9 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -357,14 +357,15 @@ impl<'test> TestCx<'test> { Ui if pm == Some(PassMode::Run) || self.props.fail_mode == Some(FailMode::Run) => { WillExecute::Yes } - Ui => WillExecute::No, + MirOpt if pm == Some(PassMode::Run) => WillExecute::Yes, + Ui | MirOpt => WillExecute::No, mode => panic!("unimplemented for mode {:?}", mode), } } fn should_run_successfully(&self, pm: Option<PassMode>) -> bool { match self.config.mode { - Ui => pm == Some(PassMode::Run), + Ui | MirOpt => pm == Some(PassMode::Run), mode => panic!("unimplemented for mode {:?}", mode), } } @@ -2809,10 +2810,16 @@ impl<'test> TestCx<'test> { self.document(&out_dir); let root = self.config.find_rust_src_root().unwrap(); + let file_stem = + self.testpaths.file.file_stem().and_then(|f| f.to_str()).expect("no file stem"); let res = self.cmd2procres( Command::new(&nodejs) .arg(root.join("src/tools/rustdoc-js/tester.js")) - .arg(out_dir.parent().expect("no parent")) + .arg("--doc-folder") + .arg(out_dir) + .arg("--crate-name") + .arg(file_stem.replace("-", "_")) + .arg("--test-file") .arg(self.testpaths.file.with_extension("js")), ); if !res.status.success() { @@ -3059,18 +3066,24 @@ impl<'test> TestCx<'test> { } fn run_mir_opt_test(&self) { - let proc_res = self.compile_test(WillExecute::Yes, EmitMetadata::No); + let pm = self.pass_mode(); + let should_run = self.should_run(pm); + let emit_metadata = self.should_emit_metadata(pm); + let proc_res = self.compile_test(should_run, emit_metadata); if !proc_res.status.success() { self.fatal_proc_rec("compilation failed!", &proc_res); } - let proc_res = self.exec_compiled_test(); + self.check_mir_dump(); - if !proc_res.status.success() { - self.fatal_proc_rec("test run failed!", &proc_res); + if let WillExecute::Yes = should_run { + let proc_res = self.exec_compiled_test(); + + if !proc_res.status.success() { + self.fatal_proc_rec("test run failed!", &proc_res); + } } - self.check_mir_dump(); } fn check_mir_dump(&self) { @@ -3148,7 +3161,7 @@ impl<'test> TestCx<'test> { } let expected_string = fs::read_to_string(&expected_file).unwrap(); if dumped_string != expected_string { - print_diff(&dumped_string, &expected_string, 3); + print_diff(&expected_string, &dumped_string, 3); panic!( "Actual MIR output differs from expected MIR output {}", expected_file.display() diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index 2663b3d160a..c61bee0f8d9 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -21,6 +21,7 @@ const OS_TABLE: &'static [(&'static str, &'static str)] = &[ ("fuchsia", "fuchsia"), ("haiku", "haiku"), ("hermit", "hermit"), + ("illumos", "illumos"), ("ios", "ios"), ("l4re", "l4re"), ("linux", "linux"), diff --git a/src/tools/miri b/src/tools/miri -Subproject 325682ad56d23369059ea93d5a8d44e5782e41c +Subproject 5c823a1ec1eb3ff89bcbcb6c1fa8e1f8b24eb52 diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py index 307239fa4c9..2da62b6bd99 100755 --- a/src/tools/publish_toolstate.py +++ b/src/tools/publish_toolstate.py @@ -39,7 +39,7 @@ MAINTAINERS = { 'adamgreig', 'andre-richter', 'jamesmunns', 'korken89', 'ryankurte', 'thejpster', 'therealprof', }, - 'edition-guide': {'ehuss', 'Centril', 'steveklabnik'}, + 'edition-guide': {'ehuss', 'steveklabnik'}, 'rustc-dev-guide': {'mark-i-m', 'spastorino', 'amanjeev', 'JohnTitor'}, } diff --git a/src/tools/rls b/src/tools/rls -Subproject 1cfb87845f45758442830506b7242947dfc989d +Subproject 2659cbf14bfb0929a16d7ce9b6858d0bb286ede diff --git a/src/tools/rustdoc-js-common/lib.js b/src/tools/rustdoc-js-common/lib.js deleted file mode 100644 index 81e64aec491..00000000000 --- a/src/tools/rustdoc-js-common/lib.js +++ /dev/null @@ -1,319 +0,0 @@ -const fs = require('fs'); - -function getNextStep(content, pos, stop) { - while (pos < content.length && content[pos] !== stop && - (content[pos] === ' ' || content[pos] === '\t' || content[pos] === '\n')) { - pos += 1; - } - if (pos >= content.length) { - return null; - } - if (content[pos] !== stop) { - return pos * -1; - } - return pos; -} - -// Stupid function extractor based on indent. Doesn't support block -// comments. If someone puts a ' or an " in a block comment this -// will blow up. Template strings are not tested and might also be -// broken. -function extractFunction(content, functionName) { - var indent = 0; - var splitter = "function " + functionName + "("; - - while (true) { - var start = content.indexOf(splitter); - if (start === -1) { - break; - } - var pos = start; - while (pos < content.length && content[pos] !== ')') { - pos += 1; - } - if (pos >= content.length) { - break; - } - pos = getNextStep(content, pos + 1, '{'); - if (pos === null) { - break; - } else if (pos < 0) { - content = content.slice(-pos); - continue; - } - while (pos < content.length) { - // Eat single-line comments - if (content[pos] === '/' && pos > 0 && content[pos-1] === '/') { - do { - pos += 1; - } while (pos < content.length && content[pos] !== '\n'); - - // Eat quoted strings - } else if (content[pos] === '"' || content[pos] === "'" || content[pos] === "`") { - var stop = content[pos]; - var is_escaped = false; - do { - if (content[pos] === '\\') { - pos += 2; - } else { - pos += 1; - } - } while (pos < content.length && - (content[pos] !== stop || content[pos - 1] === '\\')); - - // Otherwise, check for indent - } else if (content[pos] === '{') { - indent += 1; - } else if (content[pos] === '}') { - indent -= 1; - if (indent === 0) { - return content.slice(start, pos + 1); - } - } - pos += 1; - } - content = content.slice(start + 1); - } - return null; -} - -// Stupid function extractor for array. -function extractArrayVariable(content, arrayName) { - var splitter = "var " + arrayName; - while (true) { - var start = content.indexOf(splitter); - if (start === -1) { - break; - } - var pos = getNextStep(content, start, '='); - if (pos === null) { - break; - } else if (pos < 0) { - content = content.slice(-pos); - continue; - } - pos = getNextStep(content, pos, '['); - if (pos === null) { - break; - } else if (pos < 0) { - content = content.slice(-pos); - continue; - } - while (pos < content.length) { - if (content[pos] === '"' || content[pos] === "'") { - var stop = content[pos]; - do { - if (content[pos] === '\\') { - pos += 2; - } else { - pos += 1; - } - } while (pos < content.length && - (content[pos] !== stop || content[pos - 1] === '\\')); - } else if (content[pos] === ']' && - pos + 1 < content.length && - content[pos + 1] === ';') { - return content.slice(start, pos + 2); - } - pos += 1; - } - content = content.slice(start + 1); - } - return null; -} - -// Stupid function extractor for variable. -function extractVariable(content, varName) { - var splitter = "var " + varName; - while (true) { - var start = content.indexOf(splitter); - if (start === -1) { - break; - } - var pos = getNextStep(content, start, '='); - if (pos === null) { - break; - } else if (pos < 0) { - content = content.slice(-pos); - continue; - } - while (pos < content.length) { - if (content[pos] === '"' || content[pos] === "'") { - var stop = content[pos]; - do { - if (content[pos] === '\\') { - pos += 2; - } else { - pos += 1; - } - } while (pos < content.length && - (content[pos] !== stop || content[pos - 1] === '\\')); - } else if (content[pos] === ';' || content[pos] === ',') { - return content.slice(start, pos + 1); - } - pos += 1; - } - content = content.slice(start + 1); - } - return null; -} - -function loadContent(content) { - var Module = module.constructor; - var m = new Module(); - m._compile(content, "tmp.js"); - m.exports.ignore_order = content.indexOf("\n// ignore-order\n") !== -1 || - content.startsWith("// ignore-order\n"); - m.exports.exact_check = content.indexOf("\n// exact-check\n") !== -1 || - content.startsWith("// exact-check\n"); - m.exports.should_fail = content.indexOf("\n// should-fail\n") !== -1 || - content.startsWith("// should-fail\n"); - return m.exports; -} - -function readFile(filePath) { - return fs.readFileSync(filePath, 'utf8'); -} - -function loadThings(thingsToLoad, kindOfLoad, funcToCall, fileContent) { - var content = ''; - for (var i = 0; i < thingsToLoad.length; ++i) { - var tmp = funcToCall(fileContent, thingsToLoad[i]); - if (tmp === null) { - console.error('unable to find ' + kindOfLoad + ' "' + thingsToLoad[i] + '"'); - process.exit(1); - } - content += tmp; - content += 'exports.' + thingsToLoad[i] + ' = ' + thingsToLoad[i] + ';'; - } - return content; -} - -function lookForEntry(entry, data) { - for (var i = 0; i < data.length; ++i) { - var allGood = true; - for (var key in entry) { - if (!entry.hasOwnProperty(key)) { - continue; - } - var value = data[i][key]; - // To make our life easier, if there is a "parent" type, we add it to the path. - if (key === 'path' && data[i]['parent'] !== undefined) { - if (value.length > 0) { - value += '::' + data[i]['parent']['name']; - } else { - value = data[i]['parent']['name']; - } - } - if (value !== entry[key]) { - allGood = false; - break; - } - } - if (allGood === true) { - return i; - } - } - return null; -} - -function loadMainJsAndIndex(mainJs, aliases, searchIndex, crate) { - if (searchIndex[searchIndex.length - 1].length === 0) { - searchIndex.pop(); - } - searchIndex.pop(); - searchIndex = loadContent(searchIndex.join("\n") + '\nexports.searchIndex = searchIndex;'); - finalJS = ""; - - var arraysToLoad = ["itemTypes"]; - var variablesToLoad = ["MAX_LEV_DISTANCE", "MAX_RESULTS", "NO_TYPE_FILTER", - "GENERICS_DATA", "NAME", "INPUTS_DATA", "OUTPUT_DATA", - "TY_PRIMITIVE", "TY_KEYWORD", - "levenshtein_row2"]; - // execQuery first parameter is built in getQuery (which takes in the search input). - // execQuery last parameter is built in buildIndex. - // buildIndex requires the hashmap from search-index. - var functionsToLoad = ["buildHrefAndPath", "pathSplitter", "levenshtein", "validateResult", - "getQuery", "buildIndex", "execQuery", "execSearch"]; - - finalJS += 'window = { "currentCrate": "' + crate + '" };\n'; - finalJS += 'var rootPath = "../";\n'; - finalJS += aliases; - finalJS += loadThings(arraysToLoad, 'array', extractArrayVariable, mainJs); - finalJS += loadThings(variablesToLoad, 'variable', extractVariable, mainJs); - finalJS += loadThings(functionsToLoad, 'function', extractFunction, mainJs); - - var loaded = loadContent(finalJS); - var index = loaded.buildIndex(searchIndex.searchIndex); - - return [loaded, index]; -} - -function runChecks(testFile, loaded, index) { - var errors = 0; - var loadedFile = loadContent( - readFile(testFile) + 'exports.QUERY = QUERY;exports.EXPECTED = EXPECTED;'); - - const expected = loadedFile.EXPECTED; - const query = loadedFile.QUERY; - const filter_crate = loadedFile.FILTER_CRATE; - const ignore_order = loadedFile.ignore_order; - const exact_check = loadedFile.exact_check; - const should_fail = loadedFile.should_fail; - - var results = loaded.execSearch(loaded.getQuery(query), index); - var error_text = []; - - for (var key in expected) { - if (!expected.hasOwnProperty(key)) { - continue; - } - if (!results.hasOwnProperty(key)) { - error_text.push('==> Unknown key "' + key + '"'); - break; - } - var entry = expected[key]; - var prev_pos = -1; - for (var i = 0; i < entry.length; ++i) { - var entry_pos = lookForEntry(entry[i], results[key]); - if (entry_pos === null) { - error_text.push("==> Result not found in '" + key + "': '" + - JSON.stringify(entry[i]) + "'"); - } else if (exact_check === true && prev_pos + 1 !== entry_pos) { - error_text.push("==> Exact check failed at position " + (prev_pos + 1) + ": " + - "expected '" + JSON.stringify(entry[i]) + "' but found '" + - JSON.stringify(results[key][i]) + "'"); - } else if (ignore_order === false && entry_pos < prev_pos) { - error_text.push("==> '" + JSON.stringify(entry[i]) + "' was supposed to be " + - " before '" + JSON.stringify(results[key][entry_pos]) + "'"); - } else { - prev_pos = entry_pos; - } - } - } - if (error_text.length === 0 && should_fail === true) { - errors += 1; - console.error("FAILED"); - console.error("==> Test was supposed to fail but all items were found..."); - } else if (error_text.length !== 0 && should_fail === false) { - errors += 1; - console.error("FAILED"); - console.error(error_text.join("\n")); - } else { - console.log("OK"); - } - return errors; -} - -module.exports = { - 'getNextStep': getNextStep, - 'extractFunction': extractFunction, - 'extractArrayVariable': extractArrayVariable, - 'extractVariable': extractVariable, - 'loadContent': loadContent, - 'readFile': readFile, - 'loadThings': loadThings, - 'lookForEntry': lookForEntry, - 'loadMainJsAndIndex': loadMainJsAndIndex, - 'runChecks': runChecks, -}; diff --git a/src/tools/rustdoc-js-std/tester.js b/src/tools/rustdoc-js-std/tester.js deleted file mode 100644 index 6f730b0fdbb..00000000000 --- a/src/tools/rustdoc-js-std/tester.js +++ /dev/null @@ -1,74 +0,0 @@ -const fs = require('fs'); -const path = require('path'); -const tools = require('../rustdoc-js-common/lib.js'); - - -function findFile(dir, name, extension) { - var entries = fs.readdirSync(dir); - var matches = []; - for (var i = 0; i < entries.length; ++i) { - var entry = entries[i]; - var file_type = fs.statSync(dir + entry); - if (file_type.isDirectory()) { - continue; - } - if (entry.startsWith(name) && entry.endsWith(extension)) { - var version = entry.slice(name.length, entry.length - extension.length); - version = version.split(".").map(function(x) { - return parseInt(x); - }); - var total = 0; - var mult = 1; - for (var j = version.length - 1; j >= 0; --j) { - total += version[j] * mult; - mult *= 1000; - } - matches.push([entry, total]); - } - } - if (matches.length === 0) { - return null; - } - // We make a reverse sort to have the "highest" file. Very useful in case you didn't clean up - // you std doc folder... - matches.sort(function(a, b) { - return b[1] - a[1]; - }); - return matches[0][0]; -} - -function readFileMatching(dir, name, extension) { - if (dir.endsWith("/") === false) { - dir += "/"; - } - var f = findFile(dir, name, extension); - if (f === null) { - return ""; - } - return tools.readFile(dir + f); -} - -function main(argv) { - if (argv.length !== 4) { - console.error("USAGE: node tester.js STD_DOCS TEST_FOLDER"); - return 1; - } - var std_docs = argv[2]; - var test_folder = argv[3]; - - var mainJs = readFileMatching(std_docs, "main", ".js"); - var aliases = readFileMatching(std_docs, "aliases", ".js"); - var searchIndex = readFileMatching(std_docs, "search-index", ".js").split("\n"); - - var [loaded, index] = tools.loadMainJsAndIndex(mainJs, aliases, searchIndex, "std"); - - var errors = 0; - - fs.readdirSync(test_folder).forEach(function(file) { - process.stdout.write('Checking "' + file + '" ... '); - errors += tools.runChecks(path.join(test_folder, file), loaded, index); - }); - return errors > 0 ? 1 : 0; -} - -process.exit(main(process.argv)); diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js index 2e8901d56d0..03f06fc1c6c 100644 --- a/src/tools/rustdoc-js/tester.js +++ b/src/tools/rustdoc-js/tester.js @@ -1,43 +1,408 @@ const fs = require('fs'); const path = require('path'); -const tools = require('../rustdoc-js-common/lib.js'); -function load_files(out_folder, crate) { - var mainJs = tools.readFile(out_folder + "/main.js"); - var aliases = tools.readFile(out_folder + "/aliases.js"); - var searchIndex = tools.readFile(out_folder + "/search-index.js").split("\n"); +function getNextStep(content, pos, stop) { + while (pos < content.length && content[pos] !== stop && + (content[pos] === ' ' || content[pos] === '\t' || content[pos] === '\n')) { + pos += 1; + } + if (pos >= content.length) { + return null; + } + if (content[pos] !== stop) { + return pos * -1; + } + return pos; +} + +// Stupid function extractor based on indent. Doesn't support block +// comments. If someone puts a ' or an " in a block comment this +// will blow up. Template strings are not tested and might also be +// broken. +function extractFunction(content, functionName) { + var indent = 0; + var splitter = "function " + functionName + "("; - return tools.loadMainJsAndIndex(mainJs, aliases, searchIndex, crate); + while (true) { + var start = content.indexOf(splitter); + if (start === -1) { + break; + } + var pos = start; + while (pos < content.length && content[pos] !== ')') { + pos += 1; + } + if (pos >= content.length) { + break; + } + pos = getNextStep(content, pos + 1, '{'); + if (pos === null) { + break; + } else if (pos < 0) { + content = content.slice(-pos); + continue; + } + while (pos < content.length) { + // Eat single-line comments + if (content[pos] === '/' && pos > 0 && content[pos-1] === '/') { + do { + pos += 1; + } while (pos < content.length && content[pos] !== '\n'); + + // Eat quoted strings + } else if (content[pos] === '"' || content[pos] === "'" || content[pos] === "`") { + var stop = content[pos]; + var is_escaped = false; + do { + if (content[pos] === '\\') { + pos += 2; + } else { + pos += 1; + } + } while (pos < content.length && + (content[pos] !== stop || content[pos - 1] === '\\')); + + // Otherwise, check for indent + } else if (content[pos] === '{') { + indent += 1; + } else if (content[pos] === '}') { + indent -= 1; + if (indent === 0) { + return content.slice(start, pos + 1); + } + } + pos += 1; + } + content = content.slice(start + 1); + } + return null; } -function main(argv) { - if (argv.length < 4) { - console.error("USAGE: node tester.js OUT_FOLDER [TESTS]"); - return 1; +// Stupid function extractor for array. +function extractArrayVariable(content, arrayName) { + var splitter = "var " + arrayName; + while (true) { + var start = content.indexOf(splitter); + if (start === -1) { + break; + } + var pos = getNextStep(content, start, '='); + if (pos === null) { + break; + } else if (pos < 0) { + content = content.slice(-pos); + continue; + } + pos = getNextStep(content, pos, '['); + if (pos === null) { + break; + } else if (pos < 0) { + content = content.slice(-pos); + continue; + } + while (pos < content.length) { + if (content[pos] === '"' || content[pos] === "'") { + var stop = content[pos]; + do { + if (content[pos] === '\\') { + pos += 2; + } else { + pos += 1; + } + } while (pos < content.length && + (content[pos] !== stop || content[pos - 1] === '\\')); + } else if (content[pos] === ']' && + pos + 1 < content.length && + content[pos + 1] === ';') { + return content.slice(start, pos + 2); + } + pos += 1; + } + content = content.slice(start + 1); } - if (argv[2].substr(-1) !== "/") { - argv[2] += "/"; + return null; +} + +// Stupid function extractor for variable. +function extractVariable(content, varName) { + var splitter = "var " + varName; + while (true) { + var start = content.indexOf(splitter); + if (start === -1) { + break; + } + var pos = getNextStep(content, start, '='); + if (pos === null) { + break; + } else if (pos < 0) { + content = content.slice(-pos); + continue; + } + while (pos < content.length) { + if (content[pos] === '"' || content[pos] === "'") { + var stop = content[pos]; + do { + if (content[pos] === '\\') { + pos += 2; + } else { + pos += 1; + } + } while (pos < content.length && + (content[pos] !== stop || content[pos - 1] === '\\')); + } else if (content[pos] === ';' || content[pos] === ',') { + return content.slice(start, pos + 1); + } + pos += 1; + } + content = content.slice(start + 1); } - const out_folder = argv[2]; + return null; +} +function loadContent(content) { + var Module = module.constructor; + var m = new Module(); + m._compile(content, "tmp.js"); + m.exports.ignore_order = content.indexOf("\n// ignore-order\n") !== -1 || + content.startsWith("// ignore-order\n"); + m.exports.exact_check = content.indexOf("\n// exact-check\n") !== -1 || + content.startsWith("// exact-check\n"); + m.exports.should_fail = content.indexOf("\n// should-fail\n") !== -1 || + content.startsWith("// should-fail\n"); + return m.exports; +} + +function readFile(filePath) { + return fs.readFileSync(filePath, 'utf8'); +} + +function loadThings(thingsToLoad, kindOfLoad, funcToCall, fileContent) { + var content = ''; + for (var i = 0; i < thingsToLoad.length; ++i) { + var tmp = funcToCall(fileContent, thingsToLoad[i]); + if (tmp === null) { + console.error('unable to find ' + kindOfLoad + ' "' + thingsToLoad[i] + '"'); + process.exit(1); + } + content += tmp; + content += 'exports.' + thingsToLoad[i] + ' = ' + thingsToLoad[i] + ';'; + } + return content; +} + +function lookForEntry(entry, data) { + for (var i = 0; i < data.length; ++i) { + var allGood = true; + for (var key in entry) { + if (!entry.hasOwnProperty(key)) { + continue; + } + var value = data[i][key]; + // To make our life easier, if there is a "parent" type, we add it to the path. + if (key === 'path' && data[i]['parent'] !== undefined) { + if (value.length > 0) { + value += '::' + data[i]['parent']['name']; + } else { + value = data[i]['parent']['name']; + } + } + if (value !== entry[key]) { + allGood = false; + break; + } + } + if (allGood === true) { + return i; + } + } + return null; +} + +function loadMainJsAndIndex(mainJs, aliases, searchIndex, crate) { + if (searchIndex[searchIndex.length - 1].length === 0) { + searchIndex.pop(); + } + searchIndex.pop(); + searchIndex = loadContent(searchIndex.join("\n") + '\nexports.searchIndex = searchIndex;'); + var finalJS = ""; + + var arraysToLoad = ["itemTypes"]; + var variablesToLoad = ["MAX_LEV_DISTANCE", "MAX_RESULTS", "NO_TYPE_FILTER", + "GENERICS_DATA", "NAME", "INPUTS_DATA", "OUTPUT_DATA", + "TY_PRIMITIVE", "TY_KEYWORD", + "levenshtein_row2"]; + // execQuery first parameter is built in getQuery (which takes in the search input). + // execQuery last parameter is built in buildIndex. + // buildIndex requires the hashmap from search-index. + var functionsToLoad = ["buildHrefAndPath", "pathSplitter", "levenshtein", "validateResult", + "getQuery", "buildIndex", "execQuery", "execSearch"]; + + finalJS += 'window = { "currentCrate": "' + crate + '" };\n'; + finalJS += 'var rootPath = "../";\n'; + finalJS += aliases; + finalJS += loadThings(arraysToLoad, 'array', extractArrayVariable, mainJs); + finalJS += loadThings(variablesToLoad, 'variable', extractVariable, mainJs); + finalJS += loadThings(functionsToLoad, 'function', extractFunction, mainJs); + + var loaded = loadContent(finalJS); + var index = loaded.buildIndex(searchIndex.searchIndex); + + return [loaded, index]; +} + +function runChecks(testFile, loaded, index) { var errors = 0; + var loadedFile = loadContent( + readFile(testFile) + 'exports.QUERY = QUERY;exports.EXPECTED = EXPECTED;'); + + const expected = loadedFile.EXPECTED; + const query = loadedFile.QUERY; + const filter_crate = loadedFile.FILTER_CRATE; + const ignore_order = loadedFile.ignore_order; + const exact_check = loadedFile.exact_check; + const should_fail = loadedFile.should_fail; - for (var j = 3; j < argv.length; ++j) { - const test_file = argv[j]; - const test_name = path.basename(test_file, ".js"); + var results = loaded.execSearch(loaded.getQuery(query), index); + var error_text = []; - process.stdout.write('Checking "' + test_name + '" ... '); - if (!fs.existsSync(test_file)) { - errors += 1; - console.error("FAILED"); - console.error("==> Missing '" + test_name + ".js' file..."); + for (var key in expected) { + if (!expected.hasOwnProperty(key)) { continue; } + if (!results.hasOwnProperty(key)) { + error_text.push('==> Unknown key "' + key + '"'); + break; + } + var entry = expected[key]; + var prev_pos = -1; + for (var i = 0; i < entry.length; ++i) { + var entry_pos = lookForEntry(entry[i], results[key]); + if (entry_pos === null) { + error_text.push("==> Result not found in '" + key + "': '" + + JSON.stringify(entry[i]) + "'"); + } else if (exact_check === true && prev_pos + 1 !== entry_pos) { + error_text.push("==> Exact check failed at position " + (prev_pos + 1) + ": " + + "expected '" + JSON.stringify(entry[i]) + "' but found '" + + JSON.stringify(results[key][i]) + "'"); + } else if (ignore_order === false && entry_pos < prev_pos) { + error_text.push("==> '" + JSON.stringify(entry[i]) + "' was supposed to be " + + " before '" + JSON.stringify(results[key][entry_pos]) + "'"); + } else { + prev_pos = entry_pos; + } + } + } + if (error_text.length === 0 && should_fail === true) { + errors += 1; + console.error("FAILED"); + console.error("==> Test was supposed to fail but all items were found..."); + } else if (error_text.length !== 0 && should_fail === false) { + errors += 1; + console.error("FAILED"); + console.error(error_text.join("\n")); + } else { + console.log("OK"); + } + return errors; +} - const test_out_folder = out_folder + test_name; +function load_files(doc_folder, resource_suffix, crate) { + var mainJs = readFile(path.join(doc_folder, "main" + resource_suffix + ".js")); + var aliases = readFile(path.join(doc_folder, "aliases" + resource_suffix + ".js")); + var searchIndex = readFile( + path.join(doc_folder, "search-index" + resource_suffix + ".js")).split("\n"); + + return loadMainJsAndIndex(mainJs, aliases, searchIndex, crate); +} - var [loaded, index] = load_files(test_out_folder, test_name); - errors += tools.runChecks(test_file, loaded, index); +function showHelp() { + console.log("rustdoc-js options:"); + console.log(" --doc-folder [PATH] : location of the generated doc folder"); + console.log(" --help : show this message then quit"); + console.log(" --crate-name [STRING] : crate name to be used"); + console.log(" --test-file [PATH] : location of the JS test file"); + console.log(" --test-folder [PATH] : location of the JS tests folder"); + console.log(" --resource-suffix [STRING] : suffix to refer to the correct files"); +} + +function parseOptions(args) { + var opts = { + "crate_name": "", + "resource_suffix": "", + "doc_folder": "", + "test_folder": "", + "test_file": "", + }; + var correspondances = { + "--resource-suffix": "resource_suffix", + "--doc-folder": "doc_folder", + "--test-folder": "test_folder", + "--test-file": "test_file", + "--crate-name": "crate_name", + }; + + for (var i = 0; i < args.length; ++i) { + if (args[i] === "--resource-suffix" + || args[i] === "--doc-folder" + || args[i] === "--test-folder" + || args[i] === "--test-file" + || args[i] === "--crate-name") { + i += 1; + if (i >= args.length) { + console.error("Missing argument after `" + args[i - 1] + "` option."); + return null; + } + opts[correspondances[args[i - 1]]] = args[i]; + } else if (args[i] === "--help") { + showHelp(); + process.exit(0); + } else { + console.error("Unknown option `" + args[i] + "`."); + console.error("Use `--help` to see the list of options"); + return null; + } + } + if (opts["doc_folder"].length < 1) { + console.error("Missing `--doc-folder` option."); + } else if (opts["crate_name"].length < 1) { + console.error("Missing `--crate-name` option."); + } else if (opts["test_folder"].length < 1 && opts["test_file"].length < 1) { + console.error("At least one of `--test-folder` or `--test-file` option is required."); + } else { + return opts; + } + return null; +} + +function checkFile(test_file, opts, loaded, index) { + const test_name = path.basename(test_file, ".js"); + + process.stdout.write('Checking "' + test_name + '" ... '); + return runChecks(test_file, loaded, index); +} + +function main(argv) { + var opts = parseOptions(argv.slice(2)); + if (opts === null) { + return 1; + } + + var [loaded, index] = load_files( + opts["doc_folder"], + opts["resource_suffix"], + opts["crate_name"]); + var errors = 0; + + if (opts["test_file"].length !== 0) { + errors += checkFile(opts["test_file"], opts, loaded, index); + } + if (opts["test_folder"].length !== 0) { + fs.readdirSync(opts["test_folder"]).forEach(function(file) { + if (!file.endsWith(".js")) { + return; + } + errors += checkFile(path.join(opts["test_folder"], file), opts, loaded, index); + }); } return errors > 0 ? 1 : 0; } diff --git a/src/tools/rustfmt b/src/tools/rustfmt -Subproject c1267303bc06408b4ce406175e8f9cddbbe11b9 +Subproject a5cb5d26833cfda6fa2ed35735448953f728bd5 |
