Merge remote-tracking branch 'origin/master' into mpk/add-long-error-message-for-E0311
This commit is contained in:
commit
eda2a40145
2077 changed files with 36548 additions and 21026 deletions
8
.github/workflows/ci.yml
vendored
8
.github/workflows/ci.yml
vendored
|
@ -391,24 +391,28 @@ jobs:
|
|||
env:
|
||||
RUST_CONFIGURE_ARGS: "--build=i686-pc-windows-gnu --set llvm.allow-old-toolchain"
|
||||
SCRIPT: make ci-mingw-subset-1
|
||||
NO_DOWNLOAD_CI_LLVM: 1
|
||||
CUSTOM_MINGW: 1
|
||||
os: windows-latest-xl
|
||||
- name: i686-mingw-2
|
||||
env:
|
||||
RUST_CONFIGURE_ARGS: "--build=i686-pc-windows-gnu --set llvm.allow-old-toolchain"
|
||||
SCRIPT: make ci-mingw-subset-2
|
||||
NO_DOWNLOAD_CI_LLVM: 1
|
||||
CUSTOM_MINGW: 1
|
||||
os: windows-latest-xl
|
||||
- name: x86_64-mingw-1
|
||||
env:
|
||||
SCRIPT: make ci-mingw-subset-1
|
||||
RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-gnu --enable-profiler --set llvm.allow-old-toolchain"
|
||||
NO_DOWNLOAD_CI_LLVM: 1
|
||||
CUSTOM_MINGW: 1
|
||||
os: windows-latest-xl
|
||||
- name: x86_64-mingw-2
|
||||
env:
|
||||
SCRIPT: make ci-mingw-subset-2
|
||||
RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-gnu --enable-profiler --set llvm.allow-old-toolchain"
|
||||
NO_DOWNLOAD_CI_LLVM: 1
|
||||
CUSTOM_MINGW: 1
|
||||
os: windows-latest-xl
|
||||
- name: dist-x86_64-msvc
|
||||
|
@ -427,12 +431,13 @@ jobs:
|
|||
env:
|
||||
RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --host=aarch64-pc-windows-msvc --enable-full-tools --enable-profiler"
|
||||
SCRIPT: python x.py dist
|
||||
DIST_REQUIRE_ALL_TOOLS: 0
|
||||
DIST_REQUIRE_ALL_TOOLS: 1
|
||||
WINDOWS_SDK_20348_HACK: 1
|
||||
os: windows-latest-xl
|
||||
- name: dist-i686-mingw
|
||||
env:
|
||||
RUST_CONFIGURE_ARGS: "--build=i686-pc-windows-gnu --enable-full-tools --enable-profiler --set llvm.allow-old-toolchain"
|
||||
NO_DOWNLOAD_CI_LLVM: 1
|
||||
SCRIPT: python x.py dist
|
||||
CUSTOM_MINGW: 1
|
||||
DIST_REQUIRE_ALL_TOOLS: 1
|
||||
|
@ -441,6 +446,7 @@ jobs:
|
|||
env:
|
||||
SCRIPT: python x.py dist
|
||||
RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-gnu --enable-full-tools --enable-profiler --set llvm.allow-old-toolchain"
|
||||
NO_DOWNLOAD_CI_LLVM: 1
|
||||
CUSTOM_MINGW: 1
|
||||
DIST_REQUIRE_ALL_TOOLS: 1
|
||||
os: windows-latest-xl
|
||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -42,6 +42,7 @@ no_llvm_build
|
|||
/llvm/
|
||||
/mingw-build/
|
||||
/build/
|
||||
/build-rust-analyzer/
|
||||
/dist/
|
||||
/unicode-downloads
|
||||
/target
|
||||
|
|
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -13,9 +13,6 @@
|
|||
[submodule "src/doc/book"]
|
||||
path = src/doc/book
|
||||
url = https://github.com/rust-lang/book.git
|
||||
[submodule "src/tools/rls"]
|
||||
path = src/tools/rls
|
||||
url = https://github.com/rust-lang/rls.git
|
||||
[submodule "src/tools/miri"]
|
||||
path = src/tools/miri
|
||||
url = https://github.com/rust-lang/miri.git
|
||||
|
|
28
.reuse/dep5
Normal file
28
.reuse/dep5
Normal file
|
@ -0,0 +1,28 @@
|
|||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Files-Excluded:
|
||||
src/llvm-project
|
||||
|
||||
Files: *
|
||||
Copyright: The Rust Project Developers (see https://thanks.rust-lang.org)
|
||||
License: MIT or Apache-2.0
|
||||
|
||||
Files: library/std/src/sync/mpsc/mpsc_queue.rs
|
||||
library/std/src/sync/mpsc/spsc_queue.rs
|
||||
Copyright: 2010-2011 Dmitry Vyukov
|
||||
License: BSD-2-Clause
|
||||
|
||||
Files: src/librustdoc/html/static/fonts/FiraSans*
|
||||
Copyright: 2014, Mozilla Foundation, 2014, Telefonica S.A.
|
||||
License: OFL-1.1
|
||||
|
||||
Files: src/librustdoc/html/static/fonts/NanumBarun*
|
||||
Copyright: 2010 NAVER Corporation
|
||||
License: OFL-1.1
|
||||
|
||||
Files: src/librustdoc/html/static/fonts/SourceCodePro*
|
||||
Copyright: 2010, 2012 Adobe Systems Incorporated
|
||||
License: OFL-1.1
|
||||
|
||||
Files: src/librustdoc/html/static/fonts/SourceSerif4*
|
||||
Copyright: 2014-2021 Adobe Systems Incorporated
|
||||
License: OFL-1.1
|
549
Cargo.lock
549
Cargo.lock
|
@ -79,7 +79,7 @@ dependencies = [
|
|||
"maplit",
|
||||
"once_cell",
|
||||
"tendril",
|
||||
"url 2.2.2",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -359,7 +359,7 @@ dependencies = [
|
|||
"openssl",
|
||||
"os_info",
|
||||
"pathdiff",
|
||||
"percent-encoding 2.1.0",
|
||||
"percent-encoding",
|
||||
"pretty_env_logger",
|
||||
"rustc-workspace-hack",
|
||||
"rustfix",
|
||||
|
@ -376,7 +376,7 @@ dependencies = [
|
|||
"toml_edit",
|
||||
"unicode-width",
|
||||
"unicode-xid",
|
||||
"url 2.2.2",
|
||||
"url",
|
||||
"walkdir",
|
||||
"winapi",
|
||||
]
|
||||
|
@ -462,7 +462,7 @@ dependencies = [
|
|||
"tar",
|
||||
"termcolor",
|
||||
"toml_edit",
|
||||
"url 2.2.2",
|
||||
"url",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
|
@ -665,7 +665,7 @@ dependencies = [
|
|||
"compiletest_rs",
|
||||
"derive-new",
|
||||
"filetime",
|
||||
"futures 0.3.19",
|
||||
"futures",
|
||||
"if_chain",
|
||||
"itertools",
|
||||
"parking_lot 0.12.1",
|
||||
|
@ -673,7 +673,7 @@ dependencies = [
|
|||
"regex",
|
||||
"rustc-semver",
|
||||
"rustc-workspace-hack",
|
||||
"rustc_tools_util 0.2.0",
|
||||
"rustc_tools_util",
|
||||
"semver",
|
||||
"serde",
|
||||
"syn",
|
||||
|
@ -718,7 +718,7 @@ dependencies = [
|
|||
"toml",
|
||||
"unicode-normalization",
|
||||
"unicode-script",
|
||||
"url 2.2.2",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -921,10 +921,10 @@ version = "0.34.0"
|
|||
dependencies = [
|
||||
"anyhow",
|
||||
"curl",
|
||||
"percent-encoding 2.1.0",
|
||||
"percent-encoding",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"url 2.2.2",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1093,17 +1093,6 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_more"
|
||||
version = "0.99.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "298998b1cf6b5b2c8a7b023dfd45821825ce3ba8a8af55c921a0e734e4653f76"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diff"
|
||||
version = "0.1.13"
|
||||
|
@ -1280,7 +1269,6 @@ name = "error_index_generator"
|
|||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"rustdoc",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1416,14 +1404,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
|
||||
dependencies = [
|
||||
"matches",
|
||||
"percent-encoding 2.1.0",
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fortanix-sgx-abi"
|
||||
version = "0.3.3"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c56c422ef86062869b2d57ae87270608dc5929969dd130a6e248979cf4fb6ca6"
|
||||
checksum = "57cafc2274c10fab234f176b25903ce17e690fca7597090d50880e047a0389c5"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-core",
|
||||
|
@ -1441,12 +1429,6 @@ version = "1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f2a4a2034423744d2cc7ca2068453168dcdb82c438419e639a26bd87839c674"
|
||||
|
||||
[[package]]
|
||||
name = "fst"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d79238883cf0307100b90aba4a755d8051a3182305dfe7f649a1e9dc0517006f"
|
||||
|
||||
[[package]]
|
||||
name = "futf"
|
||||
version = "0.1.5"
|
||||
|
@ -1457,12 +1439,6 @@ dependencies = [
|
|||
"new_debug_unreachable",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.1.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678"
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.19"
|
||||
|
@ -1503,7 +1479,6 @@ dependencies = [
|
|||
"futures-core",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1541,7 +1516,6 @@ version = "0.3.19"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b5cf40b47a271f77a8b1bec03ca09044d99d2372c0de244e66430761127164"
|
||||
dependencies = [
|
||||
"futures 0.1.31",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
|
@ -1652,9 +1626,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "git2"
|
||||
version = "0.14.2"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3826a6e0e2215d7a41c2bfc7c9244123969273f3476b939a226aac0ab56e9e3c"
|
||||
checksum = "2994bee4a3a6a51eb90c218523be382fd7ea09b16380b9312e9dbe955ff7c7d1"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"libc",
|
||||
|
@ -1662,19 +1636,19 @@ dependencies = [
|
|||
"log",
|
||||
"openssl-probe",
|
||||
"openssl-sys",
|
||||
"url 2.2.2",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "git2-curl"
|
||||
version = "0.15.0"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ee51709364c341fbb6fe2a385a290fb9196753bdde2fc45447d27cd31b11b13"
|
||||
checksum = "ed817a00721e2f8037ba722e60358d4956dae9cca10315fc982f967907d3b0cd"
|
||||
dependencies = [
|
||||
"curl",
|
||||
"git2",
|
||||
"log",
|
||||
"url 2.2.2",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1815,17 +1789,6 @@ version = "2.0.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c1ad908cc71012b7bea4d0c53ba96a8cba9962f048fa68d143376143d863b7a"
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
|
||||
dependencies = [
|
||||
"matches",
|
||||
"unicode-bidi",
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.2.0"
|
||||
|
@ -1980,12 +1943,6 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "json"
|
||||
version = "0.12.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd"
|
||||
|
||||
[[package]]
|
||||
name = "jsondocck"
|
||||
version = "0.1.0"
|
||||
|
@ -2012,110 +1969,6 @@ dependencies = [
|
|||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jsonrpc-client-transports"
|
||||
version = "18.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2b99d4207e2a04fb4581746903c2bb7eb376f88de9c699d0f3e10feeac0cd3a"
|
||||
dependencies = [
|
||||
"derive_more",
|
||||
"futures 0.3.19",
|
||||
"jsonrpc-core",
|
||||
"jsonrpc-pubsub",
|
||||
"jsonrpc-server-utils",
|
||||
"log",
|
||||
"parity-tokio-ipc",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
"url 1.7.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jsonrpc-core"
|
||||
version = "18.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14f7f76aef2d054868398427f6c54943cf3d1caa9a7ec7d0c38d69df97a965eb"
|
||||
dependencies = [
|
||||
"futures 0.3.19",
|
||||
"futures-executor",
|
||||
"futures-util",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jsonrpc-core-client"
|
||||
version = "18.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b51da17abecbdab3e3d4f26b01c5ec075e88d3abe3ab3b05dc9aa69392764ec0"
|
||||
dependencies = [
|
||||
"futures 0.3.19",
|
||||
"jsonrpc-client-transports",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jsonrpc-derive"
|
||||
version = "18.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b939a78fa820cdfcb7ee7484466746a7377760970f6f9c6fe19f9edcc8a38d2"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jsonrpc-ipc-server"
|
||||
version = "18.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "382bb0206323ca7cda3dcd7e245cea86d37d02457a02a975e3378fb149a48845"
|
||||
dependencies = [
|
||||
"futures 0.3.19",
|
||||
"jsonrpc-core",
|
||||
"jsonrpc-server-utils",
|
||||
"log",
|
||||
"parity-tokio-ipc",
|
||||
"parking_lot 0.11.2",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jsonrpc-pubsub"
|
||||
version = "18.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240f87695e6c6f62fb37f05c02c04953cf68d6408b8c1c89de85c7a0125b1011"
|
||||
dependencies = [
|
||||
"futures 0.3.19",
|
||||
"jsonrpc-core",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"parking_lot 0.11.2",
|
||||
"rand 0.7.3",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jsonrpc-server-utils"
|
||||
version = "18.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa4fdea130485b572c39a460d50888beb00afb3e35de23ccd7fad8ff19f0e0d4"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures 0.3.19",
|
||||
"globset",
|
||||
"jsonrpc-core",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tokio-util",
|
||||
"unicase",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kstring"
|
||||
version = "2.0.0"
|
||||
|
@ -2148,9 +2001,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "libgit2-sys"
|
||||
version = "0.13.2+1.4.2"
|
||||
version = "0.14.0+1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a42de9a51a5c12e00fc0e4ca6bc2ea43582fc6418488e8f615e905d886f258b"
|
||||
checksum = "47a00859c70c8a4f7218e6d1cc32875c4b55f6799445b842b0d8ed5e4c3d959b"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
|
@ -2258,30 +2111,6 @@ dependencies = [
|
|||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lsp-codec"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa939d0b62476a5a19fb7fcb423a5c6ce8c7e09b851d37531e2fe3e0e6d9d257"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"serde_json",
|
||||
"tokio-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lsp-types"
|
||||
version = "0.60.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe3edefcd66dde1f7f1df706f46520a3c93adc5ca4bc5747da6621195e894efd"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_repr",
|
||||
"url 2.2.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lzma-sys"
|
||||
version = "0.1.16"
|
||||
|
@ -2415,9 +2244,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "minifier"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac96d1e7a65f206443f95afff6de8f1690c77c97d6fc9c9bb2d2cd0662e9ff9f"
|
||||
checksum = "8eb022374af2f446981254e6bf9efb6e2c9e1a53176d395fca02792fd4435729"
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
|
@ -2446,19 +2275,6 @@ dependencies = [
|
|||
"adler 1.0.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.7.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"miow",
|
||||
"ntapi",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miow"
|
||||
version = "0.3.7"
|
||||
|
@ -2510,15 +2326,6 @@ version = "0.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be"
|
||||
|
||||
[[package]]
|
||||
name = "ntapi"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.43"
|
||||
|
@ -2647,12 +2454,6 @@ dependencies = [
|
|||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ordslice"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd20eec3dbe4376829cb7d80ae6ac45e0a766831dca50202ff2d40db46a8a024"
|
||||
|
||||
[[package]]
|
||||
name = "os_info"
|
||||
version = "3.5.0"
|
||||
|
@ -2718,20 +2519,6 @@ dependencies = [
|
|||
"unwind",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parity-tokio-ipc"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9981e32fb75e004cc148f5fb70342f393830e0a4aa62e3cc93b50976218d42b6"
|
||||
dependencies = [
|
||||
"futures 0.3.19",
|
||||
"libc",
|
||||
"log",
|
||||
"rand 0.7.3",
|
||||
"tokio",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.11.2"
|
||||
|
@ -2786,12 +2573,6 @@ version = "0.2.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.1.0"
|
||||
|
@ -2961,15 +2742,6 @@ dependencies = [
|
|||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-crate"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785"
|
||||
dependencies = [
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
|
@ -3079,37 +2851,6 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "racer"
|
||||
version = "2.2.2"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"derive_more",
|
||||
"env_logger 0.7.1",
|
||||
"humantime 2.0.1",
|
||||
"lazy_static",
|
||||
"lazycell",
|
||||
"log",
|
||||
"racer-cargo-metadata",
|
||||
"rls-span",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "racer-cargo-metadata"
|
||||
version = "0.1.2"
|
||||
dependencies = [
|
||||
"racer-interner",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "racer-interner"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.7.3"
|
||||
|
@ -3295,68 +3036,18 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "rls"
|
||||
version = "1.41.0"
|
||||
name = "replace-version-placeholder"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cargo",
|
||||
"cargo-util",
|
||||
"cargo_metadata 0.14.0",
|
||||
"clippy_lints",
|
||||
"crossbeam-channel",
|
||||
"difference",
|
||||
"env_logger 0.9.0",
|
||||
"futures 0.3.19",
|
||||
"heck",
|
||||
"home",
|
||||
"itertools",
|
||||
"jsonrpc-core",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"lsp-codec",
|
||||
"lsp-types",
|
||||
"num_cpus",
|
||||
"ordslice",
|
||||
"racer",
|
||||
"rand 0.8.5",
|
||||
"rayon",
|
||||
"regex",
|
||||
"rls-analysis",
|
||||
"rls-data",
|
||||
"rls-ipc",
|
||||
"rls-rustc",
|
||||
"rls-span",
|
||||
"rls-vfs",
|
||||
"rustc-workspace-hack",
|
||||
"rustc_tools_util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustfmt-nightly",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_ignored",
|
||||
"serde_json",
|
||||
"tempfile",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tokio-util",
|
||||
"toml",
|
||||
"toml_edit",
|
||||
"url 2.2.2",
|
||||
"tidy",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rls-analysis"
|
||||
version = "0.18.3"
|
||||
name = "rls"
|
||||
version = "2.0.0"
|
||||
dependencies = [
|
||||
"derive-new",
|
||||
"env_logger 0.9.0",
|
||||
"fst",
|
||||
"itertools",
|
||||
"json",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"rls-data",
|
||||
"rls-span",
|
||||
"rustc-workspace-hack",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
@ -3371,33 +3062,6 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rls-ipc"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"jsonrpc-core",
|
||||
"jsonrpc-core-client",
|
||||
"jsonrpc-derive",
|
||||
"jsonrpc-ipc-server",
|
||||
"rls-data",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rls-rustc"
|
||||
version = "0.6.0"
|
||||
dependencies = [
|
||||
"clippy_lints",
|
||||
"env_logger 0.9.0",
|
||||
"futures 0.3.19",
|
||||
"log",
|
||||
"rand 0.8.5",
|
||||
"rls-data",
|
||||
"rls-ipc",
|
||||
"serde",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rls-span"
|
||||
version = "0.5.3"
|
||||
|
@ -3407,16 +3071,6 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rls-vfs"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce4b57b25b4330ed5ec14028fc02141e083ddafda327e7eb598dc0569c8c83c9"
|
||||
dependencies = [
|
||||
"log",
|
||||
"rls-span",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-demangler"
|
||||
version = "0.0.1"
|
||||
|
@ -3516,21 +3170,13 @@ name = "rustc-workspace-hack"
|
|||
version = "1.0.0"
|
||||
dependencies = [
|
||||
"bstr",
|
||||
"byteorder",
|
||||
"clap",
|
||||
"crossbeam-utils",
|
||||
"libc",
|
||||
"libz-sys",
|
||||
"memchr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rand_core 0.5.1",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"smallvec",
|
||||
"syn",
|
||||
"url 2.2.2",
|
||||
"url",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
|
@ -3575,6 +3221,7 @@ dependencies = [
|
|||
"rustc_errors",
|
||||
"rustc_hir",
|
||||
"rustc_index",
|
||||
"rustc_macros",
|
||||
"rustc_middle",
|
||||
"rustc_query_system",
|
||||
"rustc_session",
|
||||
|
@ -3595,6 +3242,7 @@ dependencies = [
|
|||
"rustc_data_structures",
|
||||
"rustc_errors",
|
||||
"rustc_feature",
|
||||
"rustc_macros",
|
||||
"rustc_parse",
|
||||
"rustc_session",
|
||||
"rustc_span",
|
||||
|
@ -3686,6 +3334,7 @@ dependencies = [
|
|||
"libc",
|
||||
"libloading",
|
||||
"measureme",
|
||||
"object 0.29.0",
|
||||
"rustc-demangle",
|
||||
"rustc_ast",
|
||||
"rustc_attr",
|
||||
|
@ -3721,7 +3370,6 @@ dependencies = [
|
|||
"object 0.29.0",
|
||||
"pathdiff",
|
||||
"regex",
|
||||
"rustc_apfloat",
|
||||
"rustc_arena",
|
||||
"rustc_ast",
|
||||
"rustc_attr",
|
||||
|
@ -3819,6 +3467,7 @@ dependencies = [
|
|||
"rustc_interface",
|
||||
"rustc_lint",
|
||||
"rustc_log",
|
||||
"rustc_macros",
|
||||
"rustc_metadata",
|
||||
"rustc_middle",
|
||||
"rustc_parse",
|
||||
|
@ -3982,6 +3631,7 @@ dependencies = [
|
|||
"rustc_macros",
|
||||
"rustc_middle",
|
||||
"rustc_serialize",
|
||||
"rustc_session",
|
||||
"rustc_span",
|
||||
"rustc_target",
|
||||
"smallvec",
|
||||
|
@ -4212,11 +3862,14 @@ dependencies = [
|
|||
"regex",
|
||||
"rustc_ast",
|
||||
"rustc_data_structures",
|
||||
"rustc_errors",
|
||||
"rustc_graphviz",
|
||||
"rustc_hir",
|
||||
"rustc_index",
|
||||
"rustc_macros",
|
||||
"rustc_middle",
|
||||
"rustc_serialize",
|
||||
"rustc_session",
|
||||
"rustc_span",
|
||||
"rustc_target",
|
||||
"smallvec",
|
||||
|
@ -4252,8 +3905,10 @@ name = "rustc_monomorphize"
|
|||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"rustc_data_structures",
|
||||
"rustc_errors",
|
||||
"rustc_hir",
|
||||
"rustc_index",
|
||||
"rustc_macros",
|
||||
"rustc_middle",
|
||||
"rustc_session",
|
||||
"rustc_span",
|
||||
|
@ -4320,6 +3975,7 @@ dependencies = [
|
|||
"rustc_ast",
|
||||
"rustc_errors",
|
||||
"rustc_lint",
|
||||
"rustc_macros",
|
||||
"rustc_metadata",
|
||||
"rustc_session",
|
||||
"rustc_span",
|
||||
|
@ -4419,9 +4075,11 @@ dependencies = [
|
|||
"rustc_ast",
|
||||
"rustc_ast_pretty",
|
||||
"rustc_data_structures",
|
||||
"rustc_errors",
|
||||
"rustc_hir",
|
||||
"rustc_hir_pretty",
|
||||
"rustc_lexer",
|
||||
"rustc_macros",
|
||||
"rustc_middle",
|
||||
"rustc_session",
|
||||
"rustc_span",
|
||||
|
@ -4498,7 +4156,9 @@ dependencies = [
|
|||
"punycode",
|
||||
"rustc-demangle",
|
||||
"rustc_data_structures",
|
||||
"rustc_errors",
|
||||
"rustc_hir",
|
||||
"rustc_macros",
|
||||
"rustc_middle",
|
||||
"rustc_session",
|
||||
"rustc_span",
|
||||
|
@ -4524,12 +4184,6 @@ dependencies = [
|
|||
name = "rustc_tools_util"
|
||||
version = "0.2.0"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_tools_util"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b725dadae9fabc488df69a287f5a99c5eaf5d10853842a8a3dfac52476f544ee"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_trait_selection"
|
||||
version = "0.0.0"
|
||||
|
@ -4597,6 +4251,7 @@ dependencies = [
|
|||
"rustc_hir",
|
||||
"rustc_index",
|
||||
"rustc_infer",
|
||||
"rustc_macros",
|
||||
"rustc_middle",
|
||||
"rustc_session",
|
||||
"rustc_span",
|
||||
|
@ -4835,18 +4490,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.140"
|
||||
version = "1.0.143"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc855a42c7967b7c369eb5860f7164ef1f6f81c20c7cc1141f2a604e18723b03"
|
||||
checksum = "53e8e5d5b70924f74ff5c6d64d9a5acd91422117c60f48c4e07855238a254553"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.140"
|
||||
version = "1.0.143"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f2122636b9fe3b81f1cb25099fcf2d3f542cdb1d45940d56c713158884a05da"
|
||||
checksum = "d3d8e8de557aee63c26b85b947f5e59b690d0454c753f3adeb5cd7835ab88391"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -4864,9 +4519,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.82"
|
||||
version = "1.0.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7"
|
||||
checksum = "38dd04e3c8279e75b31ef29dbdceebfe5ad89f4d0937213c53f7d49d01b3d5a7"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"itoa",
|
||||
|
@ -4874,17 +4529,6 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_repr"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dc6b7951b17b051f3210b063f12cc17320e2fe30ae05b0fe2a3abb068551c76"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha-1"
|
||||
version = "0.8.2"
|
||||
|
@ -4940,15 +4584,6 @@ version = "1.0.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42a568c8f2cd051a4d283bd6eb0343ac214c1b0f1ac19f93e1175b2dee38c73d"
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce32ea0c6c56d5eacaeb814fbed9960547021d3edd010ded1425f180536b20ab"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "similar"
|
||||
version = "2.1.0"
|
||||
|
@ -4991,9 +4626,9 @@ checksum = "da73c8f77aebc0e40c300b93f0a5f1bece7a248a36eee287d4e095f35c7b7d6e"
|
|||
|
||||
[[package]]
|
||||
name = "snapbox"
|
||||
version = "0.2.9"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1f212b806d6f56d19838e36a0aaa7e79a0bc9ca177e873fb87651ad92f983e2"
|
||||
checksum = "44d199ccf8f606592df2d145db26f2aa45344e23c64b074cc5a4047f1d99b0f7"
|
||||
dependencies = [
|
||||
"concolor",
|
||||
"content_inspector",
|
||||
|
@ -5009,9 +4644,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "snapbox-macros"
|
||||
version = "0.2.1"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c01dea7e04cbb27ef4c86e9922184608185f7cd95c1763bc30d727cda4a5e930"
|
||||
checksum = "8a253e6f894cfa440cba00600a249fa90869d8e0ec45ab274a456e043a0ce8f2"
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
|
@ -5294,7 +4929,6 @@ name = "tidy"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cargo_metadata 0.14.0",
|
||||
"crossbeam-utils",
|
||||
"lazy_static",
|
||||
"regex",
|
||||
"walkdir",
|
||||
|
@ -5334,39 +4968,8 @@ checksum = "50dae83881bc9b0403dd5b44ea9deed3e939856cc8722d5be37f0d6e5c6d53dd"
|
|||
dependencies = [
|
||||
"autocfg",
|
||||
"bytes",
|
||||
"libc",
|
||||
"memchr",
|
||||
"mio",
|
||||
"num_cpus",
|
||||
"once_cell",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-stream"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b2f3f698253f03119ac0102beaa64f67a67e08074d03a22d18784104543727f"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.6.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1caa0b0c8d94a049db56b5acf8cba99dc0623aab1b26d5b5f5e2d945846b3592"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"log",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -5397,17 +5000,11 @@ version = "0.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa7c7f42dea4b1b99439786f5633aeb9c14c1b53f75e282803c2ec2ad545873c"
|
||||
|
||||
[[package]]
|
||||
name = "tower-service"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6"
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.29"
|
||||
version = "0.1.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105"
|
||||
checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"pin-project-lite",
|
||||
|
@ -5417,9 +5014,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tracing-attributes"
|
||||
version = "0.1.18"
|
||||
version = "0.1.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4f480b8f81512e825f337ad51e94c1eb5d3bbdf2b363dcd01e2b19a9ffe3f8e"
|
||||
checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -5428,11 +5025,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.21"
|
||||
version = "0.1.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f4ed65637b8390770814083d20756f87bfa2c21bf2f110babdc5438351746e4"
|
||||
checksum = "7b7358be39f2f274f322d2aaed611acc57f382e8eb1e5b48cb9ae30933495ce7"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"once_cell",
|
||||
"valuable",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -5726,17 +5324,6 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "1.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a"
|
||||
dependencies = [
|
||||
"idna 0.1.5",
|
||||
"matches",
|
||||
"percent-encoding 1.0.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.2.2"
|
||||
|
@ -5744,9 +5331,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna 0.2.0",
|
||||
"idna",
|
||||
"matches",
|
||||
"percent-encoding 2.1.0",
|
||||
"percent-encoding",
|
||||
"serde",
|
||||
]
|
||||
|
||||
|
@ -5762,6 +5349,12 @@ version = "0.1.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8772a4ccbb4e89959023bc5b7cb8623a795caa7092d99f3aa9501b9484d4557d"
|
||||
|
||||
[[package]]
|
||||
name = "valuable"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.10"
|
||||
|
|
16
Cargo.toml
16
Cargo.toml
|
@ -35,6 +35,7 @@ members = [
|
|||
"src/tools/jsondocck",
|
||||
"src/tools/html-checker",
|
||||
"src/tools/bump-stage0",
|
||||
"src/tools/replace-version-placeholder",
|
||||
"src/tools/lld-wrapper",
|
||||
]
|
||||
|
||||
|
@ -96,21 +97,6 @@ gimli.debug = 0
|
|||
miniz_oxide.debug = 0
|
||||
object.debug = 0
|
||||
|
||||
# We want the RLS to use the version of Cargo that we've got vendored in this
|
||||
# repository to ensure that the same exact version of Cargo is used by both the
|
||||
# RLS and the Cargo binary itself. The RLS depends on Cargo as a git repository
|
||||
# so we use a `[patch]` here to override the github repository with our local
|
||||
# vendored copy.
|
||||
[patch."https://github.com/rust-lang/cargo"]
|
||||
cargo = { path = "src/tools/cargo" }
|
||||
cargo-util = { path = "src/tools/cargo/crates/cargo-util" }
|
||||
|
||||
[patch."https://github.com/rust-lang/rustfmt"]
|
||||
# Similar to Cargo above we want the RLS to use a vendored version of `rustfmt`
|
||||
# that we're shipping as well (to ensure that the rustfmt in RLS and the
|
||||
# `rustfmt` executable are the same exact version).
|
||||
rustfmt-nightly = { path = "src/tools/rustfmt" }
|
||||
|
||||
[patch.crates-io]
|
||||
# See comments in `src/tools/rustc-workspace-hack/README.md` for what's going on
|
||||
# here
|
||||
|
|
73
LICENSES/Apache-2.0.txt
Normal file
73
LICENSES/Apache-2.0.txt
Normal file
|
@ -0,0 +1,73 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
9
LICENSES/BSD-2-Clause.txt
Normal file
9
LICENSES/BSD-2-Clause.txt
Normal file
|
@ -0,0 +1,9 @@
|
|||
Copyright (c) <year> <owner>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
9
LICENSES/MIT.txt
Normal file
9
LICENSES/MIT.txt
Normal file
|
@ -0,0 +1,9 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) <year> <copyright holders>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
43
LICENSES/OFL-1.1.txt
Normal file
43
LICENSES/OFL-1.1.txt
Normal file
|
@ -0,0 +1,43 @@
|
|||
SIL OPEN FONT LICENSE
|
||||
|
||||
Version 1.1 - 26 February 2007
|
||||
|
||||
PREAMBLE
|
||||
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
|
||||
"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting, or substituting — in part or in whole — any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
|
||||
This license becomes null and void if any of the above conditions are not met.
|
||||
|
||||
DISCLAIMER
|
||||
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
@ -83,7 +83,7 @@ by running it with the `--help` flag or reading the [rustc dev guide][rustcguide
|
|||
If you plan to use `x.py install` to create an installation, it is recommended
|
||||
that you set the `prefix` value in the `[install]` section to a directory.
|
||||
|
||||
Create install directory if you are not installing in default directory.
|
||||
Create an install directory if you are not installing in the default directory.
|
||||
|
||||
4. Build and install:
|
||||
|
||||
|
@ -153,7 +153,7 @@ build.
|
|||
#### MSVC
|
||||
|
||||
MSVC builds of Rust additionally require an installation of Visual Studio 2017
|
||||
(or later) so `rustc` can use its linker. The simplest way is to get the
|
||||
(or later) so `rustc` can use its linker. The simplest way is to get
|
||||
[Visual Studio], check the “C++ build tools” and “Windows 10 SDK” workload.
|
||||
|
||||
[Visual Studio]: https://visualstudio.microsoft.com/downloads/
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
||||
#![no_std]
|
||||
#![forbid(unsafe_code)]
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate alloc;
|
||||
|
|
|
@ -16,9 +16,12 @@
|
|||
#![feature(maybe_uninit_slice)]
|
||||
#![feature(min_specialization)]
|
||||
#![feature(decl_macro)]
|
||||
#![feature(pointer_byte_offsets)]
|
||||
#![feature(rustc_attrs)]
|
||||
#![cfg_attr(test, feature(test))]
|
||||
#![feature(strict_provenance)]
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
|
||||
use smallvec::SmallVec;
|
||||
|
||||
|
@ -209,7 +212,7 @@ impl<T> TypedArena<T> {
|
|||
|
||||
unsafe {
|
||||
if mem::size_of::<T>() == 0 {
|
||||
self.ptr.set((self.ptr.get() as *mut u8).wrapping_offset(1) as *mut T);
|
||||
self.ptr.set(self.ptr.get().wrapping_byte_add(1));
|
||||
let ptr = ptr::NonNull::<T>::dangling().as_ptr();
|
||||
// Don't drop the object. This `write` is equivalent to `forget`.
|
||||
ptr::write(ptr, object);
|
||||
|
@ -217,7 +220,7 @@ impl<T> TypedArena<T> {
|
|||
} else {
|
||||
let ptr = self.ptr.get();
|
||||
// Advance the pointer.
|
||||
self.ptr.set(self.ptr.get().offset(1));
|
||||
self.ptr.set(self.ptr.get().add(1));
|
||||
// Write into uninitialized memory.
|
||||
ptr::write(ptr, object);
|
||||
&mut *ptr
|
||||
|
|
|
@ -504,7 +504,7 @@ pub struct WhereEqPredicate {
|
|||
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
pub struct Crate {
|
||||
pub attrs: Vec<Attribute>,
|
||||
pub attrs: AttrVec,
|
||||
pub items: Vec<P<Item>>,
|
||||
pub spans: ModSpans,
|
||||
/// Must be equal to `CRATE_NODE_ID` after the crate root is expanded, but may hold
|
||||
|
@ -770,7 +770,7 @@ pub enum PatKind {
|
|||
Paren(P<Pat>),
|
||||
|
||||
/// A macro pattern; pre-expansion.
|
||||
MacCall(MacCall),
|
||||
MacCall(P<MacCall>),
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)]
|
||||
|
@ -980,7 +980,7 @@ pub enum StmtKind {
|
|||
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
pub struct MacCallStmt {
|
||||
pub mac: MacCall,
|
||||
pub mac: P<MacCall>,
|
||||
pub style: MacStmtStyle,
|
||||
pub attrs: AttrVec,
|
||||
pub tokens: Option<LazyTokenStream>,
|
||||
|
@ -1268,7 +1268,7 @@ impl Expr {
|
|||
id: DUMMY_NODE_ID,
|
||||
kind: ExprKind::Err,
|
||||
span: DUMMY_SP,
|
||||
attrs: ThinVec::new(),
|
||||
attrs: AttrVec::new(),
|
||||
tokens: None,
|
||||
},
|
||||
)
|
||||
|
@ -1437,7 +1437,7 @@ pub enum ExprKind {
|
|||
InlineAsm(P<InlineAsm>),
|
||||
|
||||
/// A macro invocation; pre-expansion.
|
||||
MacCall(MacCall),
|
||||
MacCall(P<MacCall>),
|
||||
|
||||
/// A struct literal expression.
|
||||
///
|
||||
|
@ -1751,7 +1751,8 @@ pub enum LitFloatType {
|
|||
/// E.g., `"foo"`, `42`, `12.34`, or `bool`.
|
||||
#[derive(Clone, Encodable, Decodable, Debug, Hash, Eq, PartialEq, HashStable_Generic)]
|
||||
pub enum LitKind {
|
||||
/// A string literal (`"foo"`).
|
||||
/// A string literal (`"foo"`). The symbol is unescaped, and so may differ
|
||||
/// from the original token's symbol.
|
||||
Str(Symbol, StrStyle),
|
||||
/// A byte string (`b"foo"`).
|
||||
ByteStr(Lrc<[u8]>),
|
||||
|
@ -1761,12 +1762,13 @@ pub enum LitKind {
|
|||
Char(char),
|
||||
/// An integer literal (`1`).
|
||||
Int(u128, LitIntType),
|
||||
/// A float literal (`1f64` or `1E10f64`).
|
||||
/// A float literal (`1f64` or `1E10f64`). Stored as a symbol rather than
|
||||
/// `f64` so that `LitKind` can impl `Eq` and `Hash`.
|
||||
Float(Symbol, LitFloatType),
|
||||
/// A boolean literal.
|
||||
Bool(bool),
|
||||
/// Placeholder for a literal that wasn't well-formed in some way.
|
||||
Err(Symbol),
|
||||
Err,
|
||||
}
|
||||
|
||||
impl LitKind {
|
||||
|
@ -1805,7 +1807,7 @@ impl LitKind {
|
|||
| LitKind::Int(_, LitIntType::Unsuffixed)
|
||||
| LitKind::Float(_, LitFloatType::Unsuffixed)
|
||||
| LitKind::Bool(..)
|
||||
| LitKind::Err(..) => false,
|
||||
| LitKind::Err => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2040,7 +2042,7 @@ pub enum TyKind {
|
|||
/// Inferred type of a `self` or `&self` argument in a method.
|
||||
ImplicitSelf,
|
||||
/// A macro in the type position.
|
||||
MacCall(MacCall),
|
||||
MacCall(P<MacCall>),
|
||||
/// Placeholder for a kind that has failed to be defined.
|
||||
Err,
|
||||
/// Placeholder for a `va_list`.
|
||||
|
@ -2669,7 +2671,7 @@ impl VariantData {
|
|||
/// An item definition.
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
pub struct Item<K = ItemKind> {
|
||||
pub attrs: Vec<Attribute>,
|
||||
pub attrs: AttrVec,
|
||||
pub id: NodeId,
|
||||
pub span: Span,
|
||||
pub vis: Visibility,
|
||||
|
@ -2877,7 +2879,7 @@ pub enum ItemKind {
|
|||
/// A macro invocation.
|
||||
///
|
||||
/// E.g., `foo!(..)`.
|
||||
MacCall(MacCall),
|
||||
MacCall(P<MacCall>),
|
||||
|
||||
/// A macro definition.
|
||||
MacroDef(MacroDef),
|
||||
|
@ -2951,7 +2953,7 @@ pub enum AssocItemKind {
|
|||
/// An associated type.
|
||||
TyAlias(Box<TyAlias>),
|
||||
/// A macro expanding to associated items.
|
||||
MacCall(MacCall),
|
||||
MacCall(P<MacCall>),
|
||||
}
|
||||
|
||||
impl AssocItemKind {
|
||||
|
@ -3000,7 +3002,7 @@ pub enum ForeignItemKind {
|
|||
/// An foreign type.
|
||||
TyAlias(Box<TyAlias>),
|
||||
/// A macro expanding to foreign items.
|
||||
MacCall(MacCall),
|
||||
MacCall(P<MacCall>),
|
||||
}
|
||||
|
||||
impl From<ForeignItemKind> for ItemKind {
|
||||
|
@ -3036,19 +3038,19 @@ mod size_asserts {
|
|||
use super::*;
|
||||
use rustc_data_structures::static_assert_size;
|
||||
// These are in alphabetical order, which is easy to maintain.
|
||||
static_assert_size!(AssocItem, 160);
|
||||
static_assert_size!(AssocItemKind, 72);
|
||||
static_assert_size!(AssocItem, 104);
|
||||
static_assert_size!(AssocItemKind, 32);
|
||||
static_assert_size!(Attribute, 32);
|
||||
static_assert_size!(Block, 48);
|
||||
static_assert_size!(Expr, 104);
|
||||
static_assert_size!(ExprKind, 72);
|
||||
static_assert_size!(Fn, 192);
|
||||
static_assert_size!(ForeignItem, 160);
|
||||
static_assert_size!(ForeignItemKind, 72);
|
||||
static_assert_size!(ForeignItem, 96);
|
||||
static_assert_size!(ForeignItemKind, 24);
|
||||
static_assert_size!(GenericBound, 88);
|
||||
static_assert_size!(Generics, 72);
|
||||
static_assert_size!(Impl, 200);
|
||||
static_assert_size!(Item, 200);
|
||||
static_assert_size!(Item, 184);
|
||||
static_assert_size!(ItemKind, 112);
|
||||
static_assert_size!(Lit, 48);
|
||||
static_assert_size!(LitKind, 24);
|
||||
|
|
|
@ -270,7 +270,7 @@ pub trait HasAttrs {
|
|||
/// during token collection.
|
||||
const SUPPORTS_CUSTOM_INNER_ATTRS: bool;
|
||||
fn attrs(&self) -> &[Attribute];
|
||||
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>));
|
||||
fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec));
|
||||
}
|
||||
|
||||
macro_rules! impl_has_attrs {
|
||||
|
@ -283,8 +283,8 @@ macro_rules! impl_has_attrs {
|
|||
&self.attrs
|
||||
}
|
||||
|
||||
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
|
||||
VecOrAttrVec::visit(&mut self.attrs, f)
|
||||
fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) {
|
||||
f(&mut self.attrs)
|
||||
}
|
||||
}
|
||||
)+
|
||||
|
@ -299,7 +299,7 @@ macro_rules! impl_has_attrs_none {
|
|||
fn attrs(&self) -> &[Attribute] {
|
||||
&[]
|
||||
}
|
||||
fn visit_attrs(&mut self, _f: impl FnOnce(&mut Vec<Attribute>)) {}
|
||||
fn visit_attrs(&mut self, _f: impl FnOnce(&mut AttrVec)) {}
|
||||
}
|
||||
)+
|
||||
};
|
||||
|
@ -330,7 +330,7 @@ impl<T: AstDeref<Target: HasAttrs>> HasAttrs for T {
|
|||
fn attrs(&self) -> &[Attribute] {
|
||||
self.ast_deref().attrs()
|
||||
}
|
||||
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
|
||||
fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) {
|
||||
self.ast_deref_mut().visit_attrs(f)
|
||||
}
|
||||
}
|
||||
|
@ -340,7 +340,7 @@ impl<T: HasAttrs> HasAttrs for Option<T> {
|
|||
fn attrs(&self) -> &[Attribute] {
|
||||
self.as_ref().map(|inner| inner.attrs()).unwrap_or(&[])
|
||||
}
|
||||
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
|
||||
fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) {
|
||||
if let Some(inner) = self.as_mut() {
|
||||
inner.visit_attrs(f);
|
||||
}
|
||||
|
@ -362,13 +362,13 @@ impl HasAttrs for StmtKind {
|
|||
}
|
||||
}
|
||||
|
||||
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
|
||||
fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) {
|
||||
match self {
|
||||
StmtKind::Local(local) => visit_attrvec(&mut local.attrs, f),
|
||||
StmtKind::Local(local) => f(&mut local.attrs),
|
||||
StmtKind::Expr(expr) | StmtKind::Semi(expr) => expr.visit_attrs(f),
|
||||
StmtKind::Item(item) => item.visit_attrs(f),
|
||||
StmtKind::Empty => {}
|
||||
StmtKind::MacCall(mac) => visit_attrvec(&mut mac.attrs, f),
|
||||
StmtKind::MacCall(mac) => f(&mut mac.attrs),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -378,38 +378,11 @@ impl HasAttrs for Stmt {
|
|||
fn attrs(&self) -> &[Attribute] {
|
||||
self.kind.attrs()
|
||||
}
|
||||
fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
|
||||
fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) {
|
||||
self.kind.visit_attrs(f);
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper trait for the impls above. Abstracts over
|
||||
/// the two types of attribute fields that AST nodes
|
||||
/// may have (`Vec<Attribute>` or `AttrVec`).
|
||||
trait VecOrAttrVec {
|
||||
fn visit(&mut self, f: impl FnOnce(&mut Vec<Attribute>));
|
||||
}
|
||||
|
||||
impl VecOrAttrVec for Vec<Attribute> {
|
||||
fn visit(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
|
||||
f(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl VecOrAttrVec for AttrVec {
|
||||
fn visit(&mut self, f: impl FnOnce(&mut Vec<Attribute>)) {
|
||||
visit_attrvec(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_attrvec(attrs: &mut AttrVec, f: impl FnOnce(&mut Vec<Attribute>)) {
|
||||
crate::mut_visit::visit_clobber(attrs, |attrs| {
|
||||
let mut vec = attrs.into();
|
||||
f(&mut vec);
|
||||
vec.into()
|
||||
});
|
||||
}
|
||||
|
||||
/// A newtype around an AST node that implements the traits above if the node implements them.
|
||||
pub struct AstNodeWrapper<Wrapped, Tag> {
|
||||
pub wrapped: Wrapped,
|
||||
|
|
|
@ -12,7 +12,6 @@ use crate::tokenstream::{DelimSpan, Spacing, TokenTree};
|
|||
use crate::tokenstream::{LazyTokenStream, TokenStream};
|
||||
use crate::util::comments;
|
||||
|
||||
use rustc_data_structures::thin_vec::ThinVec;
|
||||
use rustc_index::bit_set::GrowableBitSet;
|
||||
use rustc_span::source_map::BytePos;
|
||||
use rustc_span::symbol::{sym, Ident, Symbol};
|
||||
|
@ -487,7 +486,7 @@ impl MetaItemKind {
|
|||
id: ast::DUMMY_NODE_ID,
|
||||
kind: ast::ExprKind::Lit(lit.clone()),
|
||||
span: lit.span,
|
||||
attrs: ThinVec::new(),
|
||||
attrs: ast::AttrVec::new(),
|
||||
tokens: None,
|
||||
});
|
||||
MacArgs::Eq(span, MacArgsEq::Ast(expr))
|
||||
|
|
|
@ -13,12 +13,15 @@
|
|||
#![feature(const_default_impls)]
|
||||
#![feature(const_trait_impl)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(label_break_value)]
|
||||
#![cfg_attr(bootstrap, feature(label_break_value))]
|
||||
#![feature(let_chains)]
|
||||
#![feature(min_specialization)]
|
||||
#![feature(negative_impls)]
|
||||
#![feature(slice_internals)]
|
||||
#![feature(stmt_expr_attributes)]
|
||||
#![recursion_limit = "256"]
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate rustc_macros;
|
||||
|
|
|
@ -14,7 +14,6 @@ use crate::tokenstream::*;
|
|||
|
||||
use rustc_data_structures::map_in_place::MapInPlace;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_data_structures::thin_vec::ThinVec;
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::Span;
|
||||
|
@ -338,12 +337,7 @@ where
|
|||
}
|
||||
|
||||
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
|
||||
pub fn visit_attrs<T: MutVisitor>(attrs: &mut Vec<Attribute>, vis: &mut T) {
|
||||
visit_vec(attrs, |attr| vis.visit_attribute(attr));
|
||||
}
|
||||
|
||||
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
|
||||
pub fn visit_thin_attrs<T: MutVisitor>(attrs: &mut AttrVec, vis: &mut T) {
|
||||
pub fn visit_attrs<T: MutVisitor>(attrs: &mut AttrVec, vis: &mut T) {
|
||||
for attr in attrs.iter_mut() {
|
||||
vis.visit_attribute(attr);
|
||||
}
|
||||
|
@ -398,7 +392,7 @@ pub fn noop_flat_map_pat_field<T: MutVisitor>(
|
|||
vis.visit_ident(ident);
|
||||
vis.visit_pat(pat);
|
||||
vis.visit_span(span);
|
||||
visit_thin_attrs(attrs, vis);
|
||||
visit_attrs(attrs, vis);
|
||||
smallvec![fp]
|
||||
}
|
||||
|
||||
|
@ -424,7 +418,7 @@ pub fn noop_visit_use_tree<T: MutVisitor>(use_tree: &mut UseTree, vis: &mut T) {
|
|||
|
||||
pub fn noop_flat_map_arm<T: MutVisitor>(mut arm: Arm, vis: &mut T) -> SmallVec<[Arm; 1]> {
|
||||
let Arm { attrs, pat, guard, body, span, id, is_placeholder: _ } = &mut arm;
|
||||
visit_thin_attrs(attrs, vis);
|
||||
visit_attrs(attrs, vis);
|
||||
vis.visit_id(id);
|
||||
vis.visit_pat(pat);
|
||||
visit_opt(guard, |guard| vis.visit_expr(guard));
|
||||
|
@ -507,7 +501,7 @@ pub fn noop_flat_map_variant<T: MutVisitor>(
|
|||
let Variant { ident, vis, attrs, id, data, disr_expr, span, is_placeholder: _ } = &mut variant;
|
||||
visitor.visit_ident(ident);
|
||||
visitor.visit_vis(vis);
|
||||
visit_thin_attrs(attrs, visitor);
|
||||
visit_attrs(attrs, visitor);
|
||||
visitor.visit_id(id);
|
||||
visitor.visit_variant_data(data);
|
||||
visit_opt(disr_expr, |disr_expr| visitor.visit_anon_const(disr_expr));
|
||||
|
@ -589,7 +583,7 @@ pub fn noop_visit_local<T: MutVisitor>(local: &mut P<Local>, vis: &mut T) {
|
|||
}
|
||||
}
|
||||
vis.visit_span(span);
|
||||
visit_thin_attrs(attrs, vis);
|
||||
visit_attrs(attrs, vis);
|
||||
visit_lazy_tts(tokens, vis);
|
||||
}
|
||||
|
||||
|
@ -640,7 +634,7 @@ pub fn noop_visit_meta_item<T: MutVisitor>(mi: &mut MetaItem, vis: &mut T) {
|
|||
pub fn noop_flat_map_param<T: MutVisitor>(mut param: Param, vis: &mut T) -> SmallVec<[Param; 1]> {
|
||||
let Param { attrs, id, pat, span, ty, is_placeholder: _ } = &mut param;
|
||||
vis.visit_id(id);
|
||||
visit_thin_attrs(attrs, vis);
|
||||
visit_attrs(attrs, vis);
|
||||
vis.visit_pat(pat);
|
||||
vis.visit_span(span);
|
||||
vis.visit_ty(ty);
|
||||
|
@ -882,7 +876,7 @@ pub fn noop_flat_map_generic_param<T: MutVisitor>(
|
|||
if let Some(ref mut colon_span) = colon_span {
|
||||
vis.visit_span(colon_span);
|
||||
}
|
||||
visit_thin_attrs(attrs, vis);
|
||||
visit_attrs(attrs, vis);
|
||||
visit_vec(bounds, |bound| noop_visit_param_bound(bound, vis));
|
||||
match kind {
|
||||
GenericParamKind::Lifetime => {}
|
||||
|
@ -978,7 +972,7 @@ pub fn noop_flat_map_field_def<T: MutVisitor>(
|
|||
visitor.visit_vis(vis);
|
||||
visitor.visit_id(id);
|
||||
visitor.visit_ty(ty);
|
||||
visit_thin_attrs(attrs, visitor);
|
||||
visit_attrs(attrs, visitor);
|
||||
smallvec![fd]
|
||||
}
|
||||
|
||||
|
@ -991,7 +985,7 @@ pub fn noop_flat_map_expr_field<T: MutVisitor>(
|
|||
vis.visit_expr(expr);
|
||||
vis.visit_id(id);
|
||||
vis.visit_span(span);
|
||||
visit_thin_attrs(attrs, vis);
|
||||
visit_attrs(attrs, vis);
|
||||
smallvec![f]
|
||||
}
|
||||
|
||||
|
@ -1432,7 +1426,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
|
|||
}
|
||||
vis.visit_id(id);
|
||||
vis.visit_span(span);
|
||||
visit_thin_attrs(attrs, vis);
|
||||
visit_attrs(attrs, vis);
|
||||
visit_lazy_tts(tokens, vis);
|
||||
}
|
||||
|
||||
|
@ -1478,7 +1472,7 @@ pub fn noop_flat_map_stmt_kind<T: MutVisitor>(
|
|||
StmtKind::MacCall(mut mac) => {
|
||||
let MacCallStmt { mac: mac_, style: _, attrs, tokens } = mac.deref_mut();
|
||||
vis.visit_mac_call(mac_);
|
||||
visit_thin_attrs(attrs, vis);
|
||||
visit_attrs(attrs, vis);
|
||||
visit_lazy_tts(tokens, vis);
|
||||
smallvec![StmtKind::MacCall(mac)]
|
||||
}
|
||||
|
@ -1513,12 +1507,6 @@ impl<T: DummyAstNode + 'static> DummyAstNode for P<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> DummyAstNode for ThinVec<T> {
|
||||
fn dummy() -> Self {
|
||||
Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
impl DummyAstNode for Item {
|
||||
fn dummy() -> Self {
|
||||
Item {
|
||||
|
|
|
@ -436,6 +436,30 @@ impl Token {
|
|||
|| self == &OpenDelim(Delimiter::Parenthesis)
|
||||
}
|
||||
|
||||
/// Returns `true` if the token can appear at the start of an item.
|
||||
pub fn can_begin_item(&self) -> bool {
|
||||
match self.kind {
|
||||
Ident(name, _) => [
|
||||
kw::Fn,
|
||||
kw::Use,
|
||||
kw::Struct,
|
||||
kw::Enum,
|
||||
kw::Pub,
|
||||
kw::Trait,
|
||||
kw::Extern,
|
||||
kw::Impl,
|
||||
kw::Unsafe,
|
||||
kw::Static,
|
||||
kw::Union,
|
||||
kw::Macro,
|
||||
kw::Mod,
|
||||
kw::Type,
|
||||
]
|
||||
.contains(&name),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the token is any literal.
|
||||
pub fn is_lit(&self) -> bool {
|
||||
matches!(self.kind, Literal(..))
|
||||
|
|
|
@ -146,7 +146,7 @@ impl LitKind {
|
|||
|
||||
LitKind::ByteStr(bytes.into())
|
||||
}
|
||||
token::Err => LitKind::Err(symbol),
|
||||
token::Err => LitKind::Err,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -199,7 +199,9 @@ impl LitKind {
|
|||
let symbol = if value { kw::True } else { kw::False };
|
||||
(token::Bool, symbol, None)
|
||||
}
|
||||
LitKind::Err(symbol) => (token::Err, symbol, None),
|
||||
// This only shows up in places like `-Zunpretty=hir` output, so we
|
||||
// don't bother to produce something useful.
|
||||
LitKind::Err => (token::Err, Symbol::intern("<bad-literal>"), None),
|
||||
};
|
||||
|
||||
token::Lit::new(kind, symbol, suffix)
|
||||
|
|
|
@ -15,6 +15,7 @@ rustc_target = { path = "../rustc_target" }
|
|||
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||
rustc_index = { path = "../rustc_index" }
|
||||
rustc_middle = { path = "../rustc_middle" }
|
||||
rustc_macros = { path = "../rustc_macros" }
|
||||
rustc_query_system = { path = "../rustc_query_system" }
|
||||
rustc_span = { path = "../rustc_span" }
|
||||
rustc_errors = { path = "../rustc_errors" }
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
use crate::{ImplTraitContext, ImplTraitPosition, ParamMode, ResolverAstLoweringExt};
|
||||
|
||||
use super::errors::{
|
||||
AbiSpecifiedMultipleTimes, AttSyntaxOnlyX86, ClobberAbiNotSupported,
|
||||
InlineAsmUnsupportedTarget, InvalidAbiClobberAbi, InvalidAsmTemplateModifierConst,
|
||||
InvalidAsmTemplateModifierRegClass, InvalidAsmTemplateModifierRegClassSub,
|
||||
InvalidAsmTemplateModifierSym, InvalidRegister, InvalidRegisterClass, RegisterClassOnlyClobber,
|
||||
RegisterConflict,
|
||||
};
|
||||
use super::LoweringContext;
|
||||
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::*;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_errors::struct_span_err;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::definitions::DefPathData;
|
||||
|
@ -26,13 +32,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
let asm_arch =
|
||||
if self.tcx.sess.opts.actually_rustdoc { None } else { self.tcx.sess.asm_arch };
|
||||
if asm_arch.is_none() && !self.tcx.sess.opts.actually_rustdoc {
|
||||
struct_span_err!(
|
||||
self.tcx.sess,
|
||||
sp,
|
||||
E0472,
|
||||
"inline assembly is unsupported on this target"
|
||||
)
|
||||
.emit();
|
||||
self.tcx.sess.emit_err(InlineAsmUnsupportedTarget { span: sp });
|
||||
}
|
||||
if let Some(asm_arch) = asm_arch {
|
||||
// Inline assembly is currently only stable for these architectures.
|
||||
|
@ -59,10 +59,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
&& !matches!(asm_arch, Some(asm::InlineAsmArch::X86 | asm::InlineAsmArch::X86_64))
|
||||
&& !self.tcx.sess.opts.actually_rustdoc
|
||||
{
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_err(sp, "the `att_syntax` option is only supported on x86")
|
||||
.emit();
|
||||
self.tcx.sess.emit_err(AttSyntaxOnlyX86 { span: sp });
|
||||
}
|
||||
if asm.options.contains(InlineAsmOptions::MAY_UNWIND) && !self.tcx.features().asm_unwind {
|
||||
feature_err(
|
||||
|
@ -82,51 +79,37 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
// If the abi was already in the list, emit an error
|
||||
match clobber_abis.get(&abi) {
|
||||
Some((prev_name, prev_sp)) => {
|
||||
let mut err = self.tcx.sess.struct_span_err(
|
||||
*abi_span,
|
||||
&format!("`{}` ABI specified multiple times", prev_name),
|
||||
);
|
||||
err.span_label(*prev_sp, "previously specified here");
|
||||
|
||||
// Multiple different abi names may actually be the same ABI
|
||||
// If the specified ABIs are not the same name, alert the user that they resolve to the same ABI
|
||||
let source_map = self.tcx.sess.source_map();
|
||||
if source_map.span_to_snippet(*prev_sp)
|
||||
!= source_map.span_to_snippet(*abi_span)
|
||||
{
|
||||
err.note("these ABIs are equivalent on the current target");
|
||||
}
|
||||
let equivalent = (source_map.span_to_snippet(*prev_sp)
|
||||
!= source_map.span_to_snippet(*abi_span))
|
||||
.then_some(());
|
||||
|
||||
err.emit();
|
||||
self.tcx.sess.emit_err(AbiSpecifiedMultipleTimes {
|
||||
abi_span: *abi_span,
|
||||
prev_name: *prev_name,
|
||||
prev_span: *prev_sp,
|
||||
equivalent,
|
||||
});
|
||||
}
|
||||
None => {
|
||||
clobber_abis.insert(abi, (abi_name, *abi_span));
|
||||
clobber_abis.insert(abi, (*abi_name, *abi_span));
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(&[]) => {
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_err(
|
||||
*abi_span,
|
||||
"`clobber_abi` is not supported on this target",
|
||||
)
|
||||
.emit();
|
||||
self.tcx.sess.emit_err(ClobberAbiNotSupported { abi_span: *abi_span });
|
||||
}
|
||||
Err(supported_abis) => {
|
||||
let mut err = self
|
||||
.tcx
|
||||
.sess
|
||||
.struct_span_err(*abi_span, "invalid ABI for `clobber_abi`");
|
||||
let mut abis = format!("`{}`", supported_abis[0]);
|
||||
for m in &supported_abis[1..] {
|
||||
let _ = write!(abis, ", `{}`", m);
|
||||
}
|
||||
err.note(&format!(
|
||||
"the following ABIs are supported on this target: {}",
|
||||
abis
|
||||
));
|
||||
err.emit();
|
||||
self.tcx.sess.emit_err(InvalidAbiClobberAbi {
|
||||
abi_span: *abi_span,
|
||||
supported_abis: abis,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -141,24 +124,28 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
.iter()
|
||||
.map(|(op, op_sp)| {
|
||||
let lower_reg = |reg| match reg {
|
||||
InlineAsmRegOrRegClass::Reg(s) => {
|
||||
InlineAsmRegOrRegClass::Reg(reg) => {
|
||||
asm::InlineAsmRegOrRegClass::Reg(if let Some(asm_arch) = asm_arch {
|
||||
asm::InlineAsmReg::parse(asm_arch, s).unwrap_or_else(|e| {
|
||||
let msg = format!("invalid register `{}`: {}", s, e);
|
||||
sess.struct_span_err(*op_sp, &msg).emit();
|
||||
asm::InlineAsmReg::parse(asm_arch, reg).unwrap_or_else(|error| {
|
||||
sess.emit_err(InvalidRegister { op_span: *op_sp, reg, error });
|
||||
asm::InlineAsmReg::Err
|
||||
})
|
||||
} else {
|
||||
asm::InlineAsmReg::Err
|
||||
})
|
||||
}
|
||||
InlineAsmRegOrRegClass::RegClass(s) => {
|
||||
InlineAsmRegOrRegClass::RegClass(reg_class) => {
|
||||
asm::InlineAsmRegOrRegClass::RegClass(if let Some(asm_arch) = asm_arch {
|
||||
asm::InlineAsmRegClass::parse(asm_arch, s).unwrap_or_else(|e| {
|
||||
let msg = format!("invalid register class `{}`: {}", s, e);
|
||||
sess.struct_span_err(*op_sp, &msg).emit();
|
||||
asm::InlineAsmRegClass::parse(asm_arch, reg_class).unwrap_or_else(
|
||||
|error| {
|
||||
sess.emit_err(InvalidRegisterClass {
|
||||
op_span: *op_sp,
|
||||
reg_class,
|
||||
error,
|
||||
});
|
||||
asm::InlineAsmRegClass::Err
|
||||
})
|
||||
},
|
||||
)
|
||||
} else {
|
||||
asm::InlineAsmRegClass::Err
|
||||
})
|
||||
|
@ -282,50 +269,39 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
}
|
||||
let valid_modifiers = class.valid_modifiers(asm_arch.unwrap());
|
||||
if !valid_modifiers.contains(&modifier) {
|
||||
let mut err = sess.struct_span_err(
|
||||
placeholder_span,
|
||||
"invalid asm template modifier for this register class",
|
||||
);
|
||||
err.span_label(placeholder_span, "template modifier");
|
||||
err.span_label(op_sp, "argument");
|
||||
if !valid_modifiers.is_empty() {
|
||||
let sub = if !valid_modifiers.is_empty() {
|
||||
let mut mods = format!("`{}`", valid_modifiers[0]);
|
||||
for m in &valid_modifiers[1..] {
|
||||
let _ = write!(mods, ", `{}`", m);
|
||||
}
|
||||
err.note(&format!(
|
||||
"the `{}` register class supports \
|
||||
the following template modifiers: {}",
|
||||
class.name(),
|
||||
mods
|
||||
));
|
||||
} else {
|
||||
err.note(&format!(
|
||||
"the `{}` register class does not support template modifiers",
|
||||
class.name()
|
||||
));
|
||||
InvalidAsmTemplateModifierRegClassSub::SupportModifier {
|
||||
class_name: class.name(),
|
||||
modifiers: mods,
|
||||
}
|
||||
err.emit();
|
||||
} else {
|
||||
InvalidAsmTemplateModifierRegClassSub::DoesNotSupportModifier {
|
||||
class_name: class.name(),
|
||||
}
|
||||
};
|
||||
sess.emit_err(InvalidAsmTemplateModifierRegClass {
|
||||
placeholder_span,
|
||||
op_span: op_sp,
|
||||
sub,
|
||||
});
|
||||
}
|
||||
}
|
||||
hir::InlineAsmOperand::Const { .. } => {
|
||||
let mut err = sess.struct_span_err(
|
||||
sess.emit_err(InvalidAsmTemplateModifierConst {
|
||||
placeholder_span,
|
||||
"asm template modifiers are not allowed for `const` arguments",
|
||||
);
|
||||
err.span_label(placeholder_span, "template modifier");
|
||||
err.span_label(op_sp, "argument");
|
||||
err.emit();
|
||||
op_span: op_sp,
|
||||
});
|
||||
}
|
||||
hir::InlineAsmOperand::SymFn { .. }
|
||||
| hir::InlineAsmOperand::SymStatic { .. } => {
|
||||
let mut err = sess.struct_span_err(
|
||||
sess.emit_err(InvalidAsmTemplateModifierSym {
|
||||
placeholder_span,
|
||||
"asm template modifiers are not allowed for `sym` arguments",
|
||||
);
|
||||
err.span_label(placeholder_span, "template modifier");
|
||||
err.span_label(op_sp, "argument");
|
||||
err.emit();
|
||||
op_span: op_sp,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -346,12 +322,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
// require that the operand name an explicit register, not a
|
||||
// register class.
|
||||
if reg_class.is_clobber_only(asm_arch.unwrap()) && !op.is_clobber() {
|
||||
let msg = format!(
|
||||
"register class `{}` can only be used as a clobber, \
|
||||
not as an input or output",
|
||||
reg_class.name()
|
||||
);
|
||||
sess.struct_span_err(op_sp, &msg).emit();
|
||||
sess.emit_err(RegisterClassOnlyClobber {
|
||||
op_span: op_sp,
|
||||
reg_class_name: reg_class.name(),
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -391,16 +365,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
unreachable!();
|
||||
};
|
||||
|
||||
let msg = format!(
|
||||
"register `{}` conflicts with register `{}`",
|
||||
reg.name(),
|
||||
reg2.name()
|
||||
);
|
||||
let mut err = sess.struct_span_err(op_sp, &msg);
|
||||
err.span_label(op_sp, &format!("register `{}`", reg.name()));
|
||||
err.span_label(op_sp2, &format!("register `{}`", reg2.name()));
|
||||
|
||||
match (op, op2) {
|
||||
let in_out = match (op, op2) {
|
||||
(
|
||||
hir::InlineAsmOperand::In { .. },
|
||||
hir::InlineAsmOperand::Out { late, .. },
|
||||
|
@ -411,14 +376,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
) => {
|
||||
assert!(!*late);
|
||||
let out_op_sp = if input { op_sp2 } else { op_sp };
|
||||
let msg = "use `lateout` instead of \
|
||||
`out` to avoid conflict";
|
||||
err.span_help(out_op_sp, msg);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
Some(out_op_sp)
|
||||
},
|
||||
_ => None,
|
||||
};
|
||||
|
||||
err.emit();
|
||||
sess.emit_err(RegisterConflict {
|
||||
op_span1: op_sp,
|
||||
op_span2: op_sp2,
|
||||
reg1_name: reg.name(),
|
||||
reg2_name: reg2.name(),
|
||||
in_out
|
||||
});
|
||||
}
|
||||
Entry::Vacant(v) => {
|
||||
if r == reg {
|
||||
|
|
336
compiler/rustc_ast_lowering/src/errors.rs
Normal file
336
compiler/rustc_ast_lowering/src/errors.rs
Normal file
|
@ -0,0 +1,336 @@
|
|||
use rustc_errors::{fluent, AddSubdiagnostic, Applicability, Diagnostic, DiagnosticArgFromDisplay};
|
||||
use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic};
|
||||
use rustc_span::{symbol::Ident, Span, Symbol};
|
||||
|
||||
#[derive(SessionDiagnostic, Clone, Copy)]
|
||||
#[diag(ast_lowering::generic_type_with_parentheses, code = "E0214")]
|
||||
pub struct GenericTypeWithParentheses {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
#[subdiagnostic]
|
||||
pub sub: Option<UseAngleBrackets>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct UseAngleBrackets {
|
||||
pub open_param: Span,
|
||||
pub close_param: Span,
|
||||
}
|
||||
|
||||
impl AddSubdiagnostic for UseAngleBrackets {
|
||||
fn add_to_diagnostic(self, diag: &mut Diagnostic) {
|
||||
diag.multipart_suggestion(
|
||||
fluent::ast_lowering::use_angle_brackets,
|
||||
vec![(self.open_param, String::from("<")), (self.close_param, String::from(">"))],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[help]
|
||||
#[diag(ast_lowering::invalid_abi, code = "E0703")]
|
||||
pub struct InvalidAbi {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
pub abi: Symbol,
|
||||
pub valid_abis: String,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic, Clone, Copy)]
|
||||
#[diag(ast_lowering::assoc_ty_parentheses)]
|
||||
pub struct AssocTyParentheses {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[subdiagnostic]
|
||||
pub sub: AssocTyParenthesesSub,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum AssocTyParenthesesSub {
|
||||
Empty { parentheses_span: Span },
|
||||
NotEmpty { open_param: Span, close_param: Span },
|
||||
}
|
||||
|
||||
impl AddSubdiagnostic for AssocTyParenthesesSub {
|
||||
fn add_to_diagnostic(self, diag: &mut Diagnostic) {
|
||||
match self {
|
||||
Self::Empty { parentheses_span } => diag.multipart_suggestion(
|
||||
fluent::ast_lowering::remove_parentheses,
|
||||
vec![(parentheses_span, String::new())],
|
||||
Applicability::MaybeIncorrect,
|
||||
),
|
||||
Self::NotEmpty { open_param, close_param } => diag.multipart_suggestion(
|
||||
fluent::ast_lowering::use_angle_brackets,
|
||||
vec![(open_param, String::from("<")), (close_param, String::from(">"))],
|
||||
Applicability::MaybeIncorrect,
|
||||
),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(ast_lowering::misplaced_impl_trait, code = "E0562")]
|
||||
pub struct MisplacedImplTrait<'a> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub position: DiagnosticArgFromDisplay<'a>,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic, Clone, Copy)]
|
||||
#[diag(ast_lowering::rustc_box_attribute_error)]
|
||||
pub struct RustcBoxAttributeError {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic, Clone, Copy)]
|
||||
#[diag(ast_lowering::underscore_expr_lhs_assign)]
|
||||
pub struct UnderscoreExprLhsAssign {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic, Clone, Copy)]
|
||||
#[diag(ast_lowering::base_expression_double_dot)]
|
||||
pub struct BaseExpressionDoubleDot {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic, Clone, Copy)]
|
||||
#[diag(ast_lowering::await_only_in_async_fn_and_blocks, code = "E0728")]
|
||||
pub struct AwaitOnlyInAsyncFnAndBlocks {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub dot_await_span: Span,
|
||||
#[label(ast_lowering::this_not_async)]
|
||||
pub item_span: Option<Span>,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic, Clone, Copy)]
|
||||
#[diag(ast_lowering::generator_too_many_parameters, code = "E0628")]
|
||||
pub struct GeneratorTooManyParameters {
|
||||
#[primary_span]
|
||||
pub fn_decl_span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic, Clone, Copy)]
|
||||
#[diag(ast_lowering::closure_cannot_be_static, code = "E0697")]
|
||||
pub struct ClosureCannotBeStatic {
|
||||
#[primary_span]
|
||||
pub fn_decl_span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic, Clone, Copy)]
|
||||
#[help]
|
||||
#[diag(ast_lowering::async_non_move_closure_not_supported, code = "E0708")]
|
||||
pub struct AsyncNonMoveClosureNotSupported {
|
||||
#[primary_span]
|
||||
pub fn_decl_span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic, Clone, Copy)]
|
||||
#[diag(ast_lowering::functional_record_update_destructuring_assignment)]
|
||||
pub struct FunctionalRecordUpdateDestructuringAssignemnt {
|
||||
#[primary_span]
|
||||
#[suggestion(code = "", applicability = "machine-applicable")]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic, Clone, Copy)]
|
||||
#[diag(ast_lowering::async_generators_not_supported, code = "E0727")]
|
||||
pub struct AsyncGeneratorsNotSupported {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic, Clone, Copy)]
|
||||
#[diag(ast_lowering::inline_asm_unsupported_target, code = "E0472")]
|
||||
pub struct InlineAsmUnsupportedTarget {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic, Clone, Copy)]
|
||||
#[diag(ast_lowering::att_syntax_only_x86)]
|
||||
pub struct AttSyntaxOnlyX86 {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic, Clone, Copy)]
|
||||
#[diag(ast_lowering::abi_specified_multiple_times)]
|
||||
pub struct AbiSpecifiedMultipleTimes {
|
||||
#[primary_span]
|
||||
pub abi_span: Span,
|
||||
pub prev_name: Symbol,
|
||||
#[label]
|
||||
pub prev_span: Span,
|
||||
#[note]
|
||||
pub equivalent: Option<()>,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic, Clone, Copy)]
|
||||
#[diag(ast_lowering::clobber_abi_not_supported)]
|
||||
pub struct ClobberAbiNotSupported {
|
||||
#[primary_span]
|
||||
pub abi_span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[note]
|
||||
#[diag(ast_lowering::invalid_abi_clobber_abi)]
|
||||
pub struct InvalidAbiClobberAbi {
|
||||
#[primary_span]
|
||||
pub abi_span: Span,
|
||||
pub supported_abis: String,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic, Clone, Copy)]
|
||||
#[diag(ast_lowering::invalid_register)]
|
||||
pub struct InvalidRegister<'a> {
|
||||
#[primary_span]
|
||||
pub op_span: Span,
|
||||
pub reg: Symbol,
|
||||
pub error: &'a str,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic, Clone, Copy)]
|
||||
#[diag(ast_lowering::invalid_register_class)]
|
||||
pub struct InvalidRegisterClass<'a> {
|
||||
#[primary_span]
|
||||
pub op_span: Span,
|
||||
pub reg_class: Symbol,
|
||||
pub error: &'a str,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(ast_lowering::invalid_asm_template_modifier_reg_class)]
|
||||
pub struct InvalidAsmTemplateModifierRegClass {
|
||||
#[primary_span]
|
||||
#[label(ast_lowering::template_modifier)]
|
||||
pub placeholder_span: Span,
|
||||
#[label(ast_lowering::argument)]
|
||||
pub op_span: Span,
|
||||
#[subdiagnostic]
|
||||
pub sub: InvalidAsmTemplateModifierRegClassSub,
|
||||
}
|
||||
|
||||
#[derive(SessionSubdiagnostic)]
|
||||
pub enum InvalidAsmTemplateModifierRegClassSub {
|
||||
#[note(ast_lowering::support_modifiers)]
|
||||
SupportModifier { class_name: Symbol, modifiers: String },
|
||||
#[note(ast_lowering::does_not_support_modifiers)]
|
||||
DoesNotSupportModifier { class_name: Symbol },
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic, Clone, Copy)]
|
||||
#[diag(ast_lowering::invalid_asm_template_modifier_const)]
|
||||
pub struct InvalidAsmTemplateModifierConst {
|
||||
#[primary_span]
|
||||
#[label(ast_lowering::template_modifier)]
|
||||
pub placeholder_span: Span,
|
||||
#[label(ast_lowering::argument)]
|
||||
pub op_span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic, Clone, Copy)]
|
||||
#[diag(ast_lowering::invalid_asm_template_modifier_sym)]
|
||||
pub struct InvalidAsmTemplateModifierSym {
|
||||
#[primary_span]
|
||||
#[label(ast_lowering::template_modifier)]
|
||||
pub placeholder_span: Span,
|
||||
#[label(ast_lowering::argument)]
|
||||
pub op_span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic, Clone, Copy)]
|
||||
#[diag(ast_lowering::register_class_only_clobber)]
|
||||
pub struct RegisterClassOnlyClobber {
|
||||
#[primary_span]
|
||||
pub op_span: Span,
|
||||
pub reg_class_name: Symbol,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic, Clone, Copy)]
|
||||
#[diag(ast_lowering::register_conflict)]
|
||||
pub struct RegisterConflict<'a> {
|
||||
#[primary_span]
|
||||
#[label(ast_lowering::register1)]
|
||||
pub op_span1: Span,
|
||||
#[label(ast_lowering::register2)]
|
||||
pub op_span2: Span,
|
||||
pub reg1_name: &'a str,
|
||||
pub reg2_name: &'a str,
|
||||
#[help]
|
||||
pub in_out: Option<Span>,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic, Clone, Copy)]
|
||||
#[help]
|
||||
#[diag(ast_lowering::sub_tuple_binding)]
|
||||
pub struct SubTupleBinding<'a> {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
#[suggestion_verbose(
|
||||
ast_lowering::sub_tuple_binding_suggestion,
|
||||
code = "..",
|
||||
applicability = "maybe-incorrect"
|
||||
)]
|
||||
pub span: Span,
|
||||
pub ident: Ident,
|
||||
pub ident_name: Symbol,
|
||||
pub ctx: &'a str,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic, Clone, Copy)]
|
||||
#[diag(ast_lowering::extra_double_dot)]
|
||||
pub struct ExtraDoubleDot<'a> {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
#[label(ast_lowering::previously_used_here)]
|
||||
pub prev_span: Span,
|
||||
pub ctx: &'a str,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic, Clone, Copy)]
|
||||
#[note]
|
||||
#[diag(ast_lowering::misplaced_double_dot)]
|
||||
pub struct MisplacedDoubleDot {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic, Clone, Copy)]
|
||||
#[diag(ast_lowering::misplaced_relax_trait_bound)]
|
||||
pub struct MisplacedRelaxTraitBound {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic, Clone, Copy)]
|
||||
#[diag(ast_lowering::not_supported_for_lifetime_binder_async_closure)]
|
||||
pub struct NotSupportedForLifetimeBinderAsyncClosure {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic, Clone, Copy)]
|
||||
#[diag(ast_lowering::arbitrary_expression_in_pattern)]
|
||||
pub struct ArbitraryExpressionInPattern {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic, Clone, Copy)]
|
||||
#[diag(ast_lowering::inclusive_range_with_no_end)]
|
||||
pub struct InclusiveRangeWithNoEnd {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
|
@ -1,3 +1,9 @@
|
|||
use super::errors::{
|
||||
AsyncGeneratorsNotSupported, AsyncNonMoveClosureNotSupported, AwaitOnlyInAsyncFnAndBlocks,
|
||||
BaseExpressionDoubleDot, ClosureCannotBeStatic, FunctionalRecordUpdateDestructuringAssignemnt,
|
||||
GeneratorTooManyParameters, InclusiveRangeWithNoEnd, NotSupportedForLifetimeBinderAsyncClosure,
|
||||
RustcBoxAttributeError, UnderscoreExprLhsAssign,
|
||||
};
|
||||
use super::ResolverAstLoweringExt;
|
||||
use super::{ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericArgs};
|
||||
use crate::{FnDeclKind, ImplTraitPosition};
|
||||
|
@ -6,8 +12,6 @@ use rustc_ast::attr;
|
|||
use rustc_ast::ptr::P as AstP;
|
||||
use rustc_ast::*;
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_data_structures::thin_vec::ThinVec;
|
||||
use rustc_errors::struct_span_err;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::definitions::DefPathData;
|
||||
|
@ -46,13 +50,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
let hir_id = self.lower_node_id(e.id);
|
||||
return hir::Expr { hir_id, kind, span: self.lower_span(e.span) };
|
||||
} else {
|
||||
self.tcx.sess
|
||||
.struct_span_err(
|
||||
e.span,
|
||||
"#[rustc_box] requires precisely one argument \
|
||||
and no other attributes are allowed",
|
||||
)
|
||||
.emit();
|
||||
self.tcx.sess.emit_err(RustcBoxAttributeError { span: e.span });
|
||||
hir::ExprKind::Err
|
||||
}
|
||||
} else if let Some(legacy_args) = self.resolver.legacy_const_generic_args(f) {
|
||||
|
@ -212,13 +210,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
self.lower_expr_range(e.span, e1.as_deref(), e2.as_deref(), lims)
|
||||
}
|
||||
ExprKind::Underscore => {
|
||||
self.tcx
|
||||
.sess.struct_span_err(
|
||||
e.span,
|
||||
"in expressions, `_` can only be used on the left-hand side of an assignment",
|
||||
)
|
||||
.span_label(e.span, "`_` not allowed here")
|
||||
.emit();
|
||||
self.tcx.sess.emit_err(UnderscoreExprLhsAssign { span: e.span });
|
||||
hir::ExprKind::Err
|
||||
}
|
||||
ExprKind::Path(ref qself, ref path) => {
|
||||
|
@ -250,11 +242,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
let rest = match &se.rest {
|
||||
StructRest::Base(e) => Some(self.lower_expr(e)),
|
||||
StructRest::Rest(sp) => {
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_err(*sp, "base expression required after `..`")
|
||||
.span_label(*sp, "add a base expression here")
|
||||
.emit();
|
||||
self.tcx.sess.emit_err(BaseExpressionDoubleDot { span: *sp });
|
||||
Some(&*self.arena.alloc(self.expr_err(*sp)))
|
||||
}
|
||||
StructRest::None => None,
|
||||
|
@ -448,12 +436,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
let lowered_cond = self.with_loop_condition_scope(|t| t.lower_expr(cond));
|
||||
let new_cond = self.manage_let_cond(lowered_cond);
|
||||
let then = self.lower_block_expr(body);
|
||||
let expr_break = self.expr_break(span, ThinVec::new());
|
||||
let expr_break = self.expr_break(span, AttrVec::new());
|
||||
let stmt_break = self.stmt_expr(span, expr_break);
|
||||
let else_blk = self.block_all(span, arena_vec![self; stmt_break], None);
|
||||
let else_expr = self.arena.alloc(self.expr_block(else_blk, ThinVec::new()));
|
||||
let else_expr = self.arena.alloc(self.expr_block(else_blk, AttrVec::new()));
|
||||
let if_kind = hir::ExprKind::If(new_cond, self.arena.alloc(then), Some(else_expr));
|
||||
let if_expr = self.expr(span, if_kind, ThinVec::new());
|
||||
let if_expr = self.expr(span, if_kind, AttrVec::new());
|
||||
let block = self.block_expr(self.arena.alloc(if_expr));
|
||||
let span = self.lower_span(span.with_hi(cond.span.hi()));
|
||||
let opt_label = self.lower_label(opt_label);
|
||||
|
@ -512,7 +500,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
let constructor = self.arena.alloc(self.expr_lang_item_path(
|
||||
method_span,
|
||||
lang_item,
|
||||
ThinVec::new(),
|
||||
AttrVec::new(),
|
||||
None,
|
||||
));
|
||||
self.expr_call(overall_span, constructor, std::slice::from_ref(expr))
|
||||
|
@ -635,7 +623,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
let gen_future = self.expr_lang_item_path(
|
||||
unstable_span,
|
||||
hir::LangItem::FromGenerator,
|
||||
ThinVec::new(),
|
||||
AttrVec::new(),
|
||||
None,
|
||||
);
|
||||
|
||||
|
@ -663,17 +651,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
match self.generator_kind {
|
||||
Some(hir::GeneratorKind::Async(_)) => {}
|
||||
Some(hir::GeneratorKind::Gen) | None => {
|
||||
let mut err = struct_span_err!(
|
||||
self.tcx.sess,
|
||||
self.tcx.sess.emit_err(AwaitOnlyInAsyncFnAndBlocks {
|
||||
dot_await_span,
|
||||
E0728,
|
||||
"`await` is only allowed inside `async` functions and blocks"
|
||||
);
|
||||
err.span_label(dot_await_span, "only allowed inside `async` functions and blocks");
|
||||
if let Some(item_sp) = self.current_item {
|
||||
err.span_label(item_sp, "this is not `async`");
|
||||
}
|
||||
err.emit();
|
||||
item_span: self.current_item,
|
||||
});
|
||||
}
|
||||
}
|
||||
let span = self.mark_span_with_reason(DesugaringKind::Await, dot_await_span, None);
|
||||
|
@ -747,7 +728,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
let break_x = self.with_loop_scope(loop_node_id, move |this| {
|
||||
let expr_break =
|
||||
hir::ExprKind::Break(this.lower_loop_destination(None), Some(x_expr));
|
||||
this.arena.alloc(this.expr(gen_future_span, expr_break, ThinVec::new()))
|
||||
this.arena.alloc(this.expr(gen_future_span, expr_break, AttrVec::new()))
|
||||
});
|
||||
self.arm(ready_pat, break_x)
|
||||
};
|
||||
|
@ -780,7 +761,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
let yield_expr = self.expr(
|
||||
span,
|
||||
hir::ExprKind::Yield(unit, hir::YieldSource::Await { expr: Some(expr_hir_id) }),
|
||||
ThinVec::new(),
|
||||
AttrVec::new(),
|
||||
);
|
||||
let yield_expr = self.arena.alloc(yield_expr);
|
||||
|
||||
|
@ -893,13 +874,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
match generator_kind {
|
||||
Some(hir::GeneratorKind::Gen) => {
|
||||
if decl.inputs.len() > 1 {
|
||||
struct_span_err!(
|
||||
self.tcx.sess,
|
||||
fn_decl_span,
|
||||
E0628,
|
||||
"too many parameters for a generator (expected 0 or 1 parameters)"
|
||||
)
|
||||
.emit();
|
||||
self.tcx.sess.emit_err(GeneratorTooManyParameters { fn_decl_span });
|
||||
}
|
||||
Some(movability)
|
||||
}
|
||||
|
@ -908,13 +883,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
}
|
||||
None => {
|
||||
if movability == Movability::Static {
|
||||
struct_span_err!(
|
||||
self.tcx.sess,
|
||||
fn_decl_span,
|
||||
E0697,
|
||||
"closures cannot be static"
|
||||
)
|
||||
.emit();
|
||||
self.tcx.sess.emit_err(ClosureCannotBeStatic { fn_decl_span });
|
||||
}
|
||||
None
|
||||
}
|
||||
|
@ -947,10 +916,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
fn_decl_span: Span,
|
||||
) -> hir::ExprKind<'hir> {
|
||||
if let &ClosureBinder::For { span, .. } = binder {
|
||||
self.tcx.sess.span_err(
|
||||
span,
|
||||
"`for<...>` binders on `async` closures are not currently supported",
|
||||
);
|
||||
self.tcx.sess.emit_err(NotSupportedForLifetimeBinderAsyncClosure { span });
|
||||
}
|
||||
|
||||
let (binder_clause, generic_params) = self.lower_closure_binder(binder);
|
||||
|
@ -961,17 +927,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
let body = self.with_new_scopes(|this| {
|
||||
// FIXME(cramertj): allow `async` non-`move` closures with arguments.
|
||||
if capture_clause == CaptureBy::Ref && !decl.inputs.is_empty() {
|
||||
struct_span_err!(
|
||||
this.tcx.sess,
|
||||
fn_decl_span,
|
||||
E0708,
|
||||
"`async` non-`move` closures with parameters are not currently supported",
|
||||
)
|
||||
.help(
|
||||
"consider using `let` statements to manually capture \
|
||||
variables by reference before entering an `async move` closure",
|
||||
)
|
||||
.emit();
|
||||
this.tcx.sess.emit_err(AsyncNonMoveClosureNotSupported { fn_decl_span });
|
||||
}
|
||||
|
||||
// Transform `async |x: u8| -> X { ... }` into
|
||||
|
@ -987,7 +943,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
hir::AsyncGeneratorKind::Closure,
|
||||
|this| this.with_new_scopes(|this| this.lower_expr_mut(body)),
|
||||
);
|
||||
this.expr(fn_decl_span, async_body, ThinVec::new())
|
||||
this.expr(fn_decl_span, async_body, AttrVec::new())
|
||||
});
|
||||
body_id
|
||||
});
|
||||
|
@ -1211,20 +1167,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
);
|
||||
let fields_omitted = match &se.rest {
|
||||
StructRest::Base(e) => {
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_err(
|
||||
e.span,
|
||||
"functional record updates are not allowed in destructuring \
|
||||
assignments",
|
||||
)
|
||||
.span_suggestion(
|
||||
e.span,
|
||||
"consider removing the trailing pattern",
|
||||
"",
|
||||
rustc_errors::Applicability::MachineApplicable,
|
||||
)
|
||||
.emit();
|
||||
self.tcx.sess.emit_err(FunctionalRecordUpdateDestructuringAssignemnt {
|
||||
span: e.span,
|
||||
});
|
||||
true
|
||||
}
|
||||
StructRest::Rest(_) => true,
|
||||
|
@ -1257,7 +1202,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
let ident = self.expr_ident(lhs.span, ident, binding);
|
||||
let assign =
|
||||
hir::ExprKind::Assign(self.lower_expr(lhs), ident, self.lower_span(eq_sign_span));
|
||||
let expr = self.expr(lhs.span, assign, ThinVec::new());
|
||||
let expr = self.expr(lhs.span, assign, AttrVec::new());
|
||||
assignments.push(self.stmt_expr(lhs.span, expr));
|
||||
pat
|
||||
}
|
||||
|
@ -1299,7 +1244,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
let fn_path =
|
||||
hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, self.lower_span(span), None);
|
||||
let fn_expr =
|
||||
self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path), ThinVec::new()));
|
||||
self.arena.alloc(self.expr(span, hir::ExprKind::Path(fn_path), AttrVec::new()));
|
||||
hir::ExprKind::Call(fn_expr, arena_vec![self; e1, e2])
|
||||
}
|
||||
|
||||
|
@ -1319,7 +1264,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
(Some(..), Some(..), HalfOpen) => hir::LangItem::Range,
|
||||
(None, Some(..), Closed) => hir::LangItem::RangeToInclusive,
|
||||
(Some(..), Some(..), Closed) => unreachable!(),
|
||||
(_, None, Closed) => self.diagnostic().span_fatal(span, "inclusive range with no end"),
|
||||
(start, None, Closed) => {
|
||||
self.tcx.sess.emit_err(InclusiveRangeWithNoEnd { span });
|
||||
match start {
|
||||
Some(..) => hir::LangItem::RangeFrom,
|
||||
None => hir::LangItem::RangeFull,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let fields = self.arena.alloc_from_iter(
|
||||
|
@ -1421,13 +1372,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
match self.generator_kind {
|
||||
Some(hir::GeneratorKind::Gen) => {}
|
||||
Some(hir::GeneratorKind::Async(_)) => {
|
||||
struct_span_err!(
|
||||
self.tcx.sess,
|
||||
span,
|
||||
E0727,
|
||||
"`async` generators are not yet supported"
|
||||
)
|
||||
.emit();
|
||||
self.tcx.sess.emit_err(AsyncGeneratorsNotSupported { span });
|
||||
}
|
||||
None => self.generator_kind = Some(hir::GeneratorKind::Gen),
|
||||
}
|
||||
|
@ -1472,7 +1417,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
// `None => break`
|
||||
let none_arm = {
|
||||
let break_expr =
|
||||
self.with_loop_scope(e.id, |this| this.expr_break_alloc(for_span, ThinVec::new()));
|
||||
self.with_loop_scope(e.id, |this| this.expr_break_alloc(for_span, AttrVec::new()));
|
||||
let pat = self.pat_none(for_span);
|
||||
self.arm(pat, break_expr)
|
||||
};
|
||||
|
@ -1481,7 +1426,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
let some_arm = {
|
||||
let some_pat = self.pat_some(pat_span, pat);
|
||||
let body_block = self.with_loop_scope(e.id, |this| this.lower_block(body, false));
|
||||
let body_expr = self.arena.alloc(self.expr_block(body_block, ThinVec::new()));
|
||||
let body_expr = self.arena.alloc(self.expr_block(body_block, AttrVec::new()));
|
||||
self.arm(some_pat, body_expr)
|
||||
};
|
||||
|
||||
|
@ -1596,7 +1541,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
};
|
||||
attr::mk_attr_outer(allow)
|
||||
};
|
||||
let attrs = vec![attr];
|
||||
let attrs: AttrVec = vec![attr].into();
|
||||
|
||||
// `ControlFlow::Continue(val) => #[allow(unreachable_code)] val,`
|
||||
let continue_arm = {
|
||||
|
@ -1606,7 +1551,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
span,
|
||||
val_ident,
|
||||
val_pat_nid,
|
||||
ThinVec::from(attrs.clone()),
|
||||
attrs.clone(),
|
||||
));
|
||||
let continue_pat = self.pat_cf_continue(unstable_span, val_pat);
|
||||
self.arm(continue_pat, val_expr)
|
||||
|
@ -1625,7 +1570,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
self.arena.alloc(residual_expr),
|
||||
unstable_span,
|
||||
);
|
||||
let thin_attrs = ThinVec::from(attrs);
|
||||
let ret_expr = if let Some(catch_node) = self.catch_scope {
|
||||
let target_id = Ok(self.lower_node_id(catch_node));
|
||||
self.arena.alloc(self.expr(
|
||||
|
@ -1634,13 +1578,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
hir::Destination { label: None, target_id },
|
||||
Some(from_residual_expr),
|
||||
),
|
||||
thin_attrs,
|
||||
attrs,
|
||||
))
|
||||
} else {
|
||||
self.arena.alloc(self.expr(
|
||||
try_span,
|
||||
hir::ExprKind::Ret(Some(from_residual_expr)),
|
||||
thin_attrs,
|
||||
attrs,
|
||||
))
|
||||
};
|
||||
|
||||
|
@ -1728,7 +1672,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
arms: &'hir [hir::Arm<'hir>],
|
||||
source: hir::MatchSource,
|
||||
) -> hir::Expr<'hir> {
|
||||
self.expr(span, hir::ExprKind::Match(arg, arms, source), ThinVec::new())
|
||||
self.expr(span, hir::ExprKind::Match(arg, arms, source), AttrVec::new())
|
||||
}
|
||||
|
||||
fn expr_break(&mut self, span: Span, attrs: AttrVec) -> hir::Expr<'hir> {
|
||||
|
@ -1745,12 +1689,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
self.expr(
|
||||
span,
|
||||
hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Mut, e),
|
||||
ThinVec::new(),
|
||||
AttrVec::new(),
|
||||
)
|
||||
}
|
||||
|
||||
fn expr_unit(&mut self, sp: Span) -> &'hir hir::Expr<'hir> {
|
||||
self.arena.alloc(self.expr(sp, hir::ExprKind::Tup(&[]), ThinVec::new()))
|
||||
self.arena.alloc(self.expr(sp, hir::ExprKind::Tup(&[]), AttrVec::new()))
|
||||
}
|
||||
|
||||
fn expr_call_mut(
|
||||
|
@ -1759,7 +1703,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
e: &'hir hir::Expr<'hir>,
|
||||
args: &'hir [hir::Expr<'hir>],
|
||||
) -> hir::Expr<'hir> {
|
||||
self.expr(span, hir::ExprKind::Call(e, args), ThinVec::new())
|
||||
self.expr(span, hir::ExprKind::Call(e, args), AttrVec::new())
|
||||
}
|
||||
|
||||
fn expr_call(
|
||||
|
@ -1779,7 +1723,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
hir_id: Option<hir::HirId>,
|
||||
) -> hir::Expr<'hir> {
|
||||
let path =
|
||||
self.arena.alloc(self.expr_lang_item_path(span, lang_item, ThinVec::new(), hir_id));
|
||||
self.arena.alloc(self.expr_lang_item_path(span, lang_item, AttrVec::new(), hir_id));
|
||||
self.expr_call_mut(span, path, args)
|
||||
}
|
||||
|
||||
|
@ -1822,7 +1766,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
ident: Ident,
|
||||
binding: hir::HirId,
|
||||
) -> hir::Expr<'hir> {
|
||||
self.expr_ident_with_attrs(sp, ident, binding, ThinVec::new())
|
||||
self.expr_ident_with_attrs(sp, ident, binding, AttrVec::new())
|
||||
}
|
||||
|
||||
fn expr_ident_with_attrs(
|
||||
|
@ -1860,13 +1804,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
}),
|
||||
None,
|
||||
),
|
||||
ThinVec::new(),
|
||||
AttrVec::new(),
|
||||
)
|
||||
}
|
||||
|
||||
fn expr_block_empty(&mut self, span: Span) -> &'hir hir::Expr<'hir> {
|
||||
let blk = self.block_all(span, &[], None);
|
||||
let expr = self.expr_block(blk, ThinVec::new());
|
||||
let expr = self.expr_block(blk, AttrVec::new());
|
||||
self.arena.alloc(expr)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use super::errors::{InvalidAbi, MisplacedRelaxTraitBound};
|
||||
use super::ResolverAstLoweringExt;
|
||||
use super::{AstOwner, ImplTraitContext, ImplTraitPosition};
|
||||
use super::{FnDeclKind, LoweringContext, ParamMode};
|
||||
|
@ -7,7 +8,6 @@ use rustc_ast::visit::AssocCtxt;
|
|||
use rustc_ast::*;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::sorted_map::SortedMap;
|
||||
use rustc_errors::struct_span_err;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
|
||||
|
@ -1260,10 +1260,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
}
|
||||
|
||||
fn error_on_invalid_abi(&self, abi: StrLit) {
|
||||
struct_span_err!(self.tcx.sess, abi.span, E0703, "invalid ABI: found `{}`", abi.symbol)
|
||||
.span_label(abi.span, "invalid ABI")
|
||||
.help(&format!("valid ABIs: {}", abi::all_names().join(", ")))
|
||||
.emit();
|
||||
self.tcx.sess.emit_err(InvalidAbi {
|
||||
span: abi.span,
|
||||
abi: abi.symbol,
|
||||
valid_abis: abi::all_names().join(", "),
|
||||
});
|
||||
}
|
||||
|
||||
fn lower_asyncness(&mut self, a: Async) -> hir::IsAsync {
|
||||
|
@ -1338,11 +1339,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
}
|
||||
let is_param = *is_param.get_or_insert_with(compute_is_param);
|
||||
if !is_param {
|
||||
self.diagnostic().span_err(
|
||||
bound.span(),
|
||||
"`?Trait` bounds are only permitted at the \
|
||||
point where a type parameter is declared",
|
||||
);
|
||||
self.tcx.sess.emit_err(MisplacedRelaxTraitBound { span: bound.span() });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,14 +31,19 @@
|
|||
//! in the HIR, especially for multiple identifiers.
|
||||
|
||||
#![feature(box_patterns)]
|
||||
#![feature(let_chains)]
|
||||
#![feature(let_else)]
|
||||
#![feature(never_type)]
|
||||
#![recursion_limit = "256"]
|
||||
#![allow(rustc::potential_query_instability)]
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate tracing;
|
||||
|
||||
use crate::errors::{AssocTyParentheses, AssocTyParenthesesSub, MisplacedImplTrait};
|
||||
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::visit;
|
||||
use rustc_ast::{self as ast, *};
|
||||
|
@ -49,7 +54,7 @@ use rustc_data_structures::fx::FxHashMap;
|
|||
use rustc_data_structures::sorted_map::SortedMap;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_errors::{struct_span_err, Applicability, Handler, StashKey};
|
||||
use rustc_errors::{DiagnosticArgFromDisplay, Handler, StashKey};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
|
||||
use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
|
||||
|
@ -75,6 +80,7 @@ macro_rules! arena_vec {
|
|||
|
||||
mod asm;
|
||||
mod block;
|
||||
mod errors;
|
||||
mod expr;
|
||||
mod index;
|
||||
mod item;
|
||||
|
@ -928,7 +934,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
} else {
|
||||
Lit {
|
||||
token_lit: token::Lit::new(token::LitKind::Err, kw::Empty, None),
|
||||
kind: LitKind::Err(kw::Empty),
|
||||
kind: LitKind::Err,
|
||||
span: DUMMY_SP,
|
||||
}
|
||||
};
|
||||
|
@ -1070,19 +1076,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
}
|
||||
|
||||
fn emit_bad_parenthesized_trait_in_assoc_ty(&self, data: &ParenthesizedArgs) {
|
||||
let mut err = self.tcx.sess.struct_span_err(
|
||||
data.span,
|
||||
"parenthesized generic arguments cannot be used in associated type constraints",
|
||||
);
|
||||
// Suggest removing empty parentheses: "Trait()" -> "Trait"
|
||||
if data.inputs.is_empty() {
|
||||
let sub = if data.inputs.is_empty() {
|
||||
let parentheses_span =
|
||||
data.inputs_span.shrink_to_lo().to(data.inputs_span.shrink_to_hi());
|
||||
err.multipart_suggestion(
|
||||
"remove these parentheses",
|
||||
vec![(parentheses_span, String::new())],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
AssocTyParenthesesSub::Empty { parentheses_span }
|
||||
}
|
||||
// Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`
|
||||
else {
|
||||
|
@ -1096,13 +1094,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
// End of last argument to end of parameters
|
||||
let close_param =
|
||||
data.inputs.last().unwrap().span.shrink_to_hi().to(data.inputs_span.shrink_to_hi());
|
||||
err.multipart_suggestion(
|
||||
&format!("use angle brackets instead",),
|
||||
vec![(open_param, String::from("<")), (close_param, String::from(">"))],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
err.emit();
|
||||
AssocTyParenthesesSub::NotEmpty { open_param, close_param }
|
||||
};
|
||||
self.tcx.sess.emit_err(AssocTyParentheses { span: data.span, sub });
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
|
@ -1341,14 +1335,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
path
|
||||
}
|
||||
ImplTraitContext::Disallowed(position) => {
|
||||
let mut err = struct_span_err!(
|
||||
self.tcx.sess,
|
||||
t.span,
|
||||
E0562,
|
||||
"`impl Trait` only allowed in function and inherent method return types, not in {}",
|
||||
position
|
||||
);
|
||||
err.emit();
|
||||
self.tcx.sess.emit_err(MisplacedImplTrait {
|
||||
span: t.span,
|
||||
position: DiagnosticArgFromDisplay(&position),
|
||||
});
|
||||
hir::TyKind::Err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
use super::errors::{
|
||||
ArbitraryExpressionInPattern, ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding,
|
||||
};
|
||||
use super::ResolverAstLoweringExt;
|
||||
use super::{ImplTraitContext, LoweringContext, ParamMode};
|
||||
use crate::ImplTraitPosition;
|
||||
|
@ -5,7 +8,6 @@ use crate::ImplTraitPosition;
|
|||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::*;
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_span::symbol::Ident;
|
||||
|
@ -134,20 +136,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
// This is not allowed as a sub-tuple pattern
|
||||
PatKind::Ident(ref _bm, ident, Some(ref sub)) if sub.is_rest() => {
|
||||
let sp = pat.span;
|
||||
self.diagnostic()
|
||||
.struct_span_err(
|
||||
sp,
|
||||
&format!("`{} @` is not allowed in a {}", ident.name, ctx),
|
||||
)
|
||||
.span_label(sp, "this is only allowed in slice patterns")
|
||||
.help("remove this and bind each tuple field independently")
|
||||
.span_suggestion_verbose(
|
||||
sp,
|
||||
&format!("if you don't need to use the contents of {}, discard the tuple's remaining fields", ident),
|
||||
"..",
|
||||
Applicability::MaybeIncorrect,
|
||||
)
|
||||
.emit();
|
||||
self.tcx.sess.emit_err(SubTupleBinding {
|
||||
span: sp,
|
||||
ident_name: ident.name,
|
||||
ident,
|
||||
ctx,
|
||||
});
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -296,19 +290,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
|
||||
/// Emit a friendly error for extra `..` patterns in a tuple/tuple struct/slice pattern.
|
||||
pub(crate) fn ban_extra_rest_pat(&self, sp: Span, prev_sp: Span, ctx: &str) {
|
||||
self.diagnostic()
|
||||
.struct_span_err(sp, &format!("`..` can only be used once per {} pattern", ctx))
|
||||
.span_label(sp, &format!("can only be used once per {} pattern", ctx))
|
||||
.span_label(prev_sp, "previously used here")
|
||||
.emit();
|
||||
self.tcx.sess.emit_err(ExtraDoubleDot { span: sp, prev_span: prev_sp, ctx });
|
||||
}
|
||||
|
||||
/// Used to ban the `..` pattern in places it shouldn't be semantically.
|
||||
fn ban_illegal_rest_pat(&self, sp: Span) -> hir::PatKind<'hir> {
|
||||
self.diagnostic()
|
||||
.struct_span_err(sp, "`..` patterns are not allowed here")
|
||||
.note("only allowed in tuple, tuple struct, and slice patterns")
|
||||
.emit();
|
||||
self.tcx.sess.emit_err(MisplacedDoubleDot { span: sp });
|
||||
|
||||
// We're not in a list context so `..` can be reasonably treated
|
||||
// as `_` because it should always be valid and roughly matches the
|
||||
|
@ -345,8 +332,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
ExprKind::Path(..) if allow_paths => {}
|
||||
ExprKind::Unary(UnOp::Neg, ref inner) if matches!(inner.kind, ExprKind::Lit(_)) => {}
|
||||
_ => {
|
||||
self.diagnostic()
|
||||
.span_err(expr.span, "arbitrary expressions aren't allowed in patterns");
|
||||
self.tcx.sess.emit_err(ArbitraryExpressionInPattern { span: expr.span });
|
||||
return self.arena.alloc(self.expr_err(expr.span));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
use crate::ImplTraitPosition;
|
||||
|
||||
use super::errors::{GenericTypeWithParentheses, UseAngleBrackets};
|
||||
use super::ResolverAstLoweringExt;
|
||||
use super::{GenericArgsCtor, LifetimeRes, ParenthesizedGenericArgs};
|
||||
use super::{ImplTraitContext, LoweringContext, ParamMode};
|
||||
|
||||
use rustc_ast::{self as ast, *};
|
||||
use rustc_errors::{struct_span_err, Applicability};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, PartialRes, Res};
|
||||
use rustc_hir::GenericArg;
|
||||
|
@ -185,7 +185,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
) -> hir::PathSegment<'hir> {
|
||||
debug!("path_span: {:?}, lower_path_segment(segment: {:?})", path_span, segment,);
|
||||
let (mut generic_args, infer_args) = if let Some(ref generic_args) = segment.args {
|
||||
let msg = "parenthesized type parameters may only be used with a `Fn` trait";
|
||||
match **generic_args {
|
||||
GenericArgs::AngleBracketed(ref data) => {
|
||||
self.lower_angle_bracketed_parameter_data(data, param_mode, itctx)
|
||||
|
@ -193,10 +192,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
GenericArgs::Parenthesized(ref data) => match parenthesized_generic_args {
|
||||
ParenthesizedGenericArgs::Ok => self.lower_parenthesized_parameter_data(data),
|
||||
ParenthesizedGenericArgs::Err => {
|
||||
let mut err = struct_span_err!(self.tcx.sess, data.span, E0214, "{}", msg);
|
||||
err.span_label(data.span, "only `Fn` traits may use parentheses");
|
||||
// Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`
|
||||
if !data.inputs.is_empty() {
|
||||
let sub = if !data.inputs.is_empty() {
|
||||
// Start of the span to the 1st character of 1st argument
|
||||
let open_param = data.inputs_span.shrink_to_lo().to(data
|
||||
.inputs
|
||||
|
@ -212,16 +209,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
.span
|
||||
.shrink_to_hi()
|
||||
.to(data.inputs_span.shrink_to_hi());
|
||||
err.multipart_suggestion(
|
||||
&format!("use angle brackets instead",),
|
||||
vec![
|
||||
(open_param, String::from("<")),
|
||||
(close_param, String::from(">")),
|
||||
],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
err.emit();
|
||||
|
||||
Some(UseAngleBrackets { open_param, close_param })
|
||||
} else {
|
||||
None
|
||||
};
|
||||
self.tcx.sess.emit_err(GenericTypeWithParentheses { span: data.span, sub });
|
||||
(
|
||||
self.lower_angle_bracketed_parameter_data(
|
||||
&data.as_angle_bracketed_args(),
|
||||
|
|
|
@ -11,6 +11,7 @@ rustc_attr = { path = "../rustc_attr" }
|
|||
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||
rustc_errors = { path = "../rustc_errors" }
|
||||
rustc_feature = { path = "../rustc_feature" }
|
||||
rustc_macros = { path = "../rustc_macros" }
|
||||
rustc_parse = { path = "../rustc_parse" }
|
||||
rustc_session = { path = "../rustc_session" }
|
||||
rustc_span = { path = "../rustc_span" }
|
||||
|
|
|
@ -13,7 +13,7 @@ use rustc_ast::walk_list;
|
|||
use rustc_ast::*;
|
||||
use rustc_ast_pretty::pprust::{self, State};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::{error_code, pluralize, struct_span_err, Applicability, Diagnostic};
|
||||
use rustc_errors::{error_code, fluent, pluralize, struct_span_err, Applicability};
|
||||
use rustc_parse::validate_attr;
|
||||
use rustc_session::lint::builtin::{
|
||||
DEPRECATED_WHERE_CLAUSE_LOCATION, MISSING_ABI, PATTERNS_IN_FNS_WITHOUT_BODY,
|
||||
|
@ -27,6 +27,8 @@ use rustc_target::spec::abi;
|
|||
use std::mem;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
use crate::errors::*;
|
||||
|
||||
const MORE_EXTERN: &str =
|
||||
"for more information, visit https://doc.rust-lang.org/std/keyword.extern.html";
|
||||
|
||||
|
@ -117,23 +119,12 @@ impl<'a> AstValidator<'a> {
|
|||
|
||||
/// Emits an error banning the `let` expression provided in the given location.
|
||||
fn ban_let_expr(&self, expr: &'a Expr, forbidden_let_reason: ForbiddenLetReason) {
|
||||
let err = "`let` expressions are not supported here";
|
||||
let mut diag = self.session.struct_span_err(expr.span, err);
|
||||
diag.note("only supported directly in conditions of `if` and `while` expressions");
|
||||
match forbidden_let_reason {
|
||||
ForbiddenLetReason::GenericForbidden => {}
|
||||
ForbiddenLetReason::NotSupportedOr(span) => {
|
||||
diag.span_note(span, "`||` operators are not supported in let chain expressions");
|
||||
let sess = &self.session;
|
||||
if sess.opts.unstable_features.is_nightly_build() {
|
||||
sess.emit_err(ForbiddenLet { span: expr.span, reason: forbidden_let_reason });
|
||||
} else {
|
||||
sess.emit_err(ForbiddenLetStable { span: expr.span });
|
||||
}
|
||||
ForbiddenLetReason::NotSupportedParentheses(span) => {
|
||||
diag.span_note(
|
||||
span,
|
||||
"`let`s wrapped in parentheses are not supported in a context with let \
|
||||
chains",
|
||||
);
|
||||
}
|
||||
}
|
||||
diag.emit();
|
||||
}
|
||||
|
||||
fn check_gat_where(
|
||||
|
@ -163,7 +154,7 @@ impl<'a> AstValidator<'a> {
|
|||
DEPRECATED_WHERE_CLAUSE_LOCATION,
|
||||
id,
|
||||
where_clauses.0.1,
|
||||
"where clause not allowed here",
|
||||
fluent::ast_passes::deprecated_where_clause_location,
|
||||
BuiltinLintDiagnostics::DeprecatedWhereclauseLocation(
|
||||
where_clauses.1.1.shrink_to_hi(),
|
||||
suggestion,
|
||||
|
@ -193,10 +184,7 @@ impl<'a> AstValidator<'a> {
|
|||
AssocConstraintKind::Equality { .. } => {}
|
||||
AssocConstraintKind::Bound { .. } => {
|
||||
if self.is_assoc_ty_bound_banned {
|
||||
self.err_handler().span_err(
|
||||
constraint.span,
|
||||
"associated type bounds are not allowed within structs, enums, or unions",
|
||||
);
|
||||
self.session.emit_err(ForbiddenAssocConstraint { span: constraint.span });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -268,31 +256,26 @@ impl<'a> AstValidator<'a> {
|
|||
fn check_lifetime(&self, ident: Ident) {
|
||||
let valid_names = [kw::UnderscoreLifetime, kw::StaticLifetime, kw::Empty];
|
||||
if !valid_names.contains(&ident.name) && ident.without_first_quote().is_reserved() {
|
||||
self.err_handler().span_err(ident.span, "lifetimes cannot use keyword names");
|
||||
self.session.emit_err(KeywordLifetime { span: ident.span });
|
||||
}
|
||||
}
|
||||
|
||||
fn check_label(&self, ident: Ident) {
|
||||
if ident.without_first_quote().is_reserved() {
|
||||
self.err_handler()
|
||||
.span_err(ident.span, &format!("invalid label name `{}`", ident.name));
|
||||
self.session.emit_err(InvalidLabel { span: ident.span, name: ident.name });
|
||||
}
|
||||
}
|
||||
|
||||
fn invalid_visibility(&self, vis: &Visibility, note: Option<&str>) {
|
||||
fn invalid_visibility(&self, vis: &Visibility, note: Option<InvalidVisibilityNote>) {
|
||||
if let VisibilityKind::Inherited = vis.kind {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut err =
|
||||
struct_span_err!(self.session, vis.span, E0449, "unnecessary visibility qualifier");
|
||||
if vis.kind.is_pub() {
|
||||
err.span_label(vis.span, "`pub` not permitted here because it's implied");
|
||||
}
|
||||
if let Some(note) = note {
|
||||
err.note(note);
|
||||
}
|
||||
err.emit();
|
||||
self.session.emit_err(InvalidVisibility {
|
||||
span: vis.span,
|
||||
implied: if vis.kind.is_pub() { Some(vis.span) } else { None },
|
||||
note,
|
||||
});
|
||||
}
|
||||
|
||||
fn check_decl_no_pat(decl: &FnDecl, mut report_err: impl FnMut(Span, Option<Ident>, bool)) {
|
||||
|
@ -309,29 +292,13 @@ impl<'a> AstValidator<'a> {
|
|||
|
||||
fn check_trait_fn_not_async(&self, fn_span: Span, asyncness: Async) {
|
||||
if let Async::Yes { span, .. } = asyncness {
|
||||
struct_span_err!(
|
||||
self.session,
|
||||
fn_span,
|
||||
E0706,
|
||||
"functions in traits cannot be declared `async`"
|
||||
)
|
||||
.span_label(span, "`async` because of this")
|
||||
.note("`async` trait functions are not currently supported")
|
||||
.note("consider using the `async-trait` crate: https://crates.io/crates/async-trait")
|
||||
.emit();
|
||||
self.session.emit_err(TraitFnAsync { fn_span, span });
|
||||
}
|
||||
}
|
||||
|
||||
fn check_trait_fn_not_const(&self, constness: Const) {
|
||||
if let Const::Yes(span) = constness {
|
||||
struct_span_err!(
|
||||
self.session,
|
||||
span,
|
||||
E0379,
|
||||
"functions in traits cannot be declared const"
|
||||
)
|
||||
.span_label(span, "functions in traits cannot be const")
|
||||
.emit();
|
||||
self.session.emit_err(TraitFnConst { span });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -344,8 +311,7 @@ impl<'a> AstValidator<'a> {
|
|||
GenericParamKind::Lifetime { .. } => {
|
||||
if !param.bounds.is_empty() {
|
||||
let spans: Vec<_> = param.bounds.iter().map(|b| b.span()).collect();
|
||||
self.err_handler()
|
||||
.span_err(spans, "lifetime bounds cannot be used in this context");
|
||||
self.session.emit_err(ForbiddenLifetimeBound { spans });
|
||||
}
|
||||
None
|
||||
}
|
||||
|
@ -353,10 +319,7 @@ impl<'a> AstValidator<'a> {
|
|||
})
|
||||
.collect();
|
||||
if !non_lt_param_spans.is_empty() {
|
||||
self.err_handler().span_err(
|
||||
non_lt_param_spans,
|
||||
"only lifetime parameters can be used in this context",
|
||||
);
|
||||
self.session.emit_err(ForbiddenNonLifetimeParam { spans: non_lt_param_spans });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -373,10 +336,7 @@ impl<'a> AstValidator<'a> {
|
|||
let max_num_args: usize = u16::MAX.into();
|
||||
if fn_decl.inputs.len() > max_num_args {
|
||||
let Param { span, .. } = fn_decl.inputs[0];
|
||||
self.err_handler().span_fatal(
|
||||
span,
|
||||
&format!("function can not have more than {} arguments", max_num_args),
|
||||
);
|
||||
self.session.emit_fatal(FnParamTooMany { span, max_num_args });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -384,19 +344,13 @@ impl<'a> AstValidator<'a> {
|
|||
match &*fn_decl.inputs {
|
||||
[Param { ty, span, .. }] => {
|
||||
if let TyKind::CVarArgs = ty.kind {
|
||||
self.err_handler().span_err(
|
||||
*span,
|
||||
"C-variadic function must be declared with at least one named argument",
|
||||
);
|
||||
self.session.emit_err(FnParamCVarArgsOnly { span: *span });
|
||||
}
|
||||
}
|
||||
[ps @ .., _] => {
|
||||
for Param { ty, span, .. } in ps {
|
||||
if let TyKind::CVarArgs = ty.kind {
|
||||
self.err_handler().span_err(
|
||||
*span,
|
||||
"`...` must be the last argument of a C-variadic function",
|
||||
);
|
||||
self.session.emit_err(FnParamCVarArgsNotLast { span: *span });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -423,19 +377,9 @@ impl<'a> AstValidator<'a> {
|
|||
})
|
||||
.for_each(|attr| {
|
||||
if attr.is_doc_comment() {
|
||||
self.err_handler()
|
||||
.struct_span_err(
|
||||
attr.span,
|
||||
"documentation comments cannot be applied to function parameters",
|
||||
)
|
||||
.span_label(attr.span, "doc comments are not allowed here")
|
||||
.emit();
|
||||
self.session.emit_err(FnParamDocComment { span: attr.span });
|
||||
} else {
|
||||
self.err_handler().span_err(
|
||||
attr.span,
|
||||
"allow, cfg, cfg_attr, deny, expect, \
|
||||
forbid, and warn are the only allowed built-in attributes in function parameters",
|
||||
);
|
||||
self.session.emit_err(FnParamForbiddenAttr { span: attr.span });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -443,14 +387,7 @@ impl<'a> AstValidator<'a> {
|
|||
fn check_decl_self_param(&self, fn_decl: &FnDecl, self_semantic: SelfSemantic) {
|
||||
if let (SelfSemantic::No, [param, ..]) = (self_semantic, &*fn_decl.inputs) {
|
||||
if param.is_self() {
|
||||
self.err_handler()
|
||||
.struct_span_err(
|
||||
param.span,
|
||||
"`self` parameter is only allowed in associated functions",
|
||||
)
|
||||
.span_label(param.span, "not semantically valid as function parameter")
|
||||
.note("associated functions are those in `impl` or `trait` definitions")
|
||||
.emit();
|
||||
self.session.emit_err(FnParamForbiddenSelf { span: param.span });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -458,47 +395,20 @@ impl<'a> AstValidator<'a> {
|
|||
fn check_defaultness(&self, span: Span, defaultness: Defaultness) {
|
||||
if let Defaultness::Default(def_span) = defaultness {
|
||||
let span = self.session.source_map().guess_head_span(span);
|
||||
self.err_handler()
|
||||
.struct_span_err(span, "`default` is only allowed on items in trait impls")
|
||||
.span_label(def_span, "`default` because of this")
|
||||
.emit();
|
||||
self.session.emit_err(ForbiddenDefault { span, def_span });
|
||||
}
|
||||
}
|
||||
|
||||
fn error_item_without_body(&self, sp: Span, ctx: &str, msg: &str, sugg: &str) {
|
||||
self.error_item_without_body_with_help(sp, ctx, msg, sugg, |_| ());
|
||||
}
|
||||
|
||||
fn error_item_without_body_with_help(
|
||||
&self,
|
||||
sp: Span,
|
||||
ctx: &str,
|
||||
msg: &str,
|
||||
sugg: &str,
|
||||
help: impl FnOnce(&mut Diagnostic),
|
||||
) {
|
||||
/// If `sp` ends with a semicolon, returns it as a `Span`
|
||||
/// Otherwise, returns `sp.shrink_to_hi()`
|
||||
fn ending_semi_or_hi(&self, sp: Span) -> Span {
|
||||
let source_map = self.session.source_map();
|
||||
let end = source_map.end_point(sp);
|
||||
let replace_span = if source_map.span_to_snippet(end).map(|s| s == ";").unwrap_or(false) {
|
||||
|
||||
if source_map.span_to_snippet(end).map(|s| s == ";").unwrap_or(false) {
|
||||
end
|
||||
} else {
|
||||
sp.shrink_to_hi()
|
||||
};
|
||||
let mut err = self.err_handler().struct_span_err(sp, msg);
|
||||
err.span_suggestion(
|
||||
replace_span,
|
||||
&format!("provide a definition for the {}", ctx),
|
||||
sugg,
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
help(&mut err);
|
||||
err.emit();
|
||||
}
|
||||
|
||||
fn check_impl_item_provided<T>(&self, sp: Span, body: &Option<T>, ctx: &str, sugg: &str) {
|
||||
if body.is_none() {
|
||||
let msg = format!("associated {} in `impl` without body", ctx);
|
||||
self.error_item_without_body(sp, ctx, &msg, sugg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1168,7 +1078,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
|
||||
self.invalid_visibility(
|
||||
&item.vis,
|
||||
Some("place qualifiers on individual impl items instead"),
|
||||
Some(InvalidVisibilityNote::IndividualImplItems),
|
||||
);
|
||||
if let Unsafe::Yes(span) = unsafety {
|
||||
error(span, "unsafe").code(error_code!(E0197)).emit();
|
||||
|
@ -1191,37 +1101,23 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
self.check_defaultness(item.span, defaultness);
|
||||
|
||||
if body.is_none() {
|
||||
let msg = "free function without a body";
|
||||
let ext = sig.header.ext;
|
||||
|
||||
let f = |e: &mut Diagnostic| {
|
||||
if let Extern::Implicit(start_span) | Extern::Explicit(_, start_span) = &ext
|
||||
{
|
||||
let start_suggestion = if let Extern::Explicit(abi, _) = ext {
|
||||
format!("extern \"{}\" {{", abi.symbol_unescaped)
|
||||
} else {
|
||||
"extern {".to_owned()
|
||||
};
|
||||
|
||||
let end_suggestion = " }".to_owned();
|
||||
let end_span = item.span.shrink_to_hi();
|
||||
|
||||
e
|
||||
.multipart_suggestion(
|
||||
"if you meant to declare an externally defined function, use an `extern` block",
|
||||
vec![(*start_span, start_suggestion), (end_span, end_suggestion)],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
self.error_item_without_body_with_help(
|
||||
item.span,
|
||||
"function",
|
||||
msg,
|
||||
" { <body> }",
|
||||
f,
|
||||
);
|
||||
self.session.emit_err(FnWithoutBody {
|
||||
span: item.span,
|
||||
replace_span: self.ending_semi_or_hi(item.span),
|
||||
extern_block_suggestion: match sig.header.ext {
|
||||
Extern::None => None,
|
||||
Extern::Implicit(start_span) => Some(ExternBlockSuggestion {
|
||||
start_span,
|
||||
end_span: item.span.shrink_to_hi(),
|
||||
abi: None,
|
||||
}),
|
||||
Extern::Explicit(abi, start_span) => Some(ExternBlockSuggestion {
|
||||
start_span,
|
||||
end_span: item.span.shrink_to_hi(),
|
||||
abi: Some(abi.symbol_unescaped),
|
||||
}),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
self.visit_vis(&item.vis);
|
||||
|
@ -1236,7 +1132,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
let old_item = mem::replace(&mut self.extern_mod, Some(item));
|
||||
self.invalid_visibility(
|
||||
&item.vis,
|
||||
Some("place qualifiers on individual foreign items instead"),
|
||||
Some(InvalidVisibilityNote::IndividualForeignItems),
|
||||
);
|
||||
if let Unsafe::Yes(span) = unsafety {
|
||||
self.err_handler().span_err(span, "extern block cannot be declared unsafe");
|
||||
|
@ -1327,12 +1223,16 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
}
|
||||
ItemKind::Const(def, .., None) => {
|
||||
self.check_defaultness(item.span, def);
|
||||
let msg = "free constant item without body";
|
||||
self.error_item_without_body(item.span, "constant", msg, " = <expr>;");
|
||||
self.session.emit_err(ConstWithoutBody {
|
||||
span: item.span,
|
||||
replace_span: self.ending_semi_or_hi(item.span),
|
||||
});
|
||||
}
|
||||
ItemKind::Static(.., None) => {
|
||||
let msg = "free static item without body";
|
||||
self.error_item_without_body(item.span, "static", msg, " = <expr>;");
|
||||
self.session.emit_err(StaticWithoutBody {
|
||||
span: item.span,
|
||||
replace_span: self.ending_semi_or_hi(item.span),
|
||||
});
|
||||
}
|
||||
ItemKind::TyAlias(box TyAlias {
|
||||
defaultness,
|
||||
|
@ -1343,8 +1243,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
}) => {
|
||||
self.check_defaultness(item.span, defaultness);
|
||||
if ty.is_none() {
|
||||
let msg = "free type alias without body";
|
||||
self.error_item_without_body(item.span, "type", msg, " = <type>;");
|
||||
self.session.emit_err(TyAliasWithoutBody {
|
||||
span: item.span,
|
||||
replace_span: self.ending_semi_or_hi(item.span),
|
||||
});
|
||||
}
|
||||
self.check_type_no_bounds(bounds, "this context");
|
||||
if where_clauses.1.0 {
|
||||
|
@ -1648,10 +1550,20 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
if ctxt == AssocCtxt::Impl {
|
||||
match &item.kind {
|
||||
AssocItemKind::Const(_, _, body) => {
|
||||
self.check_impl_item_provided(item.span, body, "constant", " = <expr>;");
|
||||
if body.is_none() {
|
||||
self.session.emit_err(AssocConstWithoutBody {
|
||||
span: item.span,
|
||||
replace_span: self.ending_semi_or_hi(item.span),
|
||||
});
|
||||
}
|
||||
}
|
||||
AssocItemKind::Fn(box Fn { body, .. }) => {
|
||||
self.check_impl_item_provided(item.span, body, "function", " { <body> }");
|
||||
if body.is_none() {
|
||||
self.session.emit_err(AssocFnWithoutBody {
|
||||
span: item.span,
|
||||
replace_span: self.ending_semi_or_hi(item.span),
|
||||
});
|
||||
}
|
||||
}
|
||||
AssocItemKind::TyAlias(box TyAlias {
|
||||
generics,
|
||||
|
@ -1661,7 +1573,12 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
ty,
|
||||
..
|
||||
}) => {
|
||||
self.check_impl_item_provided(item.span, ty, "type", " = <type>;");
|
||||
if ty.is_none() {
|
||||
self.session.emit_err(AssocTypeWithoutBody {
|
||||
span: item.span,
|
||||
replace_span: self.ending_semi_or_hi(item.span),
|
||||
});
|
||||
}
|
||||
self.check_type_no_bounds(bounds, "`impl`s");
|
||||
if ty.is_some() {
|
||||
self.check_gat_where(
|
||||
|
@ -1876,7 +1793,7 @@ pub fn check_crate(session: &Session, krate: &Crate, lints: &mut LintBuffer) ->
|
|||
|
||||
/// Used to forbid `let` expressions in certain syntactic locations.
|
||||
#[derive(Clone, Copy)]
|
||||
enum ForbiddenLetReason {
|
||||
pub(crate) enum ForbiddenLetReason {
|
||||
/// `let` is not valid and the source environment is not important
|
||||
GenericForbidden,
|
||||
/// A let chain with the `||` operator
|
||||
|
|
256
compiler/rustc_ast_passes/src/errors.rs
Normal file
256
compiler/rustc_ast_passes/src/errors.rs
Normal file
|
@ -0,0 +1,256 @@
|
|||
//! Errors emitted by ast_passes.
|
||||
|
||||
use rustc_errors::{fluent, AddSubdiagnostic, Applicability, Diagnostic};
|
||||
use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic};
|
||||
use rustc_span::{Span, Symbol};
|
||||
|
||||
use crate::ast_validation::ForbiddenLetReason;
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(ast_passes::forbidden_let)]
|
||||
#[note]
|
||||
pub struct ForbiddenLet {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[subdiagnostic]
|
||||
pub(crate) reason: ForbiddenLetReason,
|
||||
}
|
||||
|
||||
impl AddSubdiagnostic for ForbiddenLetReason {
|
||||
fn add_to_diagnostic(self, diag: &mut Diagnostic) {
|
||||
match self {
|
||||
Self::GenericForbidden => {}
|
||||
Self::NotSupportedOr(span) => {
|
||||
diag.span_note(span, fluent::ast_passes::not_supported_or);
|
||||
}
|
||||
Self::NotSupportedParentheses(span) => {
|
||||
diag.span_note(span, fluent::ast_passes::not_supported_parentheses);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(ast_passes::forbidden_let_stable)]
|
||||
#[note]
|
||||
pub struct ForbiddenLetStable {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(ast_passes::forbidden_assoc_constraint)]
|
||||
pub struct ForbiddenAssocConstraint {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(ast_passes::keyword_lifetime)]
|
||||
pub struct KeywordLifetime {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(ast_passes::invalid_label)]
|
||||
pub struct InvalidLabel {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub name: Symbol,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(ast_passes::invalid_visibility, code = "E0449")]
|
||||
pub struct InvalidVisibility {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[label(ast_passes::implied)]
|
||||
pub implied: Option<Span>,
|
||||
#[subdiagnostic]
|
||||
pub note: Option<InvalidVisibilityNote>,
|
||||
}
|
||||
|
||||
#[derive(SessionSubdiagnostic)]
|
||||
pub enum InvalidVisibilityNote {
|
||||
#[note(ast_passes::individual_impl_items)]
|
||||
IndividualImplItems,
|
||||
#[note(ast_passes::individual_foreign_items)]
|
||||
IndividualForeignItems,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(ast_passes::trait_fn_async, code = "E0706")]
|
||||
#[note]
|
||||
#[note(ast_passes::note2)]
|
||||
pub struct TraitFnAsync {
|
||||
#[primary_span]
|
||||
pub fn_span: Span,
|
||||
#[label]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(ast_passes::trait_fn_const, code = "E0379")]
|
||||
pub struct TraitFnConst {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(ast_passes::forbidden_lifetime_bound)]
|
||||
pub struct ForbiddenLifetimeBound {
|
||||
#[primary_span]
|
||||
pub spans: Vec<Span>,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(ast_passes::forbidden_non_lifetime_param)]
|
||||
pub struct ForbiddenNonLifetimeParam {
|
||||
#[primary_span]
|
||||
pub spans: Vec<Span>,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(ast_passes::fn_param_too_many)]
|
||||
pub struct FnParamTooMany {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub max_num_args: usize,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(ast_passes::fn_param_c_var_args_only)]
|
||||
pub struct FnParamCVarArgsOnly {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(ast_passes::fn_param_c_var_args_not_last)]
|
||||
pub struct FnParamCVarArgsNotLast {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(ast_passes::fn_param_doc_comment)]
|
||||
pub struct FnParamDocComment {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(ast_passes::fn_param_forbidden_attr)]
|
||||
pub struct FnParamForbiddenAttr {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(ast_passes::fn_param_forbidden_self)]
|
||||
#[note]
|
||||
pub struct FnParamForbiddenSelf {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(ast_passes::forbidden_default)]
|
||||
pub struct ForbiddenDefault {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[label]
|
||||
pub def_span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(ast_passes::assoc_const_without_body)]
|
||||
pub struct AssocConstWithoutBody {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[suggestion(code = " = <expr>;", applicability = "has-placeholders")]
|
||||
pub replace_span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(ast_passes::assoc_fn_without_body)]
|
||||
pub struct AssocFnWithoutBody {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[suggestion(code = " {{ <body> }}", applicability = "has-placeholders")]
|
||||
pub replace_span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(ast_passes::assoc_type_without_body)]
|
||||
pub struct AssocTypeWithoutBody {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[suggestion(code = " = <type>;", applicability = "has-placeholders")]
|
||||
pub replace_span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(ast_passes::const_without_body)]
|
||||
pub struct ConstWithoutBody {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[suggestion(code = " = <expr>;", applicability = "has-placeholders")]
|
||||
pub replace_span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(ast_passes::static_without_body)]
|
||||
pub struct StaticWithoutBody {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[suggestion(code = " = <expr>;", applicability = "has-placeholders")]
|
||||
pub replace_span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(ast_passes::ty_alias_without_body)]
|
||||
pub struct TyAliasWithoutBody {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[suggestion(code = " = <type>;", applicability = "has-placeholders")]
|
||||
pub replace_span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(ast_passes::fn_without_body)]
|
||||
pub struct FnWithoutBody {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[suggestion(code = " {{ <body> }}", applicability = "has-placeholders")]
|
||||
pub replace_span: Span,
|
||||
#[subdiagnostic]
|
||||
pub extern_block_suggestion: Option<ExternBlockSuggestion>,
|
||||
}
|
||||
|
||||
pub struct ExternBlockSuggestion {
|
||||
pub start_span: Span,
|
||||
pub end_span: Span,
|
||||
pub abi: Option<Symbol>,
|
||||
}
|
||||
|
||||
impl AddSubdiagnostic for ExternBlockSuggestion {
|
||||
fn add_to_diagnostic(self, diag: &mut Diagnostic) {
|
||||
let start_suggestion = if let Some(abi) = self.abi {
|
||||
format!("extern \"{}\" {{", abi)
|
||||
} else {
|
||||
"extern {".to_owned()
|
||||
};
|
||||
let end_suggestion = " }".to_owned();
|
||||
|
||||
diag.multipart_suggestion(
|
||||
fluent::ast_passes::extern_block_suggestion,
|
||||
vec![(self.start_span, start_suggestion), (self.end_span, end_suggestion)],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
|
@ -2,10 +2,10 @@ use rustc_ast as ast;
|
|||
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
|
||||
use rustc_ast::{AssocConstraint, AssocConstraintKind, NodeId};
|
||||
use rustc_ast::{PatKind, RangeEnd, VariantData};
|
||||
use rustc_errors::{struct_span_err, Applicability};
|
||||
use rustc_errors::{struct_span_err, Applicability, StashKey};
|
||||
use rustc_feature::Features;
|
||||
use rustc_feature::{AttributeGate, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
|
||||
use rustc_feature::{Features, GateIssue};
|
||||
use rustc_session::parse::{feature_err, feature_err_issue};
|
||||
use rustc_session::parse::{feature_err, feature_warn};
|
||||
use rustc_session::Session;
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::symbol::sym;
|
||||
|
@ -20,9 +20,7 @@ macro_rules! gate_feature_fn {
|
|||
let has_feature: bool = has_feature(visitor.features);
|
||||
debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", name, span, has_feature);
|
||||
if !has_feature && !span.allows_unstable($name) {
|
||||
feature_err_issue(&visitor.sess.parse_sess, name, span, GateIssue::Language, explain)
|
||||
.help(help)
|
||||
.emit();
|
||||
feature_err(&visitor.sess.parse_sess, name, span, explain).help(help).emit();
|
||||
}
|
||||
}};
|
||||
($visitor: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr) => {{
|
||||
|
@ -31,8 +29,19 @@ macro_rules! gate_feature_fn {
|
|||
let has_feature: bool = has_feature(visitor.features);
|
||||
debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", name, span, has_feature);
|
||||
if !has_feature && !span.allows_unstable($name) {
|
||||
feature_err_issue(&visitor.sess.parse_sess, name, span, GateIssue::Language, explain)
|
||||
.emit();
|
||||
feature_err(&visitor.sess.parse_sess, name, span, explain).emit();
|
||||
}
|
||||
}};
|
||||
(future_incompatible; $visitor: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr) => {{
|
||||
let (visitor, has_feature, span, name, explain) =
|
||||
(&*$visitor, $has_feature, $span, $name, $explain);
|
||||
let has_feature: bool = has_feature(visitor.features);
|
||||
debug!(
|
||||
"gate_feature(feature = {:?}, span = {:?}); has? {} (future_incompatible)",
|
||||
name, span, has_feature
|
||||
);
|
||||
if !has_feature && !span.allows_unstable($name) {
|
||||
feature_warn(&visitor.sess.parse_sess, name, span, explain);
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
@ -44,6 +53,9 @@ macro_rules! gate_feature_post {
|
|||
($visitor: expr, $feature: ident, $span: expr, $explain: expr) => {
|
||||
gate_feature_fn!($visitor, |x: &Features| x.$feature, $span, sym::$feature, $explain)
|
||||
};
|
||||
(future_incompatible; $visitor: expr, $feature: ident, $span: expr, $explain: expr) => {
|
||||
gate_feature_fn!(future_incompatible; $visitor, |x: &Features| x.$feature, $span, sym::$feature, $explain)
|
||||
};
|
||||
}
|
||||
|
||||
pub fn check_attribute(attr: &ast::Attribute, sess: &Session, features: &Features) {
|
||||
|
@ -588,11 +600,10 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
|||
{
|
||||
// When we encounter a statement of the form `foo: Ty = val;`, this will emit a type
|
||||
// ascription error, but the likely intention was to write a `let` statement. (#78907).
|
||||
feature_err_issue(
|
||||
feature_err(
|
||||
&self.sess.parse_sess,
|
||||
sym::type_ascription,
|
||||
lhs.span,
|
||||
GateIssue::Language,
|
||||
"type ascription is experimental",
|
||||
).span_suggestion_verbose(
|
||||
lhs.span.shrink_to_lo(),
|
||||
|
@ -615,28 +626,27 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
|||
);
|
||||
}
|
||||
ast::ExprKind::Type(..) => {
|
||||
// To avoid noise about type ascription in common syntax errors, only emit if it
|
||||
// is the *only* error.
|
||||
if self.sess.parse_sess.span_diagnostic.err_count() == 0 {
|
||||
// To avoid noise about type ascription in common syntax errors,
|
||||
// only emit if it is the *only* error.
|
||||
gate_feature_post!(
|
||||
&self,
|
||||
type_ascription,
|
||||
e.span,
|
||||
"type ascription is experimental"
|
||||
);
|
||||
} else {
|
||||
// And if it isn't, cancel the early-pass warning.
|
||||
self.sess
|
||||
.parse_sess
|
||||
.span_diagnostic
|
||||
.steal_diagnostic(e.span, StashKey::EarlySyntaxWarning)
|
||||
.map(|err| err.cancel());
|
||||
}
|
||||
}
|
||||
ast::ExprKind::TryBlock(_) => {
|
||||
gate_feature_post!(&self, try_blocks, e.span, "`try` expression is experimental");
|
||||
}
|
||||
ast::ExprKind::Block(_, Some(label)) => {
|
||||
gate_feature_post!(
|
||||
&self,
|
||||
label_break_value,
|
||||
label.ident.span,
|
||||
"labels on blocks are unstable"
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
visit::walk_expr(self, e)
|
||||
|
@ -767,6 +777,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
|
|||
"`if let` guards are experimental",
|
||||
"you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`"
|
||||
);
|
||||
gate_all!(let_chains, "`let` expressions in this position are unstable");
|
||||
gate_all!(
|
||||
async_closure,
|
||||
"async closures are unstable",
|
||||
|
@ -789,14 +800,12 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
|
|||
|
||||
// All uses of `gate_all!` below this point were added in #65742,
|
||||
// and subsequently disabled (with the non-early gating readded).
|
||||
// We emit an early future-incompatible warning for these.
|
||||
// New syntax gates should go above here to get a hard error gate.
|
||||
macro_rules! gate_all {
|
||||
($gate:ident, $msg:literal) => {
|
||||
// FIXME(eddyb) do something more useful than always
|
||||
// disabling these uses of early feature-gatings.
|
||||
if false {
|
||||
for span in spans.get(&sym::$gate).unwrap_or(&vec![]) {
|
||||
gate_feature_post!(&visitor, $gate, *span, $msg);
|
||||
}
|
||||
gate_feature_post!(future_incompatible; &visitor, $gate, *span, $msg);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -807,13 +816,8 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
|
|||
gate_all!(box_patterns, "box pattern syntax is experimental");
|
||||
gate_all!(exclusive_range_pattern, "exclusive range pattern syntax is experimental");
|
||||
gate_all!(try_blocks, "`try` blocks are unstable");
|
||||
gate_all!(label_break_value, "labels on blocks are unstable");
|
||||
gate_all!(box_syntax, "box expression syntax is experimental; you can call `Box::new` instead");
|
||||
// To avoid noise about type ascription in common syntax errors,
|
||||
// only emit if it is the *only* error. (Also check it last.)
|
||||
if sess.parse_sess.span_diagnostic.err_count() == 0 {
|
||||
gate_all!(type_ascription, "type ascription is experimental");
|
||||
}
|
||||
|
||||
visit::walk_crate(&mut visitor, krate);
|
||||
}
|
||||
|
|
|
@ -8,10 +8,12 @@
|
|||
#![feature(box_patterns)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(iter_is_partitioned)]
|
||||
#![feature(let_chains)]
|
||||
#![feature(let_else)]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
pub mod ast_validation;
|
||||
mod errors;
|
||||
pub mod feature_gate;
|
||||
pub mod node_count;
|
||||
pub mod show_span;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
#![feature(associated_type_bounds)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(with_negative_coherence)]
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
use rustc_ast as ast;
|
||||
use rustc_ast::{Attribute, Lit, LitKind, MetaItem, MetaItemKind, NestedMetaItem, NodeId};
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_errors::{struct_span_err, Applicability};
|
||||
use rustc_feature::{find_gated_cfg, is_builtin_attr_name, Features, GatedCfg};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use rustc_session::lint::builtin::UNEXPECTED_CFGS;
|
||||
|
@ -14,6 +13,8 @@ use rustc_span::hygiene::Transparency;
|
|||
use rustc_span::{symbol::sym, symbol::Symbol, Span};
|
||||
use std::num::NonZeroU32;
|
||||
|
||||
use crate::session_diagnostics::{self, IncorrectReprFormatGenericCause};
|
||||
|
||||
pub fn is_builtin_attr(attr: &Attribute) -> bool {
|
||||
attr.is_doc_comment() || attr.ident().filter(|ident| is_builtin_attr_name(ident.name)).is_some()
|
||||
}
|
||||
|
@ -25,46 +26,38 @@ enum AttrError {
|
|||
NonIdentFeature,
|
||||
MissingFeature,
|
||||
MultipleStabilityLevels,
|
||||
UnsupportedLiteral(&'static str, /* is_bytestr */ bool),
|
||||
UnsupportedLiteral(UnsupportedLiteralReason, /* is_bytestr */ bool),
|
||||
}
|
||||
|
||||
pub(crate) enum UnsupportedLiteralReason {
|
||||
Generic,
|
||||
CfgString,
|
||||
DeprecatedString,
|
||||
DeprecatedKvPair,
|
||||
}
|
||||
|
||||
fn handle_errors(sess: &ParseSess, span: Span, error: AttrError) {
|
||||
let diag = &sess.span_diagnostic;
|
||||
match error {
|
||||
AttrError::MultipleItem(item) => {
|
||||
struct_span_err!(diag, span, E0538, "multiple '{}' items", item).emit();
|
||||
sess.emit_err(session_diagnostics::MultipleItem { span, item });
|
||||
}
|
||||
AttrError::UnknownMetaItem(item, expected) => {
|
||||
let expected = expected.iter().map(|name| format!("`{}`", name)).collect::<Vec<_>>();
|
||||
struct_span_err!(diag, span, E0541, "unknown meta item '{}'", item)
|
||||
.span_label(span, format!("expected one of {}", expected.join(", ")))
|
||||
.emit();
|
||||
sess.emit_err(session_diagnostics::UnknownMetaItem { span, item, expected });
|
||||
}
|
||||
AttrError::MissingSince => {
|
||||
struct_span_err!(diag, span, E0542, "missing 'since'").emit();
|
||||
sess.emit_err(session_diagnostics::MissingSince { span });
|
||||
}
|
||||
AttrError::NonIdentFeature => {
|
||||
struct_span_err!(diag, span, E0546, "'feature' is not an identifier").emit();
|
||||
sess.emit_err(session_diagnostics::NonIdentFeature { span });
|
||||
}
|
||||
AttrError::MissingFeature => {
|
||||
struct_span_err!(diag, span, E0546, "missing 'feature'").emit();
|
||||
sess.emit_err(session_diagnostics::MissingFeature { span });
|
||||
}
|
||||
AttrError::MultipleStabilityLevels => {
|
||||
struct_span_err!(diag, span, E0544, "multiple stability levels").emit();
|
||||
sess.emit_err(session_diagnostics::MultipleStabilityLevels { span });
|
||||
}
|
||||
AttrError::UnsupportedLiteral(msg, is_bytestr) => {
|
||||
let mut err = struct_span_err!(diag, span, E0565, "{}", msg);
|
||||
if is_bytestr {
|
||||
if let Ok(lint_str) = sess.source_map().span_to_snippet(span) {
|
||||
err.span_suggestion(
|
||||
span,
|
||||
"consider removing the prefix",
|
||||
&lint_str[1..],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
err.emit();
|
||||
AttrError::UnsupportedLiteral(reason, is_bytestr) => {
|
||||
sess.emit_err(session_diagnostics::UnsupportedLiteral { span, reason, is_bytestr });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -243,8 +236,6 @@ where
|
|||
let mut promotable = false;
|
||||
let mut allowed_through_unstable_modules = false;
|
||||
|
||||
let diagnostic = &sess.parse_sess.span_diagnostic;
|
||||
|
||||
'outer: for attr in attrs_iter {
|
||||
if ![
|
||||
sym::rustc_const_unstable,
|
||||
|
@ -284,7 +275,7 @@ where
|
|||
*item = Some(v);
|
||||
true
|
||||
} else {
|
||||
struct_span_err!(diagnostic, meta.span, E0539, "incorrect meta item").emit();
|
||||
sess.emit_err(session_diagnostics::IncorrectMetaItem { span: meta.span });
|
||||
false
|
||||
}
|
||||
};
|
||||
|
@ -326,7 +317,7 @@ where
|
|||
handle_errors(
|
||||
&sess.parse_sess,
|
||||
meta.span(),
|
||||
AttrError::UnsupportedLiteral("unsupported literal", false),
|
||||
AttrError::UnsupportedLiteral(UnsupportedLiteralReason::Generic, false),
|
||||
);
|
||||
continue 'outer;
|
||||
};
|
||||
|
@ -350,39 +341,28 @@ where
|
|||
// is a name/value pair string literal.
|
||||
issue_num = match issue.unwrap().as_str() {
|
||||
"none" => None,
|
||||
issue => {
|
||||
let emit_diag = |msg: &str| {
|
||||
struct_span_err!(
|
||||
diagnostic,
|
||||
mi.span,
|
||||
E0545,
|
||||
"`issue` must be a non-zero numeric string \
|
||||
or \"none\"",
|
||||
)
|
||||
.span_label(mi.name_value_literal_span().unwrap(), msg)
|
||||
.emit();
|
||||
};
|
||||
match issue.parse() {
|
||||
Ok(0) => {
|
||||
emit_diag(
|
||||
"`issue` must not be \"0\", \
|
||||
use \"none\" instead",
|
||||
issue => match issue.parse::<NonZeroU32>() {
|
||||
Ok(num) => Some(num),
|
||||
Err(err) => {
|
||||
sess.emit_err(
|
||||
session_diagnostics::InvalidIssueString {
|
||||
span: mi.span,
|
||||
cause: session_diagnostics::InvalidIssueStringCause::from_int_error_kind(
|
||||
mi.name_value_literal_span().unwrap(),
|
||||
err.kind(),
|
||||
),
|
||||
},
|
||||
);
|
||||
continue 'outer;
|
||||
}
|
||||
Ok(num) => NonZeroU32::new(num),
|
||||
Err(err) => {
|
||||
emit_diag(&err.to_string());
|
||||
continue 'outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
sym::soft => {
|
||||
if !mi.is_word() {
|
||||
let msg = "`soft` should not have any arguments";
|
||||
sess.parse_sess.span_diagnostic.span_err(mi.span, msg);
|
||||
sess.emit_err(session_diagnostics::SoftNoArgs {
|
||||
span: mi.span,
|
||||
});
|
||||
}
|
||||
is_soft = true;
|
||||
}
|
||||
|
@ -440,8 +420,7 @@ where
|
|||
continue;
|
||||
}
|
||||
_ => {
|
||||
struct_span_err!(diagnostic, attr.span, E0547, "missing 'issue'")
|
||||
.emit();
|
||||
sess.emit_err(session_diagnostics::MissingIssue { span: attr.span });
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -494,7 +473,10 @@ where
|
|||
handle_errors(
|
||||
&sess.parse_sess,
|
||||
lit.span,
|
||||
AttrError::UnsupportedLiteral("unsupported literal", false),
|
||||
AttrError::UnsupportedLiteral(
|
||||
UnsupportedLiteralReason::Generic,
|
||||
false,
|
||||
),
|
||||
);
|
||||
continue 'outer;
|
||||
}
|
||||
|
@ -533,14 +515,7 @@ where
|
|||
if let Some((ref mut stab, _)) = const_stab {
|
||||
stab.promotable = promotable;
|
||||
} else {
|
||||
struct_span_err!(
|
||||
diagnostic,
|
||||
item_sp,
|
||||
E0717,
|
||||
"`rustc_promotable` attribute must be paired with either a `rustc_const_unstable` \
|
||||
or a `rustc_const_stable` attribute"
|
||||
)
|
||||
.emit();
|
||||
sess.emit_err(session_diagnostics::RustcPromotablePairing { span: item_sp });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -555,13 +530,7 @@ where
|
|||
{
|
||||
*allowed_through_unstable_modules = true;
|
||||
} else {
|
||||
struct_span_err!(
|
||||
diagnostic,
|
||||
item_sp,
|
||||
E0789,
|
||||
"`rustc_allowed_through_unstable_modules` attribute must be paired with a `stable` attribute"
|
||||
)
|
||||
.emit();
|
||||
sess.emit_err(session_diagnostics::RustcAllowedUnstablePairing { span: item_sp });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -675,25 +644,18 @@ pub fn eval_condition(
|
|||
NestedMetaItem::Literal(Lit { span, .. })
|
||||
| NestedMetaItem::MetaItem(MetaItem { span, .. }),
|
||||
] => {
|
||||
sess.span_diagnostic
|
||||
.struct_span_err(*span, "expected a version literal")
|
||||
.emit();
|
||||
sess.emit_err(session_diagnostics::ExpectedVersionLiteral { span: *span });
|
||||
return false;
|
||||
}
|
||||
[..] => {
|
||||
sess.span_diagnostic
|
||||
.struct_span_err(cfg.span, "expected single version literal")
|
||||
.emit();
|
||||
sess.emit_err(session_diagnostics::ExpectedSingleVersionLiteral {
|
||||
span: cfg.span,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
};
|
||||
let Some(min_version) = parse_version(min_version.as_str(), false) else {
|
||||
sess.span_diagnostic
|
||||
.struct_span_warn(
|
||||
*span,
|
||||
"unknown version literal format, assuming it refers to a future version",
|
||||
)
|
||||
.emit();
|
||||
sess.emit_warning(session_diagnostics::UnknownVersionLiteral { span: *span });
|
||||
return false;
|
||||
};
|
||||
let rustc_version = parse_version(env!("CFG_RELEASE"), true).unwrap();
|
||||
|
@ -711,7 +673,7 @@ pub fn eval_condition(
|
|||
handle_errors(
|
||||
sess,
|
||||
mi.span(),
|
||||
AttrError::UnsupportedLiteral("unsupported literal", false),
|
||||
AttrError::UnsupportedLiteral(UnsupportedLiteralReason::Generic, false),
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
@ -736,13 +698,9 @@ pub fn eval_condition(
|
|||
}),
|
||||
sym::not => {
|
||||
if mis.len() != 1 {
|
||||
struct_span_err!(
|
||||
sess.span_diagnostic,
|
||||
cfg.span,
|
||||
E0536,
|
||||
"expected 1 cfg-pattern"
|
||||
)
|
||||
.emit();
|
||||
sess.emit_err(session_diagnostics::ExpectedOneCfgPattern {
|
||||
span: cfg.span,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -768,21 +726,16 @@ pub fn eval_condition(
|
|||
})
|
||||
}
|
||||
_ => {
|
||||
struct_span_err!(
|
||||
sess.span_diagnostic,
|
||||
cfg.span,
|
||||
E0537,
|
||||
"invalid predicate `{}`",
|
||||
pprust::path_to_string(&cfg.path)
|
||||
)
|
||||
.emit();
|
||||
sess.emit_err(session_diagnostics::InvalidPredicate {
|
||||
span: cfg.span,
|
||||
predicate: pprust::path_to_string(&cfg.path),
|
||||
});
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
ast::MetaItemKind::Word | MetaItemKind::NameValue(..) if cfg.path.segments.len() != 1 => {
|
||||
sess.span_diagnostic
|
||||
.span_err(cfg.path.span, "`cfg` predicate key must be an identifier");
|
||||
sess.emit_err(session_diagnostics::CfgPredicateIdentifier { span: cfg.path.span });
|
||||
true
|
||||
}
|
||||
MetaItemKind::NameValue(ref lit) if !lit.kind.is_str() => {
|
||||
|
@ -790,7 +743,7 @@ pub fn eval_condition(
|
|||
sess,
|
||||
lit.span,
|
||||
AttrError::UnsupportedLiteral(
|
||||
"literal in `cfg` predicate value must be a string",
|
||||
UnsupportedLiteralReason::CfgString,
|
||||
lit.kind.is_bytestr(),
|
||||
),
|
||||
);
|
||||
|
@ -834,7 +787,6 @@ where
|
|||
I: Iterator<Item = &'a Attribute>,
|
||||
{
|
||||
let mut depr: Option<(Deprecation, Span)> = None;
|
||||
let diagnostic = &sess.parse_sess.span_diagnostic;
|
||||
let is_rustc = sess.features_untracked().staged_api;
|
||||
|
||||
'outer: for attr in attrs_iter {
|
||||
|
@ -870,14 +822,14 @@ where
|
|||
&sess.parse_sess,
|
||||
lit.span,
|
||||
AttrError::UnsupportedLiteral(
|
||||
"literal in `deprecated` \
|
||||
value must be a string",
|
||||
UnsupportedLiteralReason::DeprecatedString,
|
||||
lit.kind.is_bytestr(),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
struct_span_err!(diagnostic, meta.span, E0551, "incorrect meta item")
|
||||
.emit();
|
||||
sess.emit_err(session_diagnostics::IncorrectMetaItem2 {
|
||||
span: meta.span,
|
||||
});
|
||||
}
|
||||
|
||||
false
|
||||
|
@ -899,14 +851,11 @@ where
|
|||
}
|
||||
sym::suggestion => {
|
||||
if !sess.features_untracked().deprecated_suggestion {
|
||||
let mut diag = sess.struct_span_err(
|
||||
mi.span,
|
||||
"suggestions on deprecated items are unstable",
|
||||
);
|
||||
if sess.is_nightly_build() {
|
||||
diag.help("add `#![feature(deprecated_suggestion)]` to the crate root");
|
||||
}
|
||||
diag.note("see #94785 for more details").emit();
|
||||
sess.emit_err(session_diagnostics::DeprecatedItemSuggestion {
|
||||
span: mi.span,
|
||||
is_nightly: sess.is_nightly_build().then_some(()),
|
||||
details: (),
|
||||
});
|
||||
}
|
||||
|
||||
if !get(mi, &mut suggestion) {
|
||||
|
@ -934,7 +883,7 @@ where
|
|||
&sess.parse_sess,
|
||||
lit.span,
|
||||
AttrError::UnsupportedLiteral(
|
||||
"item in `deprecated` must be a key/value pair",
|
||||
UnsupportedLiteralReason::DeprecatedKvPair,
|
||||
false,
|
||||
),
|
||||
);
|
||||
|
@ -952,7 +901,7 @@ where
|
|||
}
|
||||
|
||||
if note.is_none() {
|
||||
struct_span_err!(diagnostic, attr.span, E0543, "missing 'note'").emit();
|
||||
sess.emit_err(session_diagnostics::MissingNote { span: attr.span });
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -1022,19 +971,9 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
|
|||
sym::simd => Some(ReprSimd),
|
||||
sym::transparent => Some(ReprTransparent),
|
||||
sym::align => {
|
||||
let mut err = struct_span_err!(
|
||||
diagnostic,
|
||||
item.span(),
|
||||
E0589,
|
||||
"invalid `repr(align)` attribute: `align` needs an argument"
|
||||
);
|
||||
err.span_suggestion(
|
||||
item.span(),
|
||||
"supply an argument here",
|
||||
"align(...)",
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
err.emit();
|
||||
sess.emit_err(session_diagnostics::InvalidReprAlignNeedArg {
|
||||
span: item.span(),
|
||||
});
|
||||
recognised = true;
|
||||
None
|
||||
}
|
||||
|
@ -1063,57 +1002,32 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
|
|||
|| int_type_of_word(name).is_some()
|
||||
{
|
||||
recognised = true;
|
||||
struct_span_err!(
|
||||
diagnostic,
|
||||
item.span(),
|
||||
E0552,
|
||||
"invalid representation hint: `{}` does not take a parenthesized argument list",
|
||||
name.to_ident_string(),
|
||||
).emit();
|
||||
sess.emit_err(session_diagnostics::InvalidReprHintNoParen {
|
||||
span: item.span(),
|
||||
name: name.to_ident_string(),
|
||||
});
|
||||
}
|
||||
if let Some(literal_error) = literal_error {
|
||||
struct_span_err!(
|
||||
diagnostic,
|
||||
item.span(),
|
||||
E0589,
|
||||
"invalid `repr({})` attribute: {}",
|
||||
name.to_ident_string(),
|
||||
literal_error
|
||||
)
|
||||
.emit();
|
||||
sess.emit_err(session_diagnostics::InvalidReprGeneric {
|
||||
span: item.span(),
|
||||
repr_arg: name.to_ident_string(),
|
||||
error_part: literal_error,
|
||||
});
|
||||
}
|
||||
} else if let Some(meta_item) = item.meta_item() {
|
||||
if let MetaItemKind::NameValue(ref value) = meta_item.kind {
|
||||
if meta_item.has_name(sym::align) || meta_item.has_name(sym::packed) {
|
||||
let name = meta_item.name_or_empty().to_ident_string();
|
||||
recognised = true;
|
||||
let mut err = struct_span_err!(
|
||||
diagnostic,
|
||||
sess.emit_err(session_diagnostics::IncorrectReprFormatGeneric {
|
||||
span: item.span(),
|
||||
repr_arg: &name,
|
||||
cause: IncorrectReprFormatGenericCause::from_lit_kind(
|
||||
item.span(),
|
||||
E0693,
|
||||
"incorrect `repr({})` attribute format",
|
||||
name,
|
||||
);
|
||||
match value.kind {
|
||||
ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => {
|
||||
err.span_suggestion(
|
||||
item.span(),
|
||||
"use parentheses instead",
|
||||
format!("{}({})", name, int),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
ast::LitKind::Str(s, _) => {
|
||||
err.span_suggestion(
|
||||
item.span(),
|
||||
"use parentheses instead",
|
||||
format!("{}({})", name, s),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
err.emit();
|
||||
&value.kind,
|
||||
&name,
|
||||
),
|
||||
});
|
||||
} else {
|
||||
if matches!(
|
||||
meta_item.name_or_empty(),
|
||||
|
@ -1121,51 +1035,33 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
|
|||
) || int_type_of_word(meta_item.name_or_empty()).is_some()
|
||||
{
|
||||
recognised = true;
|
||||
struct_span_err!(
|
||||
diagnostic,
|
||||
meta_item.span,
|
||||
E0552,
|
||||
"invalid representation hint: `{}` does not take a value",
|
||||
meta_item.name_or_empty().to_ident_string(),
|
||||
)
|
||||
.emit();
|
||||
sess.emit_err(session_diagnostics::InvalidReprHintNoValue {
|
||||
span: meta_item.span,
|
||||
name: meta_item.name_or_empty().to_ident_string(),
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if let MetaItemKind::List(_) = meta_item.kind {
|
||||
if meta_item.has_name(sym::align) {
|
||||
recognised = true;
|
||||
struct_span_err!(
|
||||
diagnostic,
|
||||
meta_item.span,
|
||||
E0693,
|
||||
"incorrect `repr(align)` attribute format: \
|
||||
`align` takes exactly one argument in parentheses"
|
||||
)
|
||||
.emit();
|
||||
sess.emit_err(session_diagnostics::IncorrectReprFormatAlignOneArg {
|
||||
span: meta_item.span,
|
||||
});
|
||||
} else if meta_item.has_name(sym::packed) {
|
||||
recognised = true;
|
||||
struct_span_err!(
|
||||
diagnostic,
|
||||
meta_item.span,
|
||||
E0552,
|
||||
"incorrect `repr(packed)` attribute format: \
|
||||
`packed` takes exactly one parenthesized argument, \
|
||||
or no parentheses at all"
|
||||
)
|
||||
.emit();
|
||||
sess.emit_err(session_diagnostics::IncorrectReprFormatPackedOneOrZeroArg {
|
||||
span: meta_item.span,
|
||||
});
|
||||
} else if matches!(
|
||||
meta_item.name_or_empty(),
|
||||
sym::C | sym::simd | sym::transparent
|
||||
) || int_type_of_word(meta_item.name_or_empty()).is_some()
|
||||
{
|
||||
recognised = true;
|
||||
struct_span_err!(
|
||||
diagnostic,
|
||||
meta_item.span,
|
||||
E0552,
|
||||
"invalid representation hint: `{}` does not take a parenthesized argument list",
|
||||
meta_item.name_or_empty().to_ident_string(),
|
||||
).emit();
|
||||
sess.emit_err(session_diagnostics::InvalidReprHintNoParen {
|
||||
span: meta_item.span,
|
||||
name: meta_item.name_or_empty().to_ident_string(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1262,10 +1158,10 @@ fn allow_unstable<'a>(
|
|||
let list = attrs
|
||||
.filter_map(move |attr| {
|
||||
attr.meta_item_list().or_else(|| {
|
||||
sess.diagnostic().span_err(
|
||||
attr.span,
|
||||
&format!("`{}` expects a list of feature names", symbol.to_ident_string()),
|
||||
);
|
||||
sess.emit_err(session_diagnostics::ExpectsFeatureList {
|
||||
span: attr.span,
|
||||
name: symbol.to_ident_string(),
|
||||
});
|
||||
None
|
||||
})
|
||||
})
|
||||
|
@ -1274,10 +1170,10 @@ fn allow_unstable<'a>(
|
|||
list.into_iter().filter_map(move |it| {
|
||||
let name = it.ident().map(|ident| ident.name);
|
||||
if name.is_none() {
|
||||
sess.diagnostic().span_err(
|
||||
it.span(),
|
||||
&format!("`{}` expects feature names", symbol.to_ident_string()),
|
||||
);
|
||||
sess.emit_err(session_diagnostics::ExpectsFeatures {
|
||||
span: it.span(),
|
||||
name: symbol.to_ident_string(),
|
||||
});
|
||||
}
|
||||
name
|
||||
})
|
||||
|
|
|
@ -4,12 +4,16 @@
|
|||
//! The goal is to move the definition of `MetaItem` and things that don't need to be in `syntax`
|
||||
//! to this crate.
|
||||
|
||||
#![feature(let_chains)]
|
||||
#![feature(let_else)]
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate rustc_macros;
|
||||
|
||||
mod builtin;
|
||||
mod session_diagnostics;
|
||||
|
||||
pub use builtin::*;
|
||||
pub use IntType::*;
|
||||
|
|
395
compiler/rustc_attr/src/session_diagnostics.rs
Normal file
395
compiler/rustc_attr/src/session_diagnostics.rs
Normal file
|
@ -0,0 +1,395 @@
|
|||
use std::num::IntErrorKind;
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_errors::{error_code, fluent, Applicability, DiagnosticBuilder, ErrorGuaranteed};
|
||||
use rustc_macros::SessionDiagnostic;
|
||||
use rustc_session::{parse::ParseSess, SessionDiagnostic};
|
||||
use rustc_span::{Span, Symbol};
|
||||
|
||||
use crate::UnsupportedLiteralReason;
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(attr::expected_one_cfg_pattern, code = "E0536")]
|
||||
pub(crate) struct ExpectedOneCfgPattern {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(attr::invalid_predicate, code = "E0537")]
|
||||
pub(crate) struct InvalidPredicate {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
|
||||
pub predicate: String,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(attr::multiple_item, code = "E0538")]
|
||||
pub(crate) struct MultipleItem {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
|
||||
pub item: String,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(attr::incorrect_meta_item, code = "E0539")]
|
||||
pub(crate) struct IncorrectMetaItem {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
// Error code: E0541
|
||||
pub(crate) struct UnknownMetaItem<'a> {
|
||||
pub span: Span,
|
||||
pub item: String,
|
||||
pub expected: &'a [&'a str],
|
||||
}
|
||||
|
||||
// Manual implementation to be able to format `expected` items correctly.
|
||||
impl<'a> SessionDiagnostic<'a> for UnknownMetaItem<'_> {
|
||||
fn into_diagnostic(self, sess: &'a ParseSess) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
|
||||
let expected = self.expected.iter().map(|name| format!("`{}`", name)).collect::<Vec<_>>();
|
||||
let mut diag = sess.span_diagnostic.struct_span_err_with_code(
|
||||
self.span,
|
||||
fluent::attr::unknown_meta_item,
|
||||
error_code!(E0541),
|
||||
);
|
||||
diag.set_arg("item", self.item);
|
||||
diag.set_arg("expected", expected.join(", "));
|
||||
diag.span_label(self.span, fluent::attr::label);
|
||||
diag
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(attr::missing_since, code = "E0542")]
|
||||
pub(crate) struct MissingSince {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(attr::missing_note, code = "E0543")]
|
||||
pub(crate) struct MissingNote {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(attr::multiple_stability_levels, code = "E0544")]
|
||||
pub(crate) struct MultipleStabilityLevels {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(attr::invalid_issue_string, code = "E0545")]
|
||||
pub(crate) struct InvalidIssueString {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
|
||||
#[subdiagnostic]
|
||||
pub cause: Option<InvalidIssueStringCause>,
|
||||
}
|
||||
|
||||
// The error kinds of `IntErrorKind` are duplicated here in order to allow the messages to be
|
||||
// translatable.
|
||||
#[derive(SessionSubdiagnostic)]
|
||||
pub(crate) enum InvalidIssueStringCause {
|
||||
#[label(attr::must_not_be_zero)]
|
||||
MustNotBeZero {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
|
||||
#[label(attr::empty)]
|
||||
Empty {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
|
||||
#[label(attr::invalid_digit)]
|
||||
InvalidDigit {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
|
||||
#[label(attr::pos_overflow)]
|
||||
PosOverflow {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
|
||||
#[label(attr::neg_overflow)]
|
||||
NegOverflow {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
}
|
||||
|
||||
impl InvalidIssueStringCause {
|
||||
pub fn from_int_error_kind(span: Span, kind: &IntErrorKind) -> Option<Self> {
|
||||
match kind {
|
||||
IntErrorKind::Empty => Some(Self::Empty { span }),
|
||||
IntErrorKind::InvalidDigit => Some(Self::InvalidDigit { span }),
|
||||
IntErrorKind::PosOverflow => Some(Self::PosOverflow { span }),
|
||||
IntErrorKind::NegOverflow => Some(Self::NegOverflow { span }),
|
||||
IntErrorKind::Zero => Some(Self::MustNotBeZero { span }),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(attr::missing_feature, code = "E0546")]
|
||||
pub(crate) struct MissingFeature {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(attr::non_ident_feature, code = "E0546")]
|
||||
pub(crate) struct NonIdentFeature {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(attr::missing_issue, code = "E0547")]
|
||||
pub(crate) struct MissingIssue {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
// FIXME: This diagnostic is identical to `IncorrectMetaItem`, barring the error code. Consider
|
||||
// changing this to `IncorrectMetaItem`. See #51489.
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(attr::incorrect_meta_item, code = "E0551")]
|
||||
pub(crate) struct IncorrectMetaItem2 {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
// FIXME: Why is this the same error code as `InvalidReprHintNoParen` and `InvalidReprHintNoValue`?
|
||||
// It is more similar to `IncorrectReprFormatGeneric`.
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(attr::incorrect_repr_format_packed_one_or_zero_arg, code = "E0552")]
|
||||
pub(crate) struct IncorrectReprFormatPackedOneOrZeroArg {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(attr::invalid_repr_hint_no_paren, code = "E0552")]
|
||||
pub(crate) struct InvalidReprHintNoParen {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(attr::invalid_repr_hint_no_value, code = "E0552")]
|
||||
pub(crate) struct InvalidReprHintNoValue {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
// Error code: E0565
|
||||
pub(crate) struct UnsupportedLiteral {
|
||||
pub span: Span,
|
||||
pub reason: UnsupportedLiteralReason,
|
||||
pub is_bytestr: bool,
|
||||
}
|
||||
|
||||
impl<'a> SessionDiagnostic<'a> for UnsupportedLiteral {
|
||||
fn into_diagnostic(self, sess: &'a ParseSess) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
|
||||
let mut diag = sess.span_diagnostic.struct_span_err_with_code(
|
||||
self.span,
|
||||
match self.reason {
|
||||
UnsupportedLiteralReason::Generic => fluent::attr::unsupported_literal_generic,
|
||||
UnsupportedLiteralReason::CfgString => fluent::attr::unsupported_literal_cfg_string,
|
||||
UnsupportedLiteralReason::DeprecatedString => {
|
||||
fluent::attr::unsupported_literal_deprecated_string
|
||||
}
|
||||
UnsupportedLiteralReason::DeprecatedKvPair => {
|
||||
fluent::attr::unsupported_literal_deprecated_kv_pair
|
||||
}
|
||||
},
|
||||
error_code!(E0565),
|
||||
);
|
||||
if self.is_bytestr {
|
||||
diag.span_suggestion(
|
||||
sess.source_map().start_point(self.span),
|
||||
fluent::attr::unsupported_literal_suggestion,
|
||||
"",
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
diag
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(attr::invalid_repr_align_need_arg, code = "E0589")]
|
||||
pub(crate) struct InvalidReprAlignNeedArg {
|
||||
#[primary_span]
|
||||
#[suggestion(code = "align(...)", applicability = "has-placeholders")]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(attr::invalid_repr_generic, code = "E0589")]
|
||||
pub(crate) struct InvalidReprGeneric<'a> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
|
||||
pub repr_arg: String,
|
||||
pub error_part: &'a str,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(attr::incorrect_repr_format_align_one_arg, code = "E0693")]
|
||||
pub(crate) struct IncorrectReprFormatAlignOneArg {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(attr::incorrect_repr_format_generic, code = "E0693")]
|
||||
pub(crate) struct IncorrectReprFormatGeneric<'a> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
|
||||
pub repr_arg: &'a str,
|
||||
|
||||
#[subdiagnostic]
|
||||
pub cause: Option<IncorrectReprFormatGenericCause<'a>>,
|
||||
}
|
||||
|
||||
#[derive(SessionSubdiagnostic)]
|
||||
pub(crate) enum IncorrectReprFormatGenericCause<'a> {
|
||||
#[suggestion(attr::suggestion, code = "{name}({int})", applicability = "machine-applicable")]
|
||||
Int {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
|
||||
#[skip_arg]
|
||||
name: &'a str,
|
||||
|
||||
#[skip_arg]
|
||||
int: u128,
|
||||
},
|
||||
|
||||
#[suggestion(
|
||||
attr::suggestion,
|
||||
code = "{name}({symbol})",
|
||||
applicability = "machine-applicable"
|
||||
)]
|
||||
Symbol {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
|
||||
#[skip_arg]
|
||||
name: &'a str,
|
||||
|
||||
#[skip_arg]
|
||||
symbol: Symbol,
|
||||
},
|
||||
}
|
||||
|
||||
impl<'a> IncorrectReprFormatGenericCause<'a> {
|
||||
pub fn from_lit_kind(span: Span, kind: &ast::LitKind, name: &'a str) -> Option<Self> {
|
||||
match kind {
|
||||
ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => {
|
||||
Some(Self::Int { span, name, int: *int })
|
||||
}
|
||||
ast::LitKind::Str(symbol, _) => Some(Self::Symbol { span, name, symbol: *symbol }),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(attr::rustc_promotable_pairing, code = "E0717")]
|
||||
pub(crate) struct RustcPromotablePairing {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(attr::rustc_allowed_unstable_pairing, code = "E0789")]
|
||||
pub(crate) struct RustcAllowedUnstablePairing {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(attr::cfg_predicate_identifier)]
|
||||
pub(crate) struct CfgPredicateIdentifier {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(attr::deprecated_item_suggestion)]
|
||||
pub(crate) struct DeprecatedItemSuggestion {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
|
||||
#[help]
|
||||
pub is_nightly: Option<()>,
|
||||
|
||||
#[note]
|
||||
pub details: (),
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(attr::expected_single_version_literal)]
|
||||
pub(crate) struct ExpectedSingleVersionLiteral {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(attr::expected_version_literal)]
|
||||
pub(crate) struct ExpectedVersionLiteral {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(attr::expects_feature_list)]
|
||||
pub(crate) struct ExpectsFeatureList {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(attr::expects_features)]
|
||||
pub(crate) struct ExpectsFeatures {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(attr::soft_no_args)]
|
||||
pub(crate) struct SoftNoArgs {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(attr::unknown_version_literal)]
|
||||
pub(crate) struct UnknownVersionLiteral {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
|
@ -31,7 +31,7 @@ pub(super) fn generate_constraints<'cx, 'tcx>(
|
|||
body,
|
||||
};
|
||||
|
||||
for (bb, data) in body.basic_blocks().iter_enumerated() {
|
||||
for (bb, data) in body.basic_blocks.iter_enumerated() {
|
||||
cg.visit_basic_block_data(bb, data);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -105,8 +105,8 @@ impl<'tcx> fmt::Debug for OutlivesConstraint<'tcx> {
|
|||
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
formatter,
|
||||
"({:?}: {:?}) due to {:?} ({:?})",
|
||||
self.sup, self.sub, self.locations, self.variance_info
|
||||
"({:?}: {:?}) due to {:?} ({:?}) ({:?})",
|
||||
self.sup, self.sub, self.locations, self.variance_info, self.category,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,7 +143,7 @@ struct OutOfScopePrecomputer<'a, 'tcx> {
|
|||
impl<'a, 'tcx> OutOfScopePrecomputer<'a, 'tcx> {
|
||||
fn new(body: &'a Body<'tcx>, regioncx: &'a RegionInferenceContext<'tcx>) -> Self {
|
||||
OutOfScopePrecomputer {
|
||||
visited: BitSet::new_empty(body.basic_blocks().len()),
|
||||
visited: BitSet::new_empty(body.basic_blocks.len()),
|
||||
visit_stack: vec![],
|
||||
body,
|
||||
regioncx,
|
||||
|
|
|
@ -1119,6 +1119,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
/// short a lifetime. (But sometimes it is more useful to report
|
||||
/// it as a more direct conflict between the execution of a
|
||||
/// `Drop::drop` with an aliasing borrow.)
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
pub(crate) fn report_borrowed_value_does_not_live_long_enough(
|
||||
&mut self,
|
||||
location: Location,
|
||||
|
@ -1126,13 +1127,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
place_span: (Place<'tcx>, Span),
|
||||
kind: Option<WriteKind>,
|
||||
) {
|
||||
debug!(
|
||||
"report_borrowed_value_does_not_live_long_enough(\
|
||||
{:?}, {:?}, {:?}, {:?}\
|
||||
)",
|
||||
location, borrow, place_span, kind
|
||||
);
|
||||
|
||||
let drop_span = place_span.1;
|
||||
let root_place =
|
||||
self.prefixes(borrow.borrowed_place.as_ref(), PrefixSet::All).last().unwrap();
|
||||
|
@ -1189,10 +1183,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
let kind_place = kind.filter(|_| place_desc.is_some()).map(|k| (k, place_span.0));
|
||||
let explanation = self.explain_why_borrow_contains_point(location, &borrow, kind_place);
|
||||
|
||||
debug!(
|
||||
"report_borrowed_value_does_not_live_long_enough(place_desc: {:?}, explanation: {:?})",
|
||||
place_desc, explanation
|
||||
);
|
||||
debug!(?place_desc, ?explanation);
|
||||
|
||||
let err = match (place_desc, explanation) {
|
||||
// If the outlives constraint comes from inside the closure,
|
||||
// for example:
|
||||
|
@ -1464,6 +1456,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
err
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn report_temporary_value_does_not_live_long_enough(
|
||||
&mut self,
|
||||
location: Location,
|
||||
|
@ -1473,13 +1466,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
proper_span: Span,
|
||||
explanation: BorrowExplanation<'tcx>,
|
||||
) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
|
||||
debug!(
|
||||
"report_temporary_value_does_not_live_long_enough(\
|
||||
{:?}, {:?}, {:?}, {:?}\
|
||||
)",
|
||||
location, borrow, drop_span, proper_span
|
||||
);
|
||||
|
||||
if let BorrowExplanation::MustBeValidFor { category, span, from_closure: false, .. } =
|
||||
explanation
|
||||
{
|
||||
|
|
|
@ -273,13 +273,17 @@ impl<'tcx> BorrowExplanation<'tcx> {
|
|||
_ => {}
|
||||
}
|
||||
}
|
||||
pub(crate) fn add_lifetime_bound_suggestion_to_diagnostic(
|
||||
|
||||
fn add_lifetime_bound_suggestion_to_diagnostic(
|
||||
&self,
|
||||
err: &mut Diagnostic,
|
||||
category: &ConstraintCategory<'tcx>,
|
||||
span: Span,
|
||||
region_name: &RegionName,
|
||||
) {
|
||||
if !span.is_desugaring(DesugaringKind::OpaqueTy) {
|
||||
return;
|
||||
}
|
||||
if let ConstraintCategory::OpaqueType = category {
|
||||
let suggestable_name =
|
||||
if region_name.was_named() { region_name.name } else { kw::UnderscoreLifetime };
|
||||
|
@ -332,26 +336,22 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
/// - second half is the place being accessed
|
||||
///
|
||||
/// [d]: https://rust-lang.github.io/rfcs/2094-nll.html#leveraging-intuition-framing-errors-in-terms-of-points
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
pub(crate) fn explain_why_borrow_contains_point(
|
||||
&self,
|
||||
location: Location,
|
||||
borrow: &BorrowData<'tcx>,
|
||||
kind_place: Option<(WriteKind, Place<'tcx>)>,
|
||||
) -> BorrowExplanation<'tcx> {
|
||||
debug!(
|
||||
"explain_why_borrow_contains_point(location={:?}, borrow={:?}, kind_place={:?})",
|
||||
location, borrow, kind_place
|
||||
);
|
||||
|
||||
let regioncx = &self.regioncx;
|
||||
let body: &Body<'_> = &self.body;
|
||||
let tcx = self.infcx.tcx;
|
||||
|
||||
let borrow_region_vid = borrow.region;
|
||||
debug!("explain_why_borrow_contains_point: borrow_region_vid={:?}", borrow_region_vid);
|
||||
debug!(?borrow_region_vid);
|
||||
|
||||
let region_sub = self.regioncx.find_sub_region_live_at(borrow_region_vid, location);
|
||||
debug!("explain_why_borrow_contains_point: region_sub={:?}", region_sub);
|
||||
debug!(?region_sub);
|
||||
|
||||
match find_use::find(body, regioncx, tcx, region_sub, location) {
|
||||
Some(Cause::LiveVar(local, location)) => {
|
||||
|
@ -404,17 +404,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
opt_place_desc,
|
||||
}
|
||||
} else {
|
||||
debug!(
|
||||
"explain_why_borrow_contains_point: \
|
||||
Could not generate a region name"
|
||||
);
|
||||
debug!("Could not generate a region name");
|
||||
BorrowExplanation::Unexplained
|
||||
}
|
||||
} else {
|
||||
debug!(
|
||||
"explain_why_borrow_contains_point: \
|
||||
Could not generate an error region vid"
|
||||
);
|
||||
debug!("Could not generate an error region vid");
|
||||
BorrowExplanation::Unexplained
|
||||
}
|
||||
}
|
||||
|
@ -455,7 +449,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
return outmost_back_edge;
|
||||
}
|
||||
|
||||
let block = &self.body.basic_blocks()[location.block];
|
||||
let block = &self.body.basic_blocks[location.block];
|
||||
|
||||
if location.statement_index < block.statements.len() {
|
||||
let successor = location.successor_within_block();
|
||||
|
@ -514,7 +508,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
}
|
||||
|
||||
if loop_head.dominates(from, &self.dominators) {
|
||||
let block = &self.body.basic_blocks()[from.block];
|
||||
let block = &self.body.basic_blocks[from.block];
|
||||
|
||||
if from.statement_index < block.statements.len() {
|
||||
let successor = from.successor_within_block();
|
||||
|
@ -564,7 +558,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
UseSpans::PatUse(span)
|
||||
| UseSpans::OtherUse(span)
|
||||
| UseSpans::FnSelfUse { var_span: span, .. } => {
|
||||
let block = &self.body.basic_blocks()[location.block];
|
||||
let block = &self.body.basic_blocks[location.block];
|
||||
|
||||
let kind = if let Some(&Statement {
|
||||
kind: StatementKind::FakeRead(box (FakeReadCause::ForLet(_), _)),
|
||||
|
|
|
@ -1086,14 +1086,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
),
|
||||
);
|
||||
}
|
||||
if is_option_or_result && maybe_reinitialized_locations_is_empty {
|
||||
err.span_suggestion_verbose(
|
||||
fn_call_span.shrink_to_lo(),
|
||||
"consider calling `.as_ref()` to borrow the type's contents",
|
||||
"as_ref().",
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
// Avoid pointing to the same function in multiple different
|
||||
// error messages.
|
||||
if span != DUMMY_SP && self.fn_self_span_reported.insert(self_arg.span) {
|
||||
|
@ -1102,6 +1094,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
&format!("this function takes ownership of the receiver `self`, which moves {}", place_name)
|
||||
);
|
||||
}
|
||||
if is_option_or_result && maybe_reinitialized_locations_is_empty {
|
||||
err.span_label(
|
||||
var_span,
|
||||
"help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents",
|
||||
);
|
||||
}
|
||||
}
|
||||
// Other desugarings takes &self, which cannot cause a move
|
||||
_ => {}
|
||||
|
|
|
@ -88,7 +88,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
if let Some(StatementKind::Assign(box (
|
||||
place,
|
||||
Rvalue::Use(Operand::Move(move_from)),
|
||||
))) = self.body.basic_blocks()[location.block]
|
||||
))) = self.body.basic_blocks[location.block]
|
||||
.statements
|
||||
.get(location.statement_index)
|
||||
.map(|stmt| &stmt.kind)
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
use rustc_errors::{
|
||||
Applicability, Diagnostic, DiagnosticBuilder, EmissionGuarantee, ErrorGuaranteed,
|
||||
};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::intravisit::Visitor;
|
||||
use rustc_hir::Node;
|
||||
use rustc_middle::hir::map::Map;
|
||||
use rustc_middle::mir::{Mutability, Place, PlaceRef, ProjectionElem};
|
||||
|
@ -12,12 +16,11 @@ use rustc_middle::{
|
|||
};
|
||||
use rustc_span::source_map::DesugaringKind;
|
||||
use rustc_span::symbol::{kw, Symbol};
|
||||
use rustc_span::{BytePos, Span};
|
||||
use rustc_span::{sym, BytePos, Span};
|
||||
|
||||
use crate::diagnostics::BorrowedContentSource;
|
||||
use crate::MirBorrowckCtxt;
|
||||
use rustc_const_eval::util::collect_writes::FindAssignments;
|
||||
use rustc_errors::{Applicability, Diagnostic};
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub(crate) enum AccessKind {
|
||||
|
@ -614,6 +617,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
"trait `IndexMut` is required to modify indexed content, \
|
||||
but it is not implemented for `{ty}`",
|
||||
));
|
||||
self.suggest_map_index_mut_alternatives(ty, &mut err, span);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
@ -627,6 +631,127 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
self.buffer_error(err);
|
||||
}
|
||||
|
||||
fn suggest_map_index_mut_alternatives(
|
||||
&self,
|
||||
ty: Ty<'_>,
|
||||
err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>,
|
||||
span: Span,
|
||||
) {
|
||||
let Some(adt) = ty.ty_adt_def() else { return };
|
||||
let did = adt.did();
|
||||
if self.infcx.tcx.is_diagnostic_item(sym::HashMap, did)
|
||||
|| self.infcx.tcx.is_diagnostic_item(sym::BTreeMap, did)
|
||||
{
|
||||
struct V<'a, 'b, 'tcx, G: EmissionGuarantee> {
|
||||
assign_span: Span,
|
||||
err: &'a mut DiagnosticBuilder<'b, G>,
|
||||
ty: Ty<'tcx>,
|
||||
suggested: bool,
|
||||
}
|
||||
impl<'a, 'b: 'a, 'hir, 'tcx, G: EmissionGuarantee> Visitor<'hir> for V<'a, 'b, 'tcx, G> {
|
||||
fn visit_stmt(&mut self, stmt: &'hir hir::Stmt<'hir>) {
|
||||
hir::intravisit::walk_stmt(self, stmt);
|
||||
let expr = match stmt.kind {
|
||||
hir::StmtKind::Semi(expr) | hir::StmtKind::Expr(expr) => expr,
|
||||
hir::StmtKind::Local(hir::Local { init: Some(expr), .. }) => expr,
|
||||
_ => {
|
||||
return;
|
||||
}
|
||||
};
|
||||
if let hir::ExprKind::Assign(place, rv, _sp) = expr.kind
|
||||
&& let hir::ExprKind::Index(val, index) = place.kind
|
||||
&& (expr.span == self.assign_span || place.span == self.assign_span)
|
||||
{
|
||||
// val[index] = rv;
|
||||
// ---------- place
|
||||
self.err.multipart_suggestions(
|
||||
&format!(
|
||||
"to modify a `{}`, use `.get_mut()`, `.insert()` or the entry API",
|
||||
self.ty,
|
||||
),
|
||||
vec![
|
||||
vec![ // val.insert(index, rv);
|
||||
(
|
||||
val.span.shrink_to_hi().with_hi(index.span.lo()),
|
||||
".insert(".to_string(),
|
||||
),
|
||||
(
|
||||
index.span.shrink_to_hi().with_hi(rv.span.lo()),
|
||||
", ".to_string(),
|
||||
),
|
||||
(rv.span.shrink_to_hi(), ")".to_string()),
|
||||
],
|
||||
vec![ // val.get_mut(index).map(|v| { *v = rv; });
|
||||
(
|
||||
val.span.shrink_to_hi().with_hi(index.span.lo()),
|
||||
".get_mut(".to_string(),
|
||||
),
|
||||
(
|
||||
index.span.shrink_to_hi().with_hi(place.span.hi()),
|
||||
").map(|val| { *val".to_string(),
|
||||
),
|
||||
(
|
||||
rv.span.shrink_to_hi(),
|
||||
"; })".to_string(),
|
||||
),
|
||||
],
|
||||
vec![ // let x = val.entry(index).or_insert(rv);
|
||||
(val.span.shrink_to_lo(), "let val = ".to_string()),
|
||||
(
|
||||
val.span.shrink_to_hi().with_hi(index.span.lo()),
|
||||
".entry(".to_string(),
|
||||
),
|
||||
(
|
||||
index.span.shrink_to_hi().with_hi(rv.span.lo()),
|
||||
").or_insert(".to_string(),
|
||||
),
|
||||
(rv.span.shrink_to_hi(), ")".to_string()),
|
||||
],
|
||||
].into_iter(),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
self.suggested = true;
|
||||
} else if let hir::ExprKind::MethodCall(_path, args @ [_, ..], sp) = expr.kind
|
||||
&& let hir::ExprKind::Index(val, index) = args[0].kind
|
||||
&& expr.span == self.assign_span
|
||||
{
|
||||
// val[index].path(args..);
|
||||
self.err.multipart_suggestion(
|
||||
&format!("to modify a `{}` use `.get_mut()`", self.ty),
|
||||
vec![
|
||||
(
|
||||
val.span.shrink_to_hi().with_hi(index.span.lo()),
|
||||
".get_mut(".to_string(),
|
||||
),
|
||||
(
|
||||
index.span.shrink_to_hi().with_hi(args[0].span.hi()),
|
||||
").map(|val| val".to_string(),
|
||||
),
|
||||
(sp.shrink_to_hi(), ")".to_string()),
|
||||
],
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
self.suggested = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
let hir_map = self.infcx.tcx.hir();
|
||||
let def_id = self.body.source.def_id();
|
||||
let hir_id = hir_map.local_def_id_to_hir_id(def_id.as_local().unwrap());
|
||||
let node = hir_map.find(hir_id);
|
||||
let Some(hir::Node::Item(item)) = node else { return; };
|
||||
let hir::ItemKind::Fn(.., body_id) = item.kind else { return; };
|
||||
let body = self.infcx.tcx.hir().body(body_id);
|
||||
let mut v = V { assign_span: span, err, ty, suggested: false };
|
||||
v.visit_body(body);
|
||||
if !v.suggested {
|
||||
err.help(&format!(
|
||||
"to modify a `{ty}`, use `.get_mut()`, `.insert()` or the entry API",
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// User cannot make signature of a trait mutable without changing the
|
||||
/// trait. So we find if this error belongs to a trait and if so we move
|
||||
/// suggestion to the trait or disable it if it is out of scope of this crate
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
//! Error reporting machinery for lifetime errors.
|
||||
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
|
@ -23,7 +25,10 @@ use rustc_span::symbol::{kw, sym, Ident};
|
|||
use rustc_span::Span;
|
||||
|
||||
use crate::borrowck_errors;
|
||||
use crate::session_diagnostics::GenericDoesNotLiveLongEnough;
|
||||
use crate::session_diagnostics::{
|
||||
FnMutError, FnMutReturnTypeErr, GenericDoesNotLiveLongEnough, LifetimeOutliveErr,
|
||||
LifetimeReturnCategoryErr, RequireStaticErr, VarHereDenote,
|
||||
};
|
||||
|
||||
use super::{OutlivesSuggestionBuilder, RegionName};
|
||||
use crate::region_infer::BlameConstraint;
|
||||
|
@ -488,12 +493,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
|
||||
let ErrorConstraintInfo { outlived_fr, span, .. } = errci;
|
||||
|
||||
let mut diag = self
|
||||
.infcx
|
||||
.tcx
|
||||
.sess
|
||||
.struct_span_err(*span, "captured variable cannot escape `FnMut` closure body");
|
||||
|
||||
let mut output_ty = self.regioncx.universal_regions().unnormalized_output_ty;
|
||||
if let ty::Opaque(def_id, _) = *output_ty.kind() {
|
||||
output_ty = self.infcx.tcx.type_of(def_id)
|
||||
|
@ -501,19 +500,20 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
|
||||
debug!("report_fnmut_error: output_ty={:?}", output_ty);
|
||||
|
||||
let message = match output_ty.kind() {
|
||||
ty::Closure(_, _) => {
|
||||
"returns a closure that contains a reference to a captured variable, which then \
|
||||
escapes the closure body"
|
||||
let err = FnMutError {
|
||||
span: *span,
|
||||
ty_err: match output_ty.kind() {
|
||||
ty::Closure(_, _) => FnMutReturnTypeErr::ReturnClosure { span: *span },
|
||||
ty::Adt(def, _)
|
||||
if self.infcx.tcx.is_diagnostic_item(sym::gen_future, def.did()) =>
|
||||
{
|
||||
FnMutReturnTypeErr::ReturnAsyncBlock { span: *span }
|
||||
}
|
||||
ty::Adt(def, _) if self.infcx.tcx.is_diagnostic_item(sym::gen_future, def.did()) => {
|
||||
"returns an `async` block that contains a reference to a captured variable, which then \
|
||||
escapes the closure body"
|
||||
}
|
||||
_ => "returns a reference to a captured variable which escapes the closure body",
|
||||
_ => FnMutReturnTypeErr::ReturnRef { span: *span },
|
||||
},
|
||||
};
|
||||
|
||||
diag.span_label(*span, message);
|
||||
let mut diag = self.infcx.tcx.sess.create_err(err);
|
||||
|
||||
if let ReturnConstraint::ClosureUpvar(upvar_field) = kind {
|
||||
let def_id = match self.regioncx.universal_regions().defining_ty {
|
||||
|
@ -532,20 +532,15 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
let upvars_map = self.infcx.tcx.upvars_mentioned(def_id).unwrap();
|
||||
let upvar_def_span = self.infcx.tcx.hir().span(def_hir);
|
||||
let upvar_span = upvars_map.get(&def_hir).unwrap().span;
|
||||
diag.span_label(upvar_def_span, "variable defined here");
|
||||
diag.span_label(upvar_span, "variable captured here");
|
||||
diag.subdiagnostic(VarHereDenote::Defined { span: upvar_def_span });
|
||||
diag.subdiagnostic(VarHereDenote::Captured { span: upvar_span });
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(fr_span) = self.give_region_a_name(*outlived_fr).unwrap().span() {
|
||||
diag.span_label(fr_span, "inferred to be a `FnMut` closure");
|
||||
diag.subdiagnostic(VarHereDenote::FnMutInferred { span: fr_span });
|
||||
}
|
||||
|
||||
diag.note(
|
||||
"`FnMut` closures only have access to their captured variables while they are \
|
||||
executing...",
|
||||
);
|
||||
diag.note("...therefore, they cannot allow references to captured variables to escape");
|
||||
self.suggest_move_on_borrowing_closure(&mut diag);
|
||||
|
||||
diag
|
||||
|
@ -681,39 +676,33 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
..
|
||||
} = errci;
|
||||
|
||||
let mut diag =
|
||||
self.infcx.tcx.sess.struct_span_err(*span, "lifetime may not live long enough");
|
||||
|
||||
let (_, mir_def_name) =
|
||||
self.infcx.tcx.article_and_description(self.mir_def_id().to_def_id());
|
||||
|
||||
let err = LifetimeOutliveErr { span: *span };
|
||||
let mut diag = self.infcx.tcx.sess.create_err(err);
|
||||
|
||||
let fr_name = self.give_region_a_name(*fr).unwrap();
|
||||
fr_name.highlight_region_name(&mut diag);
|
||||
let outlived_fr_name = self.give_region_a_name(*outlived_fr).unwrap();
|
||||
outlived_fr_name.highlight_region_name(&mut diag);
|
||||
|
||||
match (category, outlived_fr_is_local, fr_is_local) {
|
||||
(ConstraintCategory::Return(_), true, _) => {
|
||||
diag.span_label(
|
||||
*span,
|
||||
format!(
|
||||
"{mir_def_name} was supposed to return data with lifetime `{outlived_fr_name}` but it is returning \
|
||||
data with lifetime `{fr_name}`",
|
||||
),
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
diag.span_label(
|
||||
*span,
|
||||
format!(
|
||||
"{}requires that `{}` must outlive `{}`",
|
||||
category.description(),
|
||||
fr_name,
|
||||
let err_category = match (category, outlived_fr_is_local, fr_is_local) {
|
||||
(ConstraintCategory::Return(_), true, _) => LifetimeReturnCategoryErr::WrongReturn {
|
||||
span: *span,
|
||||
mir_def_name,
|
||||
outlived_fr_name,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
fr_name: &fr_name,
|
||||
},
|
||||
_ => LifetimeReturnCategoryErr::ShortReturn {
|
||||
span: *span,
|
||||
category_desc: category.description(),
|
||||
free_region_name: &fr_name,
|
||||
outlived_fr_name,
|
||||
},
|
||||
};
|
||||
|
||||
diag.subdiagnostic(err_category);
|
||||
|
||||
self.add_static_impl_trait_suggestion(&mut diag, *fr, fr_name, *outlived_fr);
|
||||
self.suggest_adding_lifetime_params(&mut diag, *fr, *outlived_fr);
|
||||
|
@ -862,7 +851,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
ident.span,
|
||||
"calling this method introduces the `impl`'s 'static` requirement",
|
||||
);
|
||||
err.span_note(multi_span, "the used `impl` has a `'static` requirement");
|
||||
err.subdiagnostic(RequireStaticErr::UsedImpl { multi_span });
|
||||
err.span_suggestion_verbose(
|
||||
span.shrink_to_hi(),
|
||||
"consider relaxing the implicit `'static` requirement",
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#![allow(rustc::potential_query_instability)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(let_chains)]
|
||||
#![feature(let_else)]
|
||||
#![feature(min_specialization)]
|
||||
#![feature(never_type)]
|
||||
|
@ -18,7 +19,7 @@ extern crate tracing;
|
|||
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_data_structures::graph::dominators::Dominators;
|
||||
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
|
||||
use rustc_errors::{Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_index::bit_set::ChunkedBitSet;
|
||||
|
@ -50,6 +51,8 @@ use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult, MoveData, MoveE
|
|||
use rustc_mir_dataflow::Analysis;
|
||||
use rustc_mir_dataflow::MoveDataParamEnv;
|
||||
|
||||
use crate::session_diagnostics::VarNeedNotMut;
|
||||
|
||||
use self::diagnostics::{AccessKind, RegionName};
|
||||
use self::location::LocationTable;
|
||||
use self::prefixes::PrefixSet;
|
||||
|
@ -424,17 +427,9 @@ fn do_mir_borrowck<'a, 'tcx>(
|
|||
continue;
|
||||
}
|
||||
|
||||
tcx.struct_span_lint_hir(UNUSED_MUT, lint_root, span, |lint| {
|
||||
let mut_span = tcx.sess.source_map().span_until_non_whitespace(span);
|
||||
lint.build("variable does not need to be mutable")
|
||||
.span_suggestion_short(
|
||||
mut_span,
|
||||
"remove this `mut`",
|
||||
"",
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
.emit();
|
||||
})
|
||||
|
||||
tcx.emit_spanned_lint(UNUSED_MUT, lint_root, span, VarNeedNotMut { span: mut_span })
|
||||
}
|
||||
|
||||
let tainted_by_errors = mbcx.emit_errors();
|
||||
|
@ -981,6 +976,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self, flow_state))]
|
||||
fn check_access_for_conflict(
|
||||
&mut self,
|
||||
location: Location,
|
||||
|
@ -989,11 +985,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
rw: ReadOrWrite,
|
||||
flow_state: &Flows<'cx, 'tcx>,
|
||||
) -> bool {
|
||||
debug!(
|
||||
"check_access_for_conflict(location={:?}, place_span={:?}, sd={:?}, rw={:?})",
|
||||
location, place_span, sd, rw,
|
||||
);
|
||||
|
||||
let mut error_reported = false;
|
||||
let tcx = self.infcx.tcx;
|
||||
let body = self.body;
|
||||
|
@ -1457,13 +1448,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
|
||||
/// Checks whether a borrow of this place is invalidated when the function
|
||||
/// exits
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn check_for_invalidation_at_exit(
|
||||
&mut self,
|
||||
location: Location,
|
||||
borrow: &BorrowData<'tcx>,
|
||||
span: Span,
|
||||
) {
|
||||
debug!("check_for_invalidation_at_exit({:?})", borrow);
|
||||
let place = borrow.borrowed_place;
|
||||
let mut root_place = PlaceRef { local: place.local, projection: &[] };
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ impl LocationTable {
|
|||
pub(crate) fn new(body: &Body<'_>) -> Self {
|
||||
let mut num_points = 0;
|
||||
let statements_before_block = body
|
||||
.basic_blocks()
|
||||
.basic_blocks
|
||||
.iter()
|
||||
.map(|block_data| {
|
||||
let v = num_points;
|
||||
|
|
|
@ -44,6 +44,7 @@ pub(crate) fn places_conflict<'tcx>(
|
|||
/// access depth. The `bias` parameter is used to determine how the unknowable (comparing runtime
|
||||
/// array indices, for example) should be interpreted - this depends on what the caller wants in
|
||||
/// order to make the conservative choice and preserve soundness.
|
||||
#[instrument(level = "debug", skip(tcx, body))]
|
||||
pub(super) fn borrow_conflicts_with_place<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
|
@ -53,11 +54,6 @@ pub(super) fn borrow_conflicts_with_place<'tcx>(
|
|||
access: AccessDepth,
|
||||
bias: PlaceConflictBias,
|
||||
) -> bool {
|
||||
debug!(
|
||||
"borrow_conflicts_with_place({:?}, {:?}, {:?}, {:?})",
|
||||
borrow_place, access_place, access, bias,
|
||||
);
|
||||
|
||||
// This Local/Local case is handled by the more general code below, but
|
||||
// it's so common that it's a speed win to check for it first.
|
||||
if let Some(l1) = borrow_place.as_local() && let Some(l2) = access_place.as_local() {
|
||||
|
@ -140,10 +136,9 @@ fn place_components_conflict<'tcx>(
|
|||
for (i, (borrow_c, &access_c)) in
|
||||
iter::zip(borrow_place.projection, access_place.projection).enumerate()
|
||||
{
|
||||
debug!("borrow_conflicts_with_place: borrow_c = {:?}", borrow_c);
|
||||
let borrow_proj_base = &borrow_place.projection[..i];
|
||||
debug!(?borrow_c, ?access_c);
|
||||
|
||||
debug!("borrow_conflicts_with_place: access_c = {:?}", access_c);
|
||||
let borrow_proj_base = &borrow_place.projection[..i];
|
||||
|
||||
// Borrow and access path both have more components.
|
||||
//
|
||||
|
@ -180,7 +175,7 @@ fn place_components_conflict<'tcx>(
|
|||
// idea, at least for now, so just give up and
|
||||
// report a conflict. This is unsafe code anyway so
|
||||
// the user could always use raw pointers.
|
||||
debug!("borrow_conflicts_with_place: arbitrary -> conflict");
|
||||
debug!("arbitrary -> conflict");
|
||||
return true;
|
||||
}
|
||||
Overlap::EqualOrDisjoint => {
|
||||
|
@ -189,7 +184,7 @@ fn place_components_conflict<'tcx>(
|
|||
Overlap::Disjoint => {
|
||||
// We have proven the borrow disjoint - further
|
||||
// projections will remain disjoint.
|
||||
debug!("borrow_conflicts_with_place: disjoint");
|
||||
debug!("disjoint");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1167,8 +1167,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
/// Therefore, this method should only be used in diagnostic code,
|
||||
/// where displaying *some* named universal region is better than
|
||||
/// falling back to 'static.
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
pub(crate) fn approx_universal_upper_bound(&self, r: RegionVid) -> RegionVid {
|
||||
debug!("approx_universal_upper_bound(r={:?}={})", r, self.region_value_str(r));
|
||||
debug!("{}", self.region_value_str(r));
|
||||
|
||||
// Find the smallest universal region that contains all other
|
||||
// universal regions within `region`.
|
||||
|
@ -1177,7 +1178,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
let static_r = self.universal_regions.fr_static;
|
||||
for ur in self.scc_values.universal_regions_outlived_by(r_scc) {
|
||||
let new_lub = self.universal_region_relations.postdom_upper_bound(lub, ur);
|
||||
debug!("approx_universal_upper_bound: ur={:?} lub={:?} new_lub={:?}", ur, lub, new_lub);
|
||||
debug!(?ur, ?lub, ?new_lub);
|
||||
// The upper bound of two non-static regions is static: this
|
||||
// means we know nothing about the relationship between these
|
||||
// two regions. Pick a 'better' one to use when constructing
|
||||
|
@ -1201,7 +1202,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
debug!("approx_universal_upper_bound: r={:?} lub={:?}", r, lub);
|
||||
debug!(?r, ?lub);
|
||||
|
||||
lub
|
||||
}
|
||||
|
@ -2048,6 +2049,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
/// creating a constraint path that forces `R` to outlive
|
||||
/// `from_region`, and then finding the best choices within that
|
||||
/// path to blame.
|
||||
#[instrument(level = "debug", skip(self, target_test))]
|
||||
pub(crate) fn best_blame_constraint(
|
||||
&self,
|
||||
body: &Body<'tcx>,
|
||||
|
@ -2055,16 +2057,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
from_region_origin: NllRegionVariableOrigin,
|
||||
target_test: impl Fn(RegionVid) -> bool,
|
||||
) -> BlameConstraint<'tcx> {
|
||||
debug!(
|
||||
"best_blame_constraint(from_region={:?}, from_region_origin={:?})",
|
||||
from_region, from_region_origin
|
||||
);
|
||||
|
||||
// Find all paths
|
||||
let (path, target_region) =
|
||||
self.find_constraint_paths_between_regions(from_region, target_test).unwrap();
|
||||
debug!(
|
||||
"best_blame_constraint: path={:#?}",
|
||||
"path={:#?}",
|
||||
path.iter()
|
||||
.map(|c| format!(
|
||||
"{:?} ({:?}: {:?})",
|
||||
|
@ -2116,7 +2113,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
}
|
||||
})
|
||||
.collect();
|
||||
debug!("best_blame_constraint: categorized_path={:#?}", categorized_path);
|
||||
debug!("categorized_path={:#?}", categorized_path);
|
||||
|
||||
// To find the best span to cite, we first try to look for the
|
||||
// final constraint that is interesting and where the `sup` is
|
||||
|
@ -2214,10 +2211,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
let best_choice =
|
||||
if blame_source { range.rev().find(find_region) } else { range.find(find_region) };
|
||||
|
||||
debug!(
|
||||
"best_blame_constraint: best_choice={:?} blame_source={}",
|
||||
best_choice, blame_source
|
||||
);
|
||||
debug!(?best_choice, ?blame_source);
|
||||
|
||||
if let Some(i) = best_choice {
|
||||
if let Some(next) = categorized_path.get(i + 1) {
|
||||
|
@ -2254,7 +2248,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
// appears to be the most interesting point to report to the
|
||||
// user via an even more ad-hoc guess.
|
||||
categorized_path.sort_by(|p0, p1| p0.category.cmp(&p1.category));
|
||||
debug!("best_blame_constraint: sorted_path={:#?}", categorized_path);
|
||||
debug!("sorted_path={:#?}", categorized_path);
|
||||
|
||||
categorized_path.remove(0)
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@ use rustc_span::Span;
|
|||
use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
|
||||
use rustc_trait_selection::traits::TraitEngineExt as _;
|
||||
|
||||
use crate::session_diagnostics::ConstNotUsedTraitAlias;
|
||||
|
||||
use super::RegionInferenceContext;
|
||||
|
||||
impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
|
@ -639,17 +641,10 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
|||
Some(GenericArgKind::Const(c1)) => c1,
|
||||
Some(u) => panic!("const mapped to unexpected kind: {:?}", u),
|
||||
None => {
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_err(
|
||||
self.span,
|
||||
&format!(
|
||||
"const parameter `{}` is part of concrete type but not \
|
||||
used in parameter list for the `impl Trait` type alias",
|
||||
ct
|
||||
),
|
||||
)
|
||||
.emit();
|
||||
self.tcx.sess.emit_err(ConstNotUsedTraitAlias {
|
||||
ct: ct.to_string(),
|
||||
span: self.span,
|
||||
});
|
||||
|
||||
self.tcx().const_error(ct.ty())
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ impl RegionValueElements {
|
|||
pub(crate) fn new(body: &Body<'_>) -> Self {
|
||||
let mut num_points = 0;
|
||||
let statements_before_block: IndexVec<BasicBlock, usize> = body
|
||||
.basic_blocks()
|
||||
.basic_blocks
|
||||
.iter()
|
||||
.map(|block_data| {
|
||||
let v = num_points;
|
||||
|
@ -37,7 +37,7 @@ impl RegionValueElements {
|
|||
debug!("RegionValueElements: num_points={:#?}", num_points);
|
||||
|
||||
let mut basic_blocks = IndexVec::with_capacity(num_points);
|
||||
for (bb, bb_data) in body.basic_blocks().iter_enumerated() {
|
||||
for (bb, bb_data) in body.basic_blocks.iter_enumerated() {
|
||||
basic_blocks.extend((0..=bb_data.statements.len()).map(|_| bb));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic};
|
||||
use rustc_errors::{IntoDiagnosticArg, MultiSpan};
|
||||
use rustc_macros::{LintDiagnostic, SessionDiagnostic, SessionSubdiagnostic};
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_span::Span;
|
||||
|
||||
use crate::diagnostics::RegionName;
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(borrowck::move_unsized, code = "E0161")]
|
||||
#[diag(borrowck::move_unsized, code = "E0161")]
|
||||
pub(crate) struct MoveUnsized<'tcx> {
|
||||
pub ty: Ty<'tcx>,
|
||||
#[primary_span]
|
||||
|
@ -12,7 +15,7 @@ pub(crate) struct MoveUnsized<'tcx> {
|
|||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(borrowck::higher_ranked_lifetime_error)]
|
||||
#[diag(borrowck::higher_ranked_lifetime_error)]
|
||||
pub(crate) struct HigherRankedLifetimeError {
|
||||
#[subdiagnostic]
|
||||
pub cause: Option<HigherRankedErrorCause>,
|
||||
|
@ -29,16 +32,128 @@ pub(crate) enum HigherRankedErrorCause {
|
|||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(borrowck::higher_ranked_subtype_error)]
|
||||
#[diag(borrowck::higher_ranked_subtype_error)]
|
||||
pub(crate) struct HigherRankedSubtypeError {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(borrowck::generic_does_not_live_long_enough)]
|
||||
#[diag(borrowck::generic_does_not_live_long_enough)]
|
||||
pub(crate) struct GenericDoesNotLiveLongEnough {
|
||||
pub kind: String,
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(borrowck::var_does_not_need_mut)]
|
||||
pub(crate) struct VarNeedNotMut {
|
||||
#[suggestion_short(applicability = "machine-applicable", code = "")]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(borrowck::const_not_used_in_type_alias)]
|
||||
pub(crate) struct ConstNotUsedTraitAlias {
|
||||
pub ct: String,
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(borrowck::var_cannot_escape_closure)]
|
||||
#[note]
|
||||
#[note(borrowck::cannot_escape)]
|
||||
pub(crate) struct FnMutError {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[subdiagnostic]
|
||||
pub ty_err: FnMutReturnTypeErr,
|
||||
}
|
||||
|
||||
#[derive(SessionSubdiagnostic)]
|
||||
pub(crate) enum VarHereDenote {
|
||||
#[label(borrowck::var_here_captured)]
|
||||
Captured {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
#[label(borrowck::var_here_defined)]
|
||||
Defined {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
#[label(borrowck::closure_inferred_mut)]
|
||||
FnMutInferred {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(SessionSubdiagnostic)]
|
||||
pub(crate) enum FnMutReturnTypeErr {
|
||||
#[label(borrowck::returned_closure_escaped)]
|
||||
ReturnClosure {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
#[label(borrowck::returned_async_block_escaped)]
|
||||
ReturnAsyncBlock {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
#[label(borrowck::returned_ref_escaped)]
|
||||
ReturnRef {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[diag(borrowck::lifetime_constraints_error)]
|
||||
pub(crate) struct LifetimeOutliveErr {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(SessionSubdiagnostic)]
|
||||
pub(crate) enum LifetimeReturnCategoryErr<'a> {
|
||||
#[label(borrowck::returned_lifetime_wrong)]
|
||||
WrongReturn {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
mir_def_name: &'a str,
|
||||
outlived_fr_name: RegionName,
|
||||
fr_name: &'a RegionName,
|
||||
},
|
||||
#[label(borrowck::returned_lifetime_short)]
|
||||
ShortReturn {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
category_desc: &'static str,
|
||||
free_region_name: &'a RegionName,
|
||||
outlived_fr_name: RegionName,
|
||||
},
|
||||
}
|
||||
|
||||
impl IntoDiagnosticArg for &RegionName {
|
||||
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
|
||||
format!("{}", self).into_diagnostic_arg()
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoDiagnosticArg for RegionName {
|
||||
fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
|
||||
format!("{}", self).into_diagnostic_arg()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(SessionSubdiagnostic)]
|
||||
pub(crate) enum RequireStaticErr {
|
||||
#[note(borrowck::used_impl_require_static)]
|
||||
UsedImpl {
|
||||
#[primary_span]
|
||||
multi_span: MultiSpan,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
/// **Any `rustc_infer::infer` operations that might generate region
|
||||
/// constraints should occur within this method so that those
|
||||
/// constraints can be properly localized!**
|
||||
#[instrument(skip(self, category, op), level = "trace")]
|
||||
#[instrument(skip(self, op), level = "trace")]
|
||||
pub(super) fn fully_perform_op<R, Op>(
|
||||
&mut self,
|
||||
locations: Locations,
|
||||
|
@ -90,12 +90,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
locations: Locations,
|
||||
category: ConstraintCategory<'tcx>,
|
||||
) {
|
||||
self.prove_predicates(
|
||||
Some(ty::Binder::dummy(ty::PredicateKind::Trait(ty::TraitPredicate {
|
||||
self.prove_predicate(
|
||||
ty::Binder::dummy(ty::PredicateKind::Trait(ty::TraitPredicate {
|
||||
trait_ref,
|
||||
constness: ty::BoundConstness::NotConst,
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
}))),
|
||||
}))
|
||||
.to_predicate(self.tcx()),
|
||||
locations,
|
||||
category,
|
||||
);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use rustc_data_structures::frozen::Frozen;
|
||||
use rustc_data_structures::transitive_relation::TransitiveRelation;
|
||||
use rustc_data_structures::transitive_relation::{TransitiveRelation, TransitiveRelationBuilder};
|
||||
use rustc_infer::infer::canonical::QueryRegionConstraints;
|
||||
use rustc_infer::infer::outlives;
|
||||
use rustc_infer::infer::outlives::env::RegionBoundPairs;
|
||||
|
@ -61,25 +61,13 @@ pub(crate) fn create<'tcx>(
|
|||
constraints,
|
||||
universal_regions: universal_regions.clone(),
|
||||
region_bound_pairs: Default::default(),
|
||||
relations: UniversalRegionRelations {
|
||||
universal_regions: universal_regions.clone(),
|
||||
outlives: Default::default(),
|
||||
inverse_outlives: Default::default(),
|
||||
},
|
||||
}
|
||||
.create()
|
||||
}
|
||||
|
||||
impl UniversalRegionRelations<'_> {
|
||||
/// Records in the `outlives_relation` (and
|
||||
/// `inverse_outlives_relation`) that `fr_a: fr_b`. Invoked by the
|
||||
/// builder below.
|
||||
fn relate_universal_regions(&mut self, fr_a: RegionVid, fr_b: RegionVid) {
|
||||
debug!("relate_universal_regions: fr_a={:?} outlives fr_b={:?}", fr_a, fr_b);
|
||||
self.outlives.add(fr_a, fr_b);
|
||||
self.inverse_outlives.add(fr_b, fr_a);
|
||||
}
|
||||
|
||||
/// Given two universal regions, returns the postdominating
|
||||
/// upper-bound (effectively the least upper bound).
|
||||
///
|
||||
|
@ -216,11 +204,20 @@ struct UniversalRegionRelationsBuilder<'this, 'tcx> {
|
|||
constraints: &'this mut MirTypeckRegionConstraints<'tcx>,
|
||||
|
||||
// outputs:
|
||||
relations: UniversalRegionRelations<'tcx>,
|
||||
outlives: TransitiveRelationBuilder<RegionVid>,
|
||||
inverse_outlives: TransitiveRelationBuilder<RegionVid>,
|
||||
region_bound_pairs: RegionBoundPairs<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
|
||||
/// Records in the `outlives_relation` (and
|
||||
/// `inverse_outlives_relation`) that `fr_a: fr_b`.
|
||||
fn relate_universal_regions(&mut self, fr_a: RegionVid, fr_b: RegionVid) {
|
||||
debug!("relate_universal_regions: fr_a={:?} outlives fr_b={:?}", fr_a, fr_b);
|
||||
self.outlives.add(fr_a, fr_b);
|
||||
self.inverse_outlives.add(fr_b, fr_a);
|
||||
}
|
||||
|
||||
pub(crate) fn create(mut self) -> CreateResult<'tcx> {
|
||||
let unnormalized_input_output_tys = self
|
||||
.universal_regions
|
||||
|
@ -292,9 +289,9 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
|
|||
let fr_fn_body = self.universal_regions.fr_fn_body;
|
||||
for fr in self.universal_regions.universal_regions() {
|
||||
debug!("build: relating free region {:?} to itself and to 'static", fr);
|
||||
self.relations.relate_universal_regions(fr, fr);
|
||||
self.relations.relate_universal_regions(fr_static, fr);
|
||||
self.relations.relate_universal_regions(fr, fr_fn_body);
|
||||
self.relate_universal_regions(fr, fr);
|
||||
self.relate_universal_regions(fr_static, fr);
|
||||
self.relate_universal_regions(fr, fr_fn_body);
|
||||
}
|
||||
|
||||
for data in &constraint_sets {
|
||||
|
@ -313,7 +310,11 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
|
|||
}
|
||||
|
||||
CreateResult {
|
||||
universal_region_relations: Frozen::freeze(self.relations),
|
||||
universal_region_relations: Frozen::freeze(UniversalRegionRelations {
|
||||
universal_regions: self.universal_regions,
|
||||
outlives: self.outlives.freeze(),
|
||||
inverse_outlives: self.inverse_outlives.freeze(),
|
||||
}),
|
||||
region_bound_pairs: self.region_bound_pairs,
|
||||
normalized_inputs_and_output,
|
||||
}
|
||||
|
@ -356,7 +357,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
|
|||
// The bound says that `r1 <= r2`; we store `r2: r1`.
|
||||
let r1 = self.universal_regions.to_region_vid(r1);
|
||||
let r2 = self.universal_regions.to_region_vid(r2);
|
||||
self.relations.relate_universal_regions(r2, r1);
|
||||
self.relate_universal_regions(r2, r1);
|
||||
}
|
||||
|
||||
OutlivesBound::RegionSubParam(r_a, param_b) => {
|
||||
|
|
|
@ -178,19 +178,29 @@ pub(crate) fn type_check<'mir, 'tcx>(
|
|||
upvars,
|
||||
};
|
||||
|
||||
let opaque_type_values = type_check_internal(
|
||||
let mut checker = TypeChecker::new(
|
||||
infcx,
|
||||
param_env,
|
||||
body,
|
||||
promoted,
|
||||
param_env,
|
||||
®ion_bound_pairs,
|
||||
implicit_region_bound,
|
||||
&mut borrowck_context,
|
||||
|mut cx| {
|
||||
debug!("inside extra closure of type_check_internal");
|
||||
cx.equate_inputs_and_outputs(&body, universal_regions, &normalized_inputs_and_output);
|
||||
);
|
||||
|
||||
let errors_reported = {
|
||||
let mut verifier = TypeVerifier::new(&mut checker, promoted);
|
||||
verifier.visit_body(&body);
|
||||
verifier.errors_reported
|
||||
};
|
||||
|
||||
if !errors_reported {
|
||||
// if verifier failed, don't do further checks to avoid ICEs
|
||||
checker.typeck_mir(body);
|
||||
}
|
||||
|
||||
checker.equate_inputs_and_outputs(&body, universal_regions, &normalized_inputs_and_output);
|
||||
liveness::generate(
|
||||
&mut cx,
|
||||
&mut checker,
|
||||
body,
|
||||
elements,
|
||||
flow_inits,
|
||||
|
@ -199,14 +209,14 @@ pub(crate) fn type_check<'mir, 'tcx>(
|
|||
use_polonius,
|
||||
);
|
||||
|
||||
translate_outlives_facts(&mut cx);
|
||||
let opaque_type_values =
|
||||
infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
|
||||
translate_outlives_facts(&mut checker);
|
||||
let opaque_type_values = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
|
||||
|
||||
opaque_type_values
|
||||
let opaque_type_values = opaque_type_values
|
||||
.into_iter()
|
||||
.map(|(opaque_type_key, decl)| {
|
||||
cx.fully_perform_op(
|
||||
checker
|
||||
.fully_perform_op(
|
||||
Locations::All(body.span),
|
||||
ConstraintCategory::OpaqueType,
|
||||
CustomTypeOp::new(
|
||||
|
@ -224,11 +234,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
|
|||
)
|
||||
.unwrap();
|
||||
let mut hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type);
|
||||
trace!(
|
||||
"finalized opaque type {:?} to {:#?}",
|
||||
opaque_type_key,
|
||||
hidden_type.ty.kind()
|
||||
);
|
||||
trace!("finalized opaque type {:?} to {:#?}", opaque_type_key, hidden_type.ty.kind());
|
||||
if hidden_type.has_infer_types_or_consts() {
|
||||
infcx.tcx.sess.delay_span_bug(
|
||||
decl.hidden_type.span,
|
||||
|
@ -239,50 +245,11 @@ pub(crate) fn type_check<'mir, 'tcx>(
|
|||
|
||||
(opaque_type_key, (hidden_type, decl.origin))
|
||||
})
|
||||
.collect()
|
||||
},
|
||||
);
|
||||
.collect();
|
||||
|
||||
MirTypeckResults { constraints, universal_region_relations, opaque_type_values }
|
||||
}
|
||||
|
||||
#[instrument(
|
||||
skip(infcx, body, promoted, region_bound_pairs, borrowck_context, extra),
|
||||
level = "debug"
|
||||
)]
|
||||
fn type_check_internal<'a, 'tcx, R>(
|
||||
infcx: &'a InferCtxt<'a, 'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
promoted: &'a IndexVec<Promoted, Body<'tcx>>,
|
||||
region_bound_pairs: &'a RegionBoundPairs<'tcx>,
|
||||
implicit_region_bound: ty::Region<'tcx>,
|
||||
borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>,
|
||||
extra: impl FnOnce(TypeChecker<'a, 'tcx>) -> R,
|
||||
) -> R {
|
||||
debug!("body: {:#?}", body);
|
||||
let mut checker = TypeChecker::new(
|
||||
infcx,
|
||||
body,
|
||||
param_env,
|
||||
region_bound_pairs,
|
||||
implicit_region_bound,
|
||||
borrowck_context,
|
||||
);
|
||||
let errors_reported = {
|
||||
let mut verifier = TypeVerifier::new(&mut checker, promoted);
|
||||
verifier.visit_body(&body);
|
||||
verifier.errors_reported
|
||||
};
|
||||
|
||||
if !errors_reported {
|
||||
// if verifier failed, don't do further checks to avoid ICEs
|
||||
checker.typeck_mir(body);
|
||||
}
|
||||
|
||||
extra(checker)
|
||||
}
|
||||
|
||||
fn translate_outlives_facts(typeck: &mut TypeChecker<'_, '_>) {
|
||||
let cx = &mut typeck.borrowck_context;
|
||||
if let Some(facts) = cx.all_facts {
|
||||
|
@ -1076,6 +1043,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty } = *user_annotation;
|
||||
let inferred_ty = self.normalize(inferred_ty, Locations::All(span));
|
||||
let annotation = self.instantiate_canonical_with_fresh_inference_vars(span, user_ty);
|
||||
debug!(?annotation);
|
||||
match annotation {
|
||||
UserType::Ty(mut ty) => {
|
||||
ty = self.normalize(ty, Locations::All(span));
|
||||
|
@ -1911,7 +1879,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
&Rvalue::NullaryOp(_, ty) => {
|
||||
&Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, ty) => {
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)),
|
||||
substs: tcx.mk_substs_trait(ty, &[]),
|
||||
|
@ -2666,7 +2634,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
self.check_local(&body, local, local_decl);
|
||||
}
|
||||
|
||||
for (block, block_data) in body.basic_blocks().iter_enumerated() {
|
||||
for (block, block_data) in body.basic_blocks.iter_enumerated() {
|
||||
let mut location = Location { block, statement_index: 0 };
|
||||
for stmt in &block_data.statements {
|
||||
if !stmt.source_info.span.is_dummy() {
|
||||
|
|
|
@ -852,7 +852,7 @@ pub(super) fn expand_global_asm<'cx>(
|
|||
if let Some(inline_asm) = expand_preparsed_asm(ecx, args) {
|
||||
MacEager::items(smallvec![P(ast::Item {
|
||||
ident: Ident::empty(),
|
||||
attrs: Vec::new(),
|
||||
attrs: ast::AttrVec::new(),
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
kind: ast::ItemKind::GlobalAsm(Box::new(inline_asm)),
|
||||
vis: ast::Visibility {
|
||||
|
|
|
@ -52,7 +52,7 @@ pub fn expand_assert<'cx>(
|
|||
let expr = if let Some(tokens) = custom_message {
|
||||
let then = cx.expr(
|
||||
call_site_span,
|
||||
ExprKind::MacCall(MacCall {
|
||||
ExprKind::MacCall(P(MacCall {
|
||||
path: panic_path(),
|
||||
args: P(MacArgs::Delimited(
|
||||
DelimSpan::from_single(call_site_span),
|
||||
|
@ -60,7 +60,7 @@ pub fn expand_assert<'cx>(
|
|||
tokens,
|
||||
)),
|
||||
prior_type_ascription: None,
|
||||
}),
|
||||
})),
|
||||
);
|
||||
expr_if_not(cx, call_site_span, cond_expr, then, None)
|
||||
}
|
||||
|
|
|
@ -119,7 +119,8 @@ impl<'cx, 'a> Context<'cx, 'a> {
|
|||
vec![self.cx.attribute(attr::mk_list_item(
|
||||
Ident::new(sym::allow, self.span),
|
||||
vec![attr::mk_nested_word_item(Ident::new(sym::unused_imports, self.span))],
|
||||
))],
|
||||
))]
|
||||
.into(),
|
||||
ItemKind::Use(UseTree {
|
||||
prefix: self.cx.path(self.span, self.cx.std_path(&[sym::asserting])),
|
||||
kind: UseTreeKind::Nested(vec![
|
||||
|
@ -177,7 +178,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
|
|||
});
|
||||
self.cx.expr(
|
||||
self.span,
|
||||
ExprKind::MacCall(MacCall {
|
||||
ExprKind::MacCall(P(MacCall {
|
||||
path: panic_path,
|
||||
args: P(MacArgs::Delimited(
|
||||
DelimSpan::from_single(self.span),
|
||||
|
@ -185,7 +186,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
|
|||
initial.into_iter().chain(captures).collect::<TokenStream>(),
|
||||
)),
|
||||
prior_type_ascription: None,
|
||||
}),
|
||||
})),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ pub fn expand_cfg(
|
|||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(builtin_macros::requires_cfg_pattern)]
|
||||
#[diag(builtin_macros::requires_cfg_pattern)]
|
||||
struct RequiresCfgPattern {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
|
@ -44,7 +44,7 @@ struct RequiresCfgPattern {
|
|||
}
|
||||
|
||||
#[derive(SessionDiagnostic)]
|
||||
#[error(builtin_macros::expected_one_cfg_pattern)]
|
||||
#[diag(builtin_macros::expected_one_cfg_pattern)]
|
||||
struct OneCfgPattern {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
|
|
|
@ -39,7 +39,7 @@ pub fn expand_concat(
|
|||
ast::LitKind::Byte(..) | ast::LitKind::ByteStr(..) => {
|
||||
cx.span_err(e.span, "cannot concatenate a byte string literal");
|
||||
}
|
||||
ast::LitKind::Err(_) => {
|
||||
ast::LitKind::Err => {
|
||||
has_errors = true;
|
||||
}
|
||||
},
|
||||
|
|
|
@ -42,7 +42,7 @@ fn invalid_type_err(cx: &mut base::ExtCtxt<'_>, expr: &P<rustc_ast::Expr>, is_ne
|
|||
ast::LitKind::Bool(_) => {
|
||||
cx.span_err(expr.span, "cannot concatenate boolean literals");
|
||||
}
|
||||
ast::LitKind::Err(_) => {}
|
||||
ast::LitKind::Err => {}
|
||||
ast::LitKind::Int(_, _) if !is_nested => {
|
||||
let mut err = cx.struct_span_err(expr.span, "cannot concatenate numeric literals");
|
||||
if let Ok(snippet) = cx.sess.source_map().span_to_snippet(expr.span) {
|
||||
|
|
|
@ -68,7 +68,7 @@ pub fn expand_deriving_clone(
|
|||
}
|
||||
|
||||
let inline = cx.meta_word(span, sym::inline);
|
||||
let attrs = vec![cx.attribute(inline)];
|
||||
let attrs = vec![cx.attribute(inline)].into();
|
||||
let trait_def = TraitDef {
|
||||
span,
|
||||
path: path_std!(clone::Clone),
|
||||
|
|
|
@ -20,7 +20,7 @@ pub fn expand_deriving_eq(
|
|||
let hidden = rustc_ast::attr::mk_nested_word_item(Ident::new(sym::hidden, span));
|
||||
let doc = rustc_ast::attr::mk_list_item(Ident::new(sym::doc, span), vec![hidden]);
|
||||
let no_coverage = cx.meta_word(span, sym::no_coverage);
|
||||
let attrs = vec![cx.attribute(inline), cx.attribute(doc), cx.attribute(no_coverage)];
|
||||
let attrs = vec![cx.attribute(inline), cx.attribute(doc), cx.attribute(no_coverage)].into();
|
||||
let trait_def = TraitDef {
|
||||
span,
|
||||
path: path_std!(cmp::Eq),
|
||||
|
|
|
@ -15,7 +15,7 @@ pub fn expand_deriving_ord(
|
|||
push: &mut dyn FnMut(Annotatable),
|
||||
) {
|
||||
let inline = cx.meta_word(span, sym::inline);
|
||||
let attrs = vec![cx.attribute(inline)];
|
||||
let attrs = vec![cx.attribute(inline)].into();
|
||||
let trait_def = TraitDef {
|
||||
span,
|
||||
path: path_std!(cmp::Ord),
|
||||
|
|
|
@ -68,7 +68,7 @@ pub fn expand_deriving_partial_eq(
|
|||
// No need to generate `ne`, the default suffices, and not generating it is
|
||||
// faster.
|
||||
let inline = cx.meta_word(span, sym::inline);
|
||||
let attrs = vec![cx.attribute(inline)];
|
||||
let attrs = vec![cx.attribute(inline)].into();
|
||||
let methods = vec![MethodDef {
|
||||
name: sym::eq,
|
||||
generics: Bounds::empty(),
|
||||
|
|
|
@ -19,7 +19,7 @@ pub fn expand_deriving_partial_ord(
|
|||
Path(Path::new_(pathvec_std!(option::Option), vec![Box::new(ordering_ty)], PathKind::Std));
|
||||
|
||||
let inline = cx.meta_word(span, sym::inline);
|
||||
let attrs = vec![cx.attribute(inline)];
|
||||
let attrs = vec![cx.attribute(inline)].into();
|
||||
|
||||
let partial_cmp_def = MethodDef {
|
||||
name: sym::partial_cmp,
|
||||
|
|
|
@ -29,7 +29,7 @@ pub fn expand_deriving_debug(
|
|||
explicit_self: true,
|
||||
nonself_args: vec![(fmtr, sym::f)],
|
||||
ret_ty: Path(path_std!(fmt::Result)),
|
||||
attributes: Vec::new(),
|
||||
attributes: ast::AttrVec::new(),
|
||||
unify_fieldless_variants: false,
|
||||
combine_substructure: combine_substructure(Box::new(|a, b, c| {
|
||||
show_substructure(a, b, c)
|
||||
|
|
|
@ -47,7 +47,7 @@ pub fn expand_deriving_rustc_decodable(
|
|||
],
|
||||
PathKind::Std,
|
||||
)),
|
||||
attributes: Vec::new(),
|
||||
attributes: ast::AttrVec::new(),
|
||||
unify_fieldless_variants: false,
|
||||
combine_substructure: combine_substructure(Box::new(|a, b, c| {
|
||||
decodable_substructure(a, b, c, krate)
|
||||
|
|
|
@ -2,9 +2,7 @@ use crate::deriving::generic::ty::*;
|
|||
use crate::deriving::generic::*;
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast::walk_list;
|
||||
use rustc_ast::EnumDef;
|
||||
use rustc_ast::VariantData;
|
||||
use rustc_ast::{walk_list, EnumDef, VariantData};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_expand::base::{Annotatable, DummyResult, ExtCtxt};
|
||||
use rustc_span::symbol::Ident;
|
||||
|
@ -22,7 +20,7 @@ pub fn expand_deriving_default(
|
|||
item.visit_with(&mut DetectNonVariantDefaultAttr { cx });
|
||||
|
||||
let inline = cx.meta_word(span, sym::inline);
|
||||
let attrs = vec![cx.attribute(inline)];
|
||||
let attrs = vec![cx.attribute(inline)].into();
|
||||
let trait_def = TraitDef {
|
||||
span,
|
||||
path: Path::new(vec![kw::Default, sym::Default]),
|
||||
|
|
|
@ -89,7 +89,7 @@ use crate::deriving::generic::ty::*;
|
|||
use crate::deriving::generic::*;
|
||||
use crate::deriving::pathvec_std;
|
||||
|
||||
use rustc_ast::{ExprKind, MetaItem, Mutability};
|
||||
use rustc_ast::{AttrVec, ExprKind, MetaItem, Mutability};
|
||||
use rustc_expand::base::{Annotatable, ExtCtxt};
|
||||
use rustc_span::symbol::{sym, Ident, Symbol};
|
||||
use rustc_span::Span;
|
||||
|
@ -131,7 +131,7 @@ pub fn expand_deriving_rustc_encodable(
|
|||
],
|
||||
PathKind::Std,
|
||||
)),
|
||||
attributes: Vec::new(),
|
||||
attributes: AttrVec::new(),
|
||||
unify_fieldless_variants: false,
|
||||
combine_substructure: combine_substructure(Box::new(|a, b, c| {
|
||||
encodable_substructure(a, b, c, krate)
|
||||
|
|
|
@ -217,7 +217,7 @@ pub struct MethodDef<'a> {
|
|||
/// Returns type
|
||||
pub ret_ty: Ty,
|
||||
|
||||
pub attributes: Vec<ast::Attribute>,
|
||||
pub attributes: ast::AttrVec,
|
||||
|
||||
/// Can we combine fieldless variants for enums into a single match arm?
|
||||
/// If true, indicates that the trait operation uses the enum tag in some
|
||||
|
@ -383,8 +383,7 @@ fn find_type_parameters(
|
|||
// Place bound generic params on a stack, to extract them when a type is encountered.
|
||||
fn visit_poly_trait_ref(&mut self, trait_ref: &'a ast::PolyTraitRef) {
|
||||
let stack_len = self.bound_generic_params_stack.len();
|
||||
self.bound_generic_params_stack
|
||||
.extend(trait_ref.bound_generic_params.clone().into_iter());
|
||||
self.bound_generic_params_stack.extend(trait_ref.bound_generic_params.iter().cloned());
|
||||
|
||||
visit::walk_poly_trait_ref(self, trait_ref);
|
||||
|
||||
|
@ -562,7 +561,7 @@ impl<'a> TraitDef<'a> {
|
|||
kind: ast::VisibilityKind::Inherited,
|
||||
tokens: None,
|
||||
},
|
||||
attrs: Vec::new(),
|
||||
attrs: ast::AttrVec::new(),
|
||||
kind: ast::AssocItemKind::TyAlias(Box::new(ast::TyAlias {
|
||||
defaultness: ast::Defaultness::Final,
|
||||
generics: Generics::default(),
|
||||
|
@ -716,7 +715,7 @@ impl<'a> TraitDef<'a> {
|
|||
let self_type = cx.ty_path(path);
|
||||
|
||||
let attr = cx.attribute(cx.meta_word(self.span, sym::automatically_derived));
|
||||
let attrs = vec![attr];
|
||||
let attrs = vec![attr].into();
|
||||
let opt_trait_ref = Some(trait_ref);
|
||||
|
||||
cx.item(
|
||||
|
|
|
@ -2,7 +2,7 @@ use crate::deriving::generic::ty::*;
|
|||
use crate::deriving::generic::*;
|
||||
use crate::deriving::{path_std, pathvec_std};
|
||||
|
||||
use rustc_ast::{MetaItem, Mutability};
|
||||
use rustc_ast::{AttrVec, MetaItem, Mutability};
|
||||
use rustc_expand::base::{Annotatable, ExtCtxt};
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::Span;
|
||||
|
@ -31,7 +31,7 @@ pub fn expand_deriving_hash(
|
|||
explicit_self: true,
|
||||
nonself_args: vec![(Ref(Box::new(Path(arg)), Mutability::Mut), sym::state)],
|
||||
ret_ty: Unit,
|
||||
attributes: vec![],
|
||||
attributes: AttrVec::new(),
|
||||
unify_fieldless_variants: true,
|
||||
combine_substructure: combine_substructure(Box::new(|a, b, c| {
|
||||
hash_substructure(a, b, c)
|
||||
|
|
|
@ -164,7 +164,7 @@ fn inject_impl_of_structural_trait(
|
|||
|
||||
// Keep the lint and stability attributes of the original item, to control
|
||||
// how the generated implementation is linted.
|
||||
let mut attrs = Vec::new();
|
||||
let mut attrs = ast::AttrVec::new();
|
||||
attrs.extend(
|
||||
item.attrs
|
||||
.iter()
|
||||
|
|
|
@ -48,7 +48,7 @@ fn expand<'cx>(
|
|||
MacEager::expr(
|
||||
cx.expr(
|
||||
sp,
|
||||
ExprKind::MacCall(MacCall {
|
||||
ExprKind::MacCall(P(MacCall {
|
||||
path: Path {
|
||||
span: sp,
|
||||
segments: cx
|
||||
|
@ -64,7 +64,7 @@ fn expand<'cx>(
|
|||
tts,
|
||||
)),
|
||||
prior_type_ascription: None,
|
||||
}),
|
||||
})),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -413,7 +413,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||
/// Verifies one piece of a parse string, and remembers it if valid.
|
||||
/// All errors are not emitted as fatal so we can continue giving errors
|
||||
/// about this and possibly other format strings.
|
||||
fn verify_piece(&mut self, p: &parse::Piece<'_>) {
|
||||
fn verify_piece(&mut self, p: &parse::Piece<'a>) {
|
||||
match *p {
|
||||
parse::String(..) => {}
|
||||
parse::NextArgument(ref arg) => {
|
||||
|
@ -433,6 +433,11 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||
let has_precision = arg.format.precision != Count::CountImplied;
|
||||
let has_width = arg.format.width != Count::CountImplied;
|
||||
|
||||
if has_precision || has_width {
|
||||
// push before named params are resolved to aid diagnostics
|
||||
self.arg_with_formatting.push(arg.format);
|
||||
}
|
||||
|
||||
// argument second, if it's an implicit positional parameter
|
||||
// it's written second, so it should come after width/precision.
|
||||
let pos = match arg.position {
|
||||
|
@ -536,7 +541,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||
) {
|
||||
match c {
|
||||
parse::CountImplied | parse::CountIs(..) => {}
|
||||
parse::CountIsParam(i) => {
|
||||
parse::CountIsParam(i) | parse::CountIsStar(i) => {
|
||||
self.unused_names_lint.maybe_add_positional_named_arg(
|
||||
self.args.get(i),
|
||||
named_arg_type,
|
||||
|
@ -581,7 +586,11 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||
let mut zero_based_note = false;
|
||||
|
||||
let count = self.pieces.len()
|
||||
+ self.arg_with_formatting.iter().filter(|fmt| fmt.precision_span.is_some()).count();
|
||||
+ self
|
||||
.arg_with_formatting
|
||||
.iter()
|
||||
.filter(|fmt| matches!(fmt.precision, parse::CountIsStar(_)))
|
||||
.count();
|
||||
if self.names.is_empty() && !numbered_position_args && count != self.num_args() {
|
||||
e = self.ecx.struct_span_err(
|
||||
sp,
|
||||
|
@ -630,7 +639,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||
if let Some(span) = fmt.precision_span {
|
||||
let span = self.fmtsp.from_inner(InnerSpan::new(span.start, span.end));
|
||||
match fmt.precision {
|
||||
parse::CountIsParam(pos) if pos > self.num_args() => {
|
||||
parse::CountIsParam(pos) if pos >= self.num_args() => {
|
||||
e.span_label(
|
||||
span,
|
||||
&format!(
|
||||
|
@ -642,12 +651,12 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||
);
|
||||
zero_based_note = true;
|
||||
}
|
||||
parse::CountIsParam(pos) => {
|
||||
parse::CountIsStar(pos) => {
|
||||
let count = self.pieces.len()
|
||||
+ self
|
||||
.arg_with_formatting
|
||||
.iter()
|
||||
.filter(|fmt| fmt.precision_span.is_some())
|
||||
.filter(|fmt| matches!(fmt.precision, parse::CountIsStar(_)))
|
||||
.count();
|
||||
e.span_label(
|
||||
span,
|
||||
|
@ -828,7 +837,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||
};
|
||||
match c {
|
||||
parse::CountIs(i) => count(sym::Is, Some(self.ecx.expr_usize(sp, i))),
|
||||
parse::CountIsParam(i) => {
|
||||
parse::CountIsParam(i) | parse::CountIsStar(i) => {
|
||||
// This needs mapping too, as `i` is referring to a macro
|
||||
// argument. If `i` is not found in `count_positions` then
|
||||
// the error had already been emitted elsewhere.
|
||||
|
@ -899,26 +908,22 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||
},
|
||||
position_span: arg.position_span,
|
||||
format: parse::FormatSpec {
|
||||
fill: arg.format.fill,
|
||||
fill: None,
|
||||
align: parse::AlignUnknown,
|
||||
flags: 0,
|
||||
precision: parse::CountImplied,
|
||||
precision_span: None,
|
||||
precision_span: arg.format.precision_span,
|
||||
width: parse::CountImplied,
|
||||
width_span: None,
|
||||
width_span: arg.format.width_span,
|
||||
ty: arg.format.ty,
|
||||
ty_span: arg.format.ty_span,
|
||||
},
|
||||
};
|
||||
|
||||
let fill = arg.format.fill.unwrap_or(' ');
|
||||
|
||||
let pos_simple = arg.position.index() == simple_arg.position.index();
|
||||
|
||||
if arg.format.precision_span.is_some() || arg.format.width_span.is_some() {
|
||||
self.arg_with_formatting.push(arg.format);
|
||||
}
|
||||
if !pos_simple || arg.format != simple_arg.format || fill != ' ' {
|
||||
if !pos_simple || arg.format != simple_arg.format {
|
||||
self.all_pieces_simple = false;
|
||||
}
|
||||
|
||||
|
@ -1176,7 +1181,7 @@ fn create_lints_for_named_arguments_used_positionally(cx: &mut Context<'_, '_>)
|
|||
|
||||
cx.ecx.buffered_early_lint.push(BufferedEarlyLint {
|
||||
span: MultiSpan::from_span(named_arg.positional_named_arg_span),
|
||||
msg: msg.clone(),
|
||||
msg: msg.into(),
|
||||
node_id: ast::CRATE_NODE_ID,
|
||||
lint_id: LintId::of(&NAMED_ARGUMENTS_USED_POSITIONALLY),
|
||||
diagnostic: BuiltinLintDiagnostics::NamedArgumentUsedPositionally {
|
||||
|
|
|
@ -4,7 +4,7 @@ use rustc_ast::expand::allocator::{
|
|||
AllocatorKind, AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS,
|
||||
};
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::{self as ast, Attribute, Expr, FnHeader, FnSig, Generics, Param, StmtKind};
|
||||
use rustc_ast::{self as ast, AttrVec, Expr, FnHeader, FnSig, Generics, Param, StmtKind};
|
||||
use rustc_ast::{Fn, ItemKind, Mutability, Stmt, Ty, TyKind, Unsafe};
|
||||
use rustc_expand::base::{Annotatable, ExtCtxt};
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
|
@ -113,10 +113,10 @@ impl AllocFnFactory<'_, '_> {
|
|||
self.cx.expr_call(self.ty_span, method, args)
|
||||
}
|
||||
|
||||
fn attrs(&self) -> Vec<Attribute> {
|
||||
fn attrs(&self) -> AttrVec {
|
||||
let special = sym::rustc_std_internal_symbol;
|
||||
let special = self.cx.meta_word(self.span, special);
|
||||
vec![self.cx.attribute(special)]
|
||||
vec![self.cx.attribute(special)].into()
|
||||
}
|
||||
|
||||
fn arg_ty(
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#![feature(decl_macro)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(is_sorted)]
|
||||
#![feature(let_chains)]
|
||||
#![feature(let_else)]
|
||||
#![feature(proc_macro_internals)]
|
||||
#![feature(proc_macro_quote)]
|
||||
|
|
|
@ -281,7 +281,7 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P<ast::Item> {
|
|||
let span = DUMMY_SP.with_def_site_ctxt(expn_id.to_expn_id());
|
||||
|
||||
let proc_macro = Ident::new(sym::proc_macro, span);
|
||||
let krate = cx.item(span, proc_macro, Vec::new(), ast::ItemKind::ExternCrate(None));
|
||||
let krate = cx.item(span, proc_macro, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None));
|
||||
|
||||
let bridge = Ident::new(sym::bridge, span);
|
||||
let client = Ident::new(sym::client, span);
|
||||
|
|
|
@ -51,7 +51,7 @@ pub fn inject(
|
|||
cx.item(
|
||||
span,
|
||||
ident,
|
||||
vec![cx.attribute(cx.meta_word(span, sym::macro_use))],
|
||||
vec![cx.attribute(cx.meta_word(span, sym::macro_use))].into(),
|
||||
ast::ItemKind::ExternCrate(None),
|
||||
),
|
||||
);
|
||||
|
@ -78,7 +78,7 @@ pub fn inject(
|
|||
let use_item = cx.item(
|
||||
span,
|
||||
Ident::empty(),
|
||||
vec![cx.attribute(cx.meta_word(span, sym::prelude_import))],
|
||||
vec![cx.attribute(cx.meta_word(span, sym::prelude_import))].into(),
|
||||
ast::ItemKind::Use(ast::UseTree {
|
||||
prefix: cx.path(span, import_path),
|
||||
kind: ast::UseTreeKind::Glob,
|
||||
|
|
|
@ -227,7 +227,8 @@ pub fn expand_test_or_bench(
|
|||
)),
|
||||
// #[rustc_test_marker]
|
||||
cx.attribute(cx.meta_word(attr_sp, sym::rustc_test_marker)),
|
||||
],
|
||||
]
|
||||
.into(),
|
||||
// const $ident: test::TestDescAndFn =
|
||||
ast::ItemKind::Const(
|
||||
ast::Defaultness::Final,
|
||||
|
@ -334,7 +335,7 @@ pub fn expand_test_or_bench(
|
|||
});
|
||||
|
||||
// extern crate test
|
||||
let test_extern = cx.item(sp, test_id, vec![], ast::ItemKind::ExternCrate(None));
|
||||
let test_extern = cx.item(sp, test_id, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None));
|
||||
|
||||
tracing::debug!("synthetic test item:\n{}\n", pprust::item_to_string(&test_const));
|
||||
|
||||
|
|
|
@ -298,8 +298,10 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
|
|||
let call_test_main = ecx.stmt_expr(call_test_main);
|
||||
|
||||
// extern crate test
|
||||
let test_extern_stmt =
|
||||
ecx.stmt_item(sp, ecx.item(sp, test_id, vec![], ast::ItemKind::ExternCrate(None)));
|
||||
let test_extern_stmt = ecx.stmt_item(
|
||||
sp,
|
||||
ecx.item(sp, test_id, ast::AttrVec::new(), ast::ItemKind::ExternCrate(None)),
|
||||
);
|
||||
|
||||
// #[rustc_main]
|
||||
let main_meta = ecx.meta_word(sp, sym::rustc_main);
|
||||
|
@ -333,7 +335,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
|
|||
|
||||
let main = P(ast::Item {
|
||||
ident: main_id,
|
||||
attrs: vec![main_attr],
|
||||
attrs: vec![main_attr].into(),
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
kind: main,
|
||||
vis: ast::Visibility { span: sp, kind: ast::VisibilityKind::Public, tokens: None },
|
||||
|
|
|
@ -22,4 +22,4 @@ task:
|
|||
- # Reduce amount of benchmark runs as they are slow
|
||||
- export COMPILE_RUNS=2
|
||||
- export RUN_RUNS=2
|
||||
- ./test.sh
|
||||
- ./y.rs test
|
||||
|
|
|
@ -103,7 +103,7 @@ jobs:
|
|||
# Enable extra checks
|
||||
export CG_CLIF_ENABLE_VERIFIER=1
|
||||
|
||||
./test.sh
|
||||
./y.rs test
|
||||
|
||||
- name: Package prebuilt cg_clif
|
||||
run: tar cvfJ cg_clif.tar.xz build
|
||||
|
@ -162,14 +162,14 @@ jobs:
|
|||
#name: Test
|
||||
run: |
|
||||
# Enable backtraces for easier debugging
|
||||
#export RUST_BACKTRACE=1
|
||||
#$Env:RUST_BACKTRACE=1
|
||||
|
||||
# Reduce amount of benchmark runs as they are slow
|
||||
#export COMPILE_RUNS=2
|
||||
#export RUN_RUNS=2
|
||||
#$Env:COMPILE_RUNS=2
|
||||
#$Env:RUN_RUNS=2
|
||||
|
||||
# Enable extra checks
|
||||
#export CG_CLIF_ENABLE_VERIFIER=1
|
||||
#$Env:CG_CLIF_ENABLE_VERIFIER=1
|
||||
|
||||
./y.exe build
|
||||
|
||||
|
|
3
compiler/rustc_codegen_cranelift/.gitignore
vendored
3
compiler/rustc_codegen_cranelift/.gitignore
vendored
|
@ -8,6 +8,8 @@ perf.data.old
|
|||
*.string*
|
||||
/y.bin
|
||||
/y.bin.dSYM
|
||||
/y.exe
|
||||
/y.pdb
|
||||
/build
|
||||
/build_sysroot/sysroot_src
|
||||
/build_sysroot/compiler-builtins
|
||||
|
@ -17,3 +19,4 @@ perf.data.old
|
|||
/regex
|
||||
/simple-raytracer
|
||||
/portable-simd
|
||||
/abi-checker
|
||||
|
|
|
@ -50,18 +50,18 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|||
|
||||
[[package]]
|
||||
name = "cranelift-bforest"
|
||||
version = "0.85.3"
|
||||
version = "0.87.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "749d0d6022c9038dccf480bdde2a38d435937335bf2bb0f14e815d94517cdce8"
|
||||
checksum = "93945adbccc8d731503d3038814a51e8317497c9e205411820348132fa01a358"
|
||||
dependencies = [
|
||||
"cranelift-entity",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-codegen"
|
||||
version = "0.85.3"
|
||||
version = "0.87.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e94370cc7b37bf652ccd8bb8f09bd900997f7ccf97520edfc75554bb5c4abbea"
|
||||
checksum = "2b482acc9d0d0d1ad3288a90a8150ee648be3dce8dc8c8669ff026f72debdc31"
|
||||
dependencies = [
|
||||
"cranelift-bforest",
|
||||
"cranelift-codegen-meta",
|
||||
|
@ -77,30 +77,30 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cranelift-codegen-meta"
|
||||
version = "0.85.3"
|
||||
version = "0.87.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0a3cea8fdab90e44018c5b9a1dfd460d8ee265ac354337150222a354628bdb6"
|
||||
checksum = "f9ec188d71e663192ef9048f204e410a7283b609942efc9fcc77da6d496edbb8"
|
||||
dependencies = [
|
||||
"cranelift-codegen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-codegen-shared"
|
||||
version = "0.85.3"
|
||||
version = "0.87.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ac72f76f2698598951ab26d8c96eaa854810e693e7dd52523958b5909fde6b2"
|
||||
checksum = "3ad794b1b1c2c7bd9f7b76cfe0f084eaf7753e55d56191c3f7d89e8fa4978b99"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-entity"
|
||||
version = "0.85.3"
|
||||
version = "0.87.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09eaeacfcd2356fe0e66b295e8f9d59fdd1ac3ace53ba50de14d628ec902f72d"
|
||||
checksum = "342da0d5056f4119d3c311c4aab2460ceb6ee6e127bb395b76dd2279a09ea7a5"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-frontend"
|
||||
version = "0.85.3"
|
||||
version = "0.87.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dba69c9980d5ffd62c18a2bde927855fcd7c8dc92f29feaf8636052662cbd99c"
|
||||
checksum = "dfff792f775b07d4d9cfe9f1c767ce755c6cbadda1bbd6db18a1c75ff9f7376a"
|
||||
dependencies = [
|
||||
"cranelift-codegen",
|
||||
"log",
|
||||
|
@ -110,15 +110,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cranelift-isle"
|
||||
version = "0.85.3"
|
||||
version = "0.87.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2920dc1e05cac40304456ed3301fde2c09bd6a9b0210bcfa2f101398d628d5b"
|
||||
checksum = "8d51089478849f2ac8ef60a8a2d5346c8d4abfec0e45ac5b24530ef9f9499e1e"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-jit"
|
||||
version = "0.85.3"
|
||||
version = "0.87.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c3c5ed067f2c81577e431f3039148a9c187b33cc79e0d1731fede27d801ec56"
|
||||
checksum = "095936e41720f86004b4c57ce88e6a13af28646bb3a6fb4afbebd5ae90c50029"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cranelift-codegen",
|
||||
|
@ -129,14 +129,14 @@ dependencies = [
|
|||
"log",
|
||||
"region",
|
||||
"target-lexicon",
|
||||
"winapi",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-module"
|
||||
version = "0.85.3"
|
||||
version = "0.87.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eee6784303bf9af235237a4885f7417e09a35df896d38ea969a0081064b3ede4"
|
||||
checksum = "704a1aea4723d97eafe0fb7af110f6f6868b1ac95f5380bbc9adb2a3b8cf97e8"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cranelift-codegen",
|
||||
|
@ -144,9 +144,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cranelift-native"
|
||||
version = "0.85.3"
|
||||
version = "0.87.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f04dfa45f9b2a6f587c564d6b63388e00cd6589d2df6ea2758cf79e1a13285e6"
|
||||
checksum = "885debe62f2078638d6585f54c9f05f5c2008f22ce5a2a9100ada785fc065dbd"
|
||||
dependencies = [
|
||||
"cranelift-codegen",
|
||||
"libc",
|
||||
|
@ -155,9 +155,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cranelift-object"
|
||||
version = "0.85.3"
|
||||
version = "0.87.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0bf38b2c505db749276793116c0cb30bd096206c7810e471677a453134881881"
|
||||
checksum = "aac1310cf1081ae8eca916c92cd163b977c77cab6e831fa812273c26ff921816"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cranelift-codegen",
|
||||
|
@ -187,9 +187,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.6"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad"
|
||||
checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
|
@ -198,27 +198,21 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.26.1"
|
||||
version = "0.26.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4"
|
||||
checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
|
@ -227,14 +221,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown 0.12.3",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.126"
|
||||
version = "0.2.127"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
|
||||
checksum = "505e71a4706fa491e9b1b55f51b95d4037d0821ee40131190475f692b35b009b"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
|
@ -248,9 +242,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.14"
|
||||
version = "0.4.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
@ -266,33 +260,33 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.4.1"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.28.4"
|
||||
version = "0.29.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424"
|
||||
checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"hashbrown 0.11.2",
|
||||
"hashbrown",
|
||||
"indexmap",
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.10.0"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
|
||||
checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1"
|
||||
|
||||
[[package]]
|
||||
name = "regalloc2"
|
||||
version = "0.2.3"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a8d23b35d7177df3b9d31ed8a9ab4bf625c668be77a319d4f5efd4a5257701c"
|
||||
checksum = "d43a209257d978ef079f3d446331d0f1794f5e0fc19b306a199983857833a779"
|
||||
dependencies = [
|
||||
"fxhash",
|
||||
"log",
|
||||
|
@ -340,15 +334,15 @@ checksum = "03b634d87b960ab1a38c4fe143b508576f075e7c978bfad18217645ebfdfa2ec"
|
|||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.8.1"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc88c725d61fc6c3132893370cac4a0200e3fedf5da8331c570664b1987f5ca2"
|
||||
checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1"
|
||||
|
||||
[[package]]
|
||||
name = "target-lexicon"
|
||||
version = "0.12.3"
|
||||
version = "0.12.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7fa7e55043acb85fca6b3c01485a2eeb6b69c5d21002e273c79e465f43b7ac1"
|
||||
checksum = "c02424087780c9b71cc96799eaeddff35af2bc513278cda5c99fc1f5d026d3c1"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
|
@ -358,9 +352,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
|||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.2+wasi-snapshot-preview1"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
|
@ -383,3 +377,46 @@ name = "winapi-x86_64-pc-windows-gnu"
|
|||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.36.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
|
||||
dependencies = [
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.36.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.36.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.36.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.36.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.36.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
|
||||
|
|
|
@ -8,15 +8,15 @@ crate-type = ["dylib"]
|
|||
|
||||
[dependencies]
|
||||
# These have to be in sync with each other
|
||||
cranelift-codegen = { version = "0.85.3", features = ["unwind", "all-arch"] }
|
||||
cranelift-frontend = "0.85.3"
|
||||
cranelift-module = "0.85.3"
|
||||
cranelift-native = "0.85.3"
|
||||
cranelift-jit = { version = "0.85.3", optional = true }
|
||||
cranelift-object = "0.85.3"
|
||||
cranelift-codegen = { version = "0.87.0", features = ["unwind", "all-arch"] }
|
||||
cranelift-frontend = "0.87.0"
|
||||
cranelift-module = "0.87.0"
|
||||
cranelift-native = "0.87.0"
|
||||
cranelift-jit = { version = "0.87.0", optional = true }
|
||||
cranelift-object = "0.87.0"
|
||||
target-lexicon = "0.12.0"
|
||||
gimli = { version = "0.26.0", default-features = false, features = ["write"]}
|
||||
object = { version = "0.28.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
|
||||
object = { version = "0.29.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
|
||||
|
||||
ar = { git = "https://github.com/bjorn3/rust-ar.git", branch = "do_not_remove_cg_clif_ranlib" }
|
||||
indexmap = "1.9.1"
|
||||
|
|
|
@ -52,9 +52,7 @@ configuration options.
|
|||
## Not yet supported
|
||||
|
||||
* Inline assembly ([no cranelift support](https://github.com/bytecodealliance/wasmtime/issues/1041))
|
||||
* On Linux there is support for invoking an external assembler for `global_asm!` and `asm!`.
|
||||
`llvm_asm!` will remain unimplemented forever. `asm!` doesn't yet support reg classes. You
|
||||
have to specify specific registers instead.
|
||||
* On UNIX there is support for invoking an external assembler for `global_asm!` and `asm!`.
|
||||
* SIMD ([tracked here](https://github.com/bjorn3/rustc_codegen_cranelift/issues/171), some basic things work)
|
||||
|
||||
## License
|
||||
|
|
|
@ -56,9 +56,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "compiler_builtins"
|
||||
version = "0.1.75"
|
||||
version = "0.1.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c6e3183e88f659a862835db8f4b67dbeed3d93e44dd4927eef78edb1c149d784"
|
||||
checksum = "4f873ce2bd3550b0b565f878b3d04ea8253f4259dc3d20223af2e1ba86f5ecca"
|
||||
dependencies = [
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
@ -69,9 +69,9 @@ version = "0.0.0"
|
|||
|
||||
[[package]]
|
||||
name = "dlmalloc"
|
||||
version = "0.2.3"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a6fe28e0bf9357092740362502f5cc7955d8dc125ebda71dec72336c2e15c62e"
|
||||
checksum = "203540e710bfadb90e5e29930baf5d10270cec1f43ab34f46f78b147b2de715a"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"libc",
|
||||
|
@ -80,9 +80,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "fortanix-sgx-abi"
|
||||
version = "0.3.3"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c56c422ef86062869b2d57ae87270608dc5929969dd130a6e248979cf4fb6ca6"
|
||||
checksum = "57cafc2274c10fab234f176b25903ce17e690fca7597090d50880e047a0389c5"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-core",
|
||||
|
@ -123,9 +123,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.2.4"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7668753748e445859e4e373c3d41117235d9feed578392f5a3a73efdc751ca4a"
|
||||
checksum = "897cd85af6387be149f55acf168e41be176a02de7872403aaab184afc2f327e6"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"libc",
|
||||
|
@ -135,9 +135,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.126"
|
||||
version = "0.2.132"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
|
||||
checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5"
|
||||
dependencies = [
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
|
60
compiler/rustc_codegen_cranelift/build_system/abi_checker.rs
Normal file
60
compiler/rustc_codegen_cranelift/build_system/abi_checker.rs
Normal file
|
@ -0,0 +1,60 @@
|
|||
use super::build_sysroot;
|
||||
use super::config;
|
||||
use super::utils::spawn_and_wait;
|
||||
use build_system::SysrootKind;
|
||||
use std::env;
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
|
||||
pub(crate) fn run(
|
||||
channel: &str,
|
||||
sysroot_kind: SysrootKind,
|
||||
target_dir: &Path,
|
||||
cg_clif_build_dir: &Path,
|
||||
host_triple: &str,
|
||||
target_triple: &str,
|
||||
) {
|
||||
if !config::get_bool("testsuite.abi-checker") {
|
||||
eprintln!("[SKIP] abi-checker");
|
||||
return;
|
||||
}
|
||||
|
||||
if host_triple != target_triple {
|
||||
eprintln!("[SKIP] abi-checker (cross-compilation not supported)");
|
||||
return;
|
||||
}
|
||||
|
||||
eprintln!("Building sysroot for abi-checker");
|
||||
build_sysroot::build_sysroot(
|
||||
channel,
|
||||
sysroot_kind,
|
||||
target_dir,
|
||||
cg_clif_build_dir,
|
||||
host_triple,
|
||||
target_triple,
|
||||
);
|
||||
|
||||
eprintln!("Running abi-checker");
|
||||
let mut abi_checker_path = env::current_dir().unwrap();
|
||||
abi_checker_path.push("abi-checker");
|
||||
env::set_current_dir(abi_checker_path.clone()).unwrap();
|
||||
|
||||
let build_dir = abi_checker_path.parent().unwrap().join("build");
|
||||
let cg_clif_dylib_path = build_dir.join(if cfg!(windows) { "bin" } else { "lib" }).join(
|
||||
env::consts::DLL_PREFIX.to_string() + "rustc_codegen_cranelift" + env::consts::DLL_SUFFIX,
|
||||
);
|
||||
|
||||
let pairs = ["rustc_calls_cgclif", "cgclif_calls_rustc", "cgclif_calls_cc", "cc_calls_cgclif"];
|
||||
|
||||
let mut cmd = Command::new("cargo");
|
||||
cmd.arg("run");
|
||||
cmd.arg("--target");
|
||||
cmd.arg(target_triple);
|
||||
cmd.arg("--");
|
||||
cmd.arg("--pairs");
|
||||
cmd.args(pairs);
|
||||
cmd.arg("--add-rustc-codegen-backend");
|
||||
cmd.arg(format!("cgclif:{}", cg_clif_dylib_path.display()));
|
||||
|
||||
spawn_and_wait(cmd);
|
||||
}
|
|
@ -2,6 +2,8 @@ use std::env;
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
|
||||
use super::utils::is_ci;
|
||||
|
||||
pub(crate) fn build_backend(
|
||||
channel: &str,
|
||||
host_triple: &str,
|
||||
|
@ -14,7 +16,7 @@ pub(crate) fn build_backend(
|
|||
|
||||
let mut rustflags = env::var("RUSTFLAGS").unwrap_or_default();
|
||||
|
||||
if env::var("CI").as_ref().map(|val| &**val) == Ok("true") {
|
||||
if is_ci() {
|
||||
// Deny warnings on CI
|
||||
rustflags += " -Dwarnings";
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ use std::fs;
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::process::{self, Command};
|
||||
|
||||
use super::rustc_info::{get_file_name, get_rustc_version};
|
||||
use super::rustc_info::{get_file_name, get_rustc_version, get_wrapper_file_name};
|
||||
use super::utils::{spawn_and_wait, try_hard_link};
|
||||
use super::SysrootKind;
|
||||
|
||||
|
@ -10,10 +10,12 @@ pub(crate) fn build_sysroot(
|
|||
channel: &str,
|
||||
sysroot_kind: SysrootKind,
|
||||
target_dir: &Path,
|
||||
cg_clif_build_dir: PathBuf,
|
||||
cg_clif_build_dir: &Path,
|
||||
host_triple: &str,
|
||||
target_triple: &str,
|
||||
) {
|
||||
eprintln!("[BUILD] sysroot {:?}", sysroot_kind);
|
||||
|
||||
if target_dir.exists() {
|
||||
fs::remove_dir_all(target_dir).unwrap();
|
||||
}
|
||||
|
@ -35,11 +37,13 @@ pub(crate) fn build_sysroot(
|
|||
|
||||
// Build and copy rustc and cargo wrappers
|
||||
for wrapper in ["rustc-clif", "cargo-clif"] {
|
||||
let wrapper_name = get_wrapper_file_name(wrapper, "bin");
|
||||
|
||||
let mut build_cargo_wrapper_cmd = Command::new("rustc");
|
||||
build_cargo_wrapper_cmd
|
||||
.arg(PathBuf::from("scripts").join(format!("{wrapper}.rs")))
|
||||
.arg("-o")
|
||||
.arg(target_dir.join(wrapper))
|
||||
.arg(target_dir.join(wrapper_name))
|
||||
.arg("-g");
|
||||
spawn_and_wait(build_cargo_wrapper_cmd);
|
||||
}
|
||||
|
|
|
@ -2,11 +2,15 @@ use std::env;
|
|||
use std::path::PathBuf;
|
||||
use std::process;
|
||||
|
||||
use self::utils::is_ci;
|
||||
|
||||
mod abi_checker;
|
||||
mod build_backend;
|
||||
mod build_sysroot;
|
||||
mod config;
|
||||
mod prepare;
|
||||
mod rustc_info;
|
||||
mod tests;
|
||||
mod utils;
|
||||
|
||||
fn usage() {
|
||||
|
@ -15,6 +19,9 @@ fn usage() {
|
|||
eprintln!(
|
||||
" ./y.rs build [--debug] [--sysroot none|clif|llvm] [--target-dir DIR] [--no-unstable-features]"
|
||||
);
|
||||
eprintln!(
|
||||
" ./y.rs test [--debug] [--sysroot none|clif|llvm] [--target-dir DIR] [--no-unstable-features]"
|
||||
);
|
||||
}
|
||||
|
||||
macro_rules! arg_error {
|
||||
|
@ -25,11 +32,13 @@ macro_rules! arg_error {
|
|||
}};
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
enum Command {
|
||||
Build,
|
||||
Test,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub(crate) enum SysrootKind {
|
||||
None,
|
||||
Clif,
|
||||
|
@ -42,16 +51,22 @@ pub fn main() {
|
|||
// The target dir is expected in the default location. Guard against the user changing it.
|
||||
env::set_var("CARGO_TARGET_DIR", "target");
|
||||
|
||||
if is_ci() {
|
||||
// Disabling incr comp reduces cache size and incr comp doesn't save as much on CI anyway
|
||||
env::set_var("CARGO_BUILD_INCREMENTAL", "false");
|
||||
}
|
||||
|
||||
let mut args = env::args().skip(1);
|
||||
let command = match args.next().as_deref() {
|
||||
Some("prepare") => {
|
||||
if args.next().is_some() {
|
||||
arg_error!("./x.rs prepare doesn't expect arguments");
|
||||
arg_error!("./y.rs prepare doesn't expect arguments");
|
||||
}
|
||||
prepare::prepare();
|
||||
process::exit(0);
|
||||
}
|
||||
Some("build") => Command::Build,
|
||||
Some("test") => Command::Test,
|
||||
Some(flag) if flag.starts_with('-') => arg_error!("Expected command found flag {}", flag),
|
||||
Some(command) => arg_error!("Unknown command {}", command),
|
||||
None => {
|
||||
|
@ -117,12 +132,35 @@ pub fn main() {
|
|||
|
||||
let cg_clif_build_dir =
|
||||
build_backend::build_backend(channel, &host_triple, use_unstable_features);
|
||||
build_sysroot::build_sysroot(
|
||||
match command {
|
||||
Command::Test => {
|
||||
tests::run_tests(
|
||||
channel,
|
||||
sysroot_kind,
|
||||
&target_dir,
|
||||
cg_clif_build_dir,
|
||||
&cg_clif_build_dir,
|
||||
&host_triple,
|
||||
&target_triple,
|
||||
);
|
||||
|
||||
abi_checker::run(
|
||||
channel,
|
||||
sysroot_kind,
|
||||
&target_dir,
|
||||
&cg_clif_build_dir,
|
||||
&host_triple,
|
||||
&target_triple,
|
||||
);
|
||||
}
|
||||
Command::Build => {
|
||||
build_sysroot::build_sysroot(
|
||||
channel,
|
||||
sysroot_kind,
|
||||
&target_dir,
|
||||
&cg_clif_build_dir,
|
||||
&host_triple,
|
||||
&target_triple,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,14 @@ pub(crate) fn prepare() {
|
|||
eprintln!("[INSTALL] hyperfine");
|
||||
Command::new("cargo").arg("install").arg("hyperfine").spawn().unwrap().wait().unwrap();
|
||||
|
||||
clone_repo_shallow_github(
|
||||
"abi-checker",
|
||||
"Gankra",
|
||||
"abi-checker",
|
||||
"a2232d45f202846f5c02203c9f27355360f9a2ff",
|
||||
);
|
||||
apply_patches("abi-checker", Path::new("abi-checker"));
|
||||
|
||||
clone_repo_shallow_github(
|
||||
"rand",
|
||||
"rust-random",
|
||||
|
@ -50,8 +58,7 @@ pub(crate) fn prepare() {
|
|||
spawn_and_wait(build_cmd);
|
||||
fs::copy(
|
||||
Path::new("simple-raytracer/target/debug").join(get_file_name("main", "bin")),
|
||||
// FIXME use get_file_name here too once testing is migrated to rust
|
||||
"simple-raytracer/raytracer_cg_llvm",
|
||||
Path::new("simple-raytracer").join(get_file_name("raytracer_cg_llvm", "bin")),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
|
|
@ -63,3 +63,12 @@ pub(crate) fn get_file_name(crate_name: &str, crate_type: &str) -> String {
|
|||
assert!(file_name.contains(crate_name));
|
||||
file_name
|
||||
}
|
||||
|
||||
/// Similar to `get_file_name`, but converts any dashes (`-`) in the `crate_name` to
|
||||
/// underscores (`_`). This is specially made for the the rustc and cargo wrappers
|
||||
/// which have a dash in the name, and that is not allowed in a crate name.
|
||||
pub(crate) fn get_wrapper_file_name(crate_name: &str, crate_type: &str) -> String {
|
||||
let crate_name = crate_name.replace('-', "_");
|
||||
let wrapper_name = get_file_name(&crate_name, crate_type);
|
||||
wrapper_name.replace('_', "-")
|
||||
}
|
||||
|
|
619
compiler/rustc_codegen_cranelift/build_system/tests.rs
Normal file
619
compiler/rustc_codegen_cranelift/build_system/tests.rs
Normal file
|
@ -0,0 +1,619 @@
|
|||
use super::build_sysroot;
|
||||
use super::config;
|
||||
use super::rustc_info::get_wrapper_file_name;
|
||||
use super::utils::{spawn_and_wait, spawn_and_wait_with_input};
|
||||
use build_system::SysrootKind;
|
||||
use std::env;
|
||||
use std::ffi::OsStr;
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
|
||||
struct TestCase {
|
||||
config: &'static str,
|
||||
func: &'static dyn Fn(&TestRunner),
|
||||
}
|
||||
|
||||
impl TestCase {
|
||||
const fn new(config: &'static str, func: &'static dyn Fn(&TestRunner)) -> Self {
|
||||
Self { config, func }
|
||||
}
|
||||
}
|
||||
|
||||
const NO_SYSROOT_SUITE: &[TestCase] = &[
|
||||
TestCase::new("build.mini_core", &|runner| {
|
||||
runner.run_rustc([
|
||||
"example/mini_core.rs",
|
||||
"--crate-name",
|
||||
"mini_core",
|
||||
"--crate-type",
|
||||
"lib,dylib",
|
||||
"--target",
|
||||
&runner.target_triple,
|
||||
]);
|
||||
}),
|
||||
TestCase::new("build.example", &|runner| {
|
||||
runner.run_rustc([
|
||||
"example/example.rs",
|
||||
"--crate-type",
|
||||
"lib",
|
||||
"--target",
|
||||
&runner.target_triple,
|
||||
]);
|
||||
}),
|
||||
TestCase::new("jit.mini_core_hello_world", &|runner| {
|
||||
let mut jit_cmd = runner.rustc_command([
|
||||
"-Zunstable-options",
|
||||
"-Cllvm-args=mode=jit",
|
||||
"-Cprefer-dynamic",
|
||||
"example/mini_core_hello_world.rs",
|
||||
"--cfg",
|
||||
"jit",
|
||||
"--target",
|
||||
&runner.host_triple,
|
||||
]);
|
||||
jit_cmd.env("CG_CLIF_JIT_ARGS", "abc bcd");
|
||||
spawn_and_wait(jit_cmd);
|
||||
|
||||
eprintln!("[JIT-lazy] mini_core_hello_world");
|
||||
let mut jit_cmd = runner.rustc_command([
|
||||
"-Zunstable-options",
|
||||
"-Cllvm-args=mode=jit-lazy",
|
||||
"-Cprefer-dynamic",
|
||||
"example/mini_core_hello_world.rs",
|
||||
"--cfg",
|
||||
"jit",
|
||||
"--target",
|
||||
&runner.host_triple,
|
||||
]);
|
||||
jit_cmd.env("CG_CLIF_JIT_ARGS", "abc bcd");
|
||||
spawn_and_wait(jit_cmd);
|
||||
}),
|
||||
TestCase::new("aot.mini_core_hello_world", &|runner| {
|
||||
runner.run_rustc([
|
||||
"example/mini_core_hello_world.rs",
|
||||
"--crate-name",
|
||||
"mini_core_hello_world",
|
||||
"--crate-type",
|
||||
"bin",
|
||||
"-g",
|
||||
"--target",
|
||||
&runner.target_triple,
|
||||
]);
|
||||
runner.run_out_command("mini_core_hello_world", ["abc", "bcd"]);
|
||||
}),
|
||||
];
|
||||
|
||||
const BASE_SYSROOT_SUITE: &[TestCase] = &[
|
||||
TestCase::new("aot.arbitrary_self_types_pointers_and_wrappers", &|runner| {
|
||||
runner.run_rustc([
|
||||
"example/arbitrary_self_types_pointers_and_wrappers.rs",
|
||||
"--crate-name",
|
||||
"arbitrary_self_types_pointers_and_wrappers",
|
||||
"--crate-type",
|
||||
"bin",
|
||||
"--target",
|
||||
&runner.target_triple,
|
||||
]);
|
||||
runner.run_out_command("arbitrary_self_types_pointers_and_wrappers", []);
|
||||
}),
|
||||
TestCase::new("aot.issue_91827_extern_types", &|runner| {
|
||||
runner.run_rustc([
|
||||
"example/issue-91827-extern-types.rs",
|
||||
"--crate-name",
|
||||
"issue_91827_extern_types",
|
||||
"--crate-type",
|
||||
"bin",
|
||||
"--target",
|
||||
&runner.target_triple,
|
||||
]);
|
||||
runner.run_out_command("issue_91827_extern_types", []);
|
||||
}),
|
||||
TestCase::new("build.alloc_system", &|runner| {
|
||||
runner.run_rustc([
|
||||
"example/alloc_system.rs",
|
||||
"--crate-type",
|
||||
"lib",
|
||||
"--target",
|
||||
&runner.target_triple,
|
||||
]);
|
||||
}),
|
||||
TestCase::new("aot.alloc_example", &|runner| {
|
||||
runner.run_rustc([
|
||||
"example/alloc_example.rs",
|
||||
"--crate-type",
|
||||
"bin",
|
||||
"--target",
|
||||
&runner.target_triple,
|
||||
]);
|
||||
runner.run_out_command("alloc_example", []);
|
||||
}),
|
||||
TestCase::new("jit.std_example", &|runner| {
|
||||
runner.run_rustc([
|
||||
"-Zunstable-options",
|
||||
"-Cllvm-args=mode=jit",
|
||||
"-Cprefer-dynamic",
|
||||
"example/std_example.rs",
|
||||
"--target",
|
||||
&runner.host_triple,
|
||||
]);
|
||||
|
||||
eprintln!("[JIT-lazy] std_example");
|
||||
runner.run_rustc([
|
||||
"-Zunstable-options",
|
||||
"-Cllvm-args=mode=jit-lazy",
|
||||
"-Cprefer-dynamic",
|
||||
"example/std_example.rs",
|
||||
"--target",
|
||||
&runner.host_triple,
|
||||
]);
|
||||
}),
|
||||
TestCase::new("aot.std_example", &|runner| {
|
||||
runner.run_rustc([
|
||||
"example/std_example.rs",
|
||||
"--crate-type",
|
||||
"bin",
|
||||
"--target",
|
||||
&runner.target_triple,
|
||||
]);
|
||||
runner.run_out_command("std_example", ["arg"]);
|
||||
}),
|
||||
TestCase::new("aot.dst_field_align", &|runner| {
|
||||
runner.run_rustc([
|
||||
"example/dst-field-align.rs",
|
||||
"--crate-name",
|
||||
"dst_field_align",
|
||||
"--crate-type",
|
||||
"bin",
|
||||
"--target",
|
||||
&runner.target_triple,
|
||||
]);
|
||||
runner.run_out_command("dst_field_align", []);
|
||||
}),
|
||||
TestCase::new("aot.subslice-patterns-const-eval", &|runner| {
|
||||
runner.run_rustc([
|
||||
"example/subslice-patterns-const-eval.rs",
|
||||
"--crate-type",
|
||||
"bin",
|
||||
"-Cpanic=abort",
|
||||
"--target",
|
||||
&runner.target_triple,
|
||||
]);
|
||||
runner.run_out_command("subslice-patterns-const-eval", []);
|
||||
}),
|
||||
TestCase::new("aot.track-caller-attribute", &|runner| {
|
||||
runner.run_rustc([
|
||||
"example/track-caller-attribute.rs",
|
||||
"--crate-type",
|
||||
"bin",
|
||||
"-Cpanic=abort",
|
||||
"--target",
|
||||
&runner.target_triple,
|
||||
]);
|
||||
runner.run_out_command("track-caller-attribute", []);
|
||||
}),
|
||||
TestCase::new("aot.float-minmax-pass", &|runner| {
|
||||
runner.run_rustc([
|
||||
"example/float-minmax-pass.rs",
|
||||
"--crate-type",
|
||||
"bin",
|
||||
"-Cpanic=abort",
|
||||
"--target",
|
||||
&runner.target_triple,
|
||||
]);
|
||||
runner.run_out_command("float-minmax-pass", []);
|
||||
}),
|
||||
TestCase::new("aot.mod_bench", &|runner| {
|
||||
runner.run_rustc([
|
||||
"example/mod_bench.rs",
|
||||
"--crate-type",
|
||||
"bin",
|
||||
"--target",
|
||||
&runner.target_triple,
|
||||
]);
|
||||
runner.run_out_command("mod_bench", []);
|
||||
}),
|
||||
];
|
||||
|
||||
const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[
|
||||
TestCase::new("test.rust-random/rand", &|runner| {
|
||||
runner.in_dir(["rand"], |runner| {
|
||||
runner.run_cargo(["clean"]);
|
||||
|
||||
if runner.host_triple == runner.target_triple {
|
||||
eprintln!("[TEST] rust-random/rand");
|
||||
runner.run_cargo(["test", "--workspace"]);
|
||||
} else {
|
||||
eprintln!("[AOT] rust-random/rand");
|
||||
runner.run_cargo([
|
||||
"build",
|
||||
"--workspace",
|
||||
"--target",
|
||||
&runner.target_triple,
|
||||
"--tests",
|
||||
]);
|
||||
}
|
||||
});
|
||||
}),
|
||||
TestCase::new("bench.simple-raytracer", &|runner| {
|
||||
runner.in_dir(["simple-raytracer"], |runner| {
|
||||
let run_runs = env::var("RUN_RUNS").unwrap_or("10".to_string());
|
||||
|
||||
if runner.host_triple == runner.target_triple {
|
||||
eprintln!("[BENCH COMPILE] ebobby/simple-raytracer");
|
||||
let mut bench_compile = Command::new("hyperfine");
|
||||
bench_compile.arg("--runs");
|
||||
bench_compile.arg(&run_runs);
|
||||
bench_compile.arg("--warmup");
|
||||
bench_compile.arg("1");
|
||||
bench_compile.arg("--prepare");
|
||||
bench_compile.arg(format!("{:?}", runner.cargo_command(["clean"])));
|
||||
|
||||
if cfg!(windows) {
|
||||
bench_compile.arg("cmd /C \"set RUSTFLAGS= && cargo build\"");
|
||||
} else {
|
||||
bench_compile.arg("RUSTFLAGS='' cargo build");
|
||||
}
|
||||
|
||||
bench_compile.arg(format!("{:?}", runner.cargo_command(["build"])));
|
||||
spawn_and_wait(bench_compile);
|
||||
|
||||
eprintln!("[BENCH RUN] ebobby/simple-raytracer");
|
||||
fs::copy(PathBuf::from("./target/debug/main"), PathBuf::from("raytracer_cg_clif"))
|
||||
.unwrap();
|
||||
|
||||
let mut bench_run = Command::new("hyperfine");
|
||||
bench_run.arg("--runs");
|
||||
bench_run.arg(&run_runs);
|
||||
bench_run.arg(PathBuf::from("./raytracer_cg_llvm"));
|
||||
bench_run.arg(PathBuf::from("./raytracer_cg_clif"));
|
||||
spawn_and_wait(bench_run);
|
||||
} else {
|
||||
runner.run_cargo(["clean"]);
|
||||
eprintln!("[BENCH COMPILE] ebobby/simple-raytracer (skipped)");
|
||||
eprintln!("[COMPILE] ebobby/simple-raytracer");
|
||||
runner.run_cargo(["build", "--target", &runner.target_triple]);
|
||||
eprintln!("[BENCH RUN] ebobby/simple-raytracer (skipped)");
|
||||
}
|
||||
});
|
||||
}),
|
||||
TestCase::new("test.libcore", &|runner| {
|
||||
runner.in_dir(["build_sysroot", "sysroot_src", "library", "core", "tests"], |runner| {
|
||||
runner.run_cargo(["clean"]);
|
||||
|
||||
if runner.host_triple == runner.target_triple {
|
||||
runner.run_cargo(["test"]);
|
||||
} else {
|
||||
eprintln!("Cross-Compiling: Not running tests");
|
||||
runner.run_cargo(["build", "--target", &runner.target_triple, "--tests"]);
|
||||
}
|
||||
});
|
||||
}),
|
||||
TestCase::new("test.regex-shootout-regex-dna", &|runner| {
|
||||
runner.in_dir(["regex"], |runner| {
|
||||
runner.run_cargo(["clean"]);
|
||||
|
||||
// newer aho_corasick versions throw a deprecation warning
|
||||
let lint_rust_flags = format!("{} --cap-lints warn", runner.rust_flags);
|
||||
|
||||
let mut build_cmd = runner.cargo_command([
|
||||
"build",
|
||||
"--example",
|
||||
"shootout-regex-dna",
|
||||
"--target",
|
||||
&runner.target_triple,
|
||||
]);
|
||||
build_cmd.env("RUSTFLAGS", lint_rust_flags.clone());
|
||||
spawn_and_wait(build_cmd);
|
||||
|
||||
if runner.host_triple == runner.target_triple {
|
||||
let mut run_cmd = runner.cargo_command([
|
||||
"run",
|
||||
"--example",
|
||||
"shootout-regex-dna",
|
||||
"--target",
|
||||
&runner.target_triple,
|
||||
]);
|
||||
run_cmd.env("RUSTFLAGS", lint_rust_flags);
|
||||
|
||||
let input =
|
||||
fs::read_to_string(PathBuf::from("examples/regexdna-input.txt")).unwrap();
|
||||
let expected_path = PathBuf::from("examples/regexdna-output.txt");
|
||||
let expected = fs::read_to_string(&expected_path).unwrap();
|
||||
|
||||
let output = spawn_and_wait_with_input(run_cmd, input);
|
||||
// Make sure `[codegen mono items] start` doesn't poison the diff
|
||||
let output = output
|
||||
.lines()
|
||||
.filter(|line| !line.contains("codegen mono items"))
|
||||
.chain(Some("")) // This just adds the trailing newline
|
||||
.collect::<Vec<&str>>()
|
||||
.join("\r\n");
|
||||
|
||||
let output_matches = expected.lines().eq(output.lines());
|
||||
if !output_matches {
|
||||
let res_path = PathBuf::from("res.txt");
|
||||
fs::write(&res_path, &output).unwrap();
|
||||
|
||||
if cfg!(windows) {
|
||||
println!("Output files don't match!");
|
||||
println!("Expected Output:\n{}", expected);
|
||||
println!("Actual Output:\n{}", output);
|
||||
} else {
|
||||
let mut diff = Command::new("diff");
|
||||
diff.arg("-u");
|
||||
diff.arg(res_path);
|
||||
diff.arg(expected_path);
|
||||
spawn_and_wait(diff);
|
||||
}
|
||||
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
});
|
||||
}),
|
||||
TestCase::new("test.regex", &|runner| {
|
||||
runner.in_dir(["regex"], |runner| {
|
||||
runner.run_cargo(["clean"]);
|
||||
|
||||
// newer aho_corasick versions throw a deprecation warning
|
||||
let lint_rust_flags = format!("{} --cap-lints warn", runner.rust_flags);
|
||||
|
||||
if runner.host_triple == runner.target_triple {
|
||||
let mut run_cmd = runner.cargo_command([
|
||||
"test",
|
||||
"--tests",
|
||||
"--",
|
||||
"--exclude-should-panic",
|
||||
"--test-threads",
|
||||
"1",
|
||||
"-Zunstable-options",
|
||||
"-q",
|
||||
]);
|
||||
run_cmd.env("RUSTFLAGS", lint_rust_flags);
|
||||
spawn_and_wait(run_cmd);
|
||||
} else {
|
||||
eprintln!("Cross-Compiling: Not running tests");
|
||||
let mut build_cmd =
|
||||
runner.cargo_command(["build", "--tests", "--target", &runner.target_triple]);
|
||||
build_cmd.env("RUSTFLAGS", lint_rust_flags.clone());
|
||||
spawn_and_wait(build_cmd);
|
||||
}
|
||||
});
|
||||
}),
|
||||
TestCase::new("test.portable-simd", &|runner| {
|
||||
runner.in_dir(["portable-simd"], |runner| {
|
||||
runner.run_cargo(["clean"]);
|
||||
runner.run_cargo(["build", "--all-targets", "--target", &runner.target_triple]);
|
||||
|
||||
if runner.host_triple == runner.target_triple {
|
||||
runner.run_cargo(["test", "-q"]);
|
||||
}
|
||||
});
|
||||
}),
|
||||
];
|
||||
|
||||
pub(crate) fn run_tests(
|
||||
channel: &str,
|
||||
sysroot_kind: SysrootKind,
|
||||
target_dir: &Path,
|
||||
cg_clif_build_dir: &Path,
|
||||
host_triple: &str,
|
||||
target_triple: &str,
|
||||
) {
|
||||
let runner = TestRunner::new(host_triple.to_string(), target_triple.to_string());
|
||||
|
||||
if config::get_bool("testsuite.no_sysroot") {
|
||||
build_sysroot::build_sysroot(
|
||||
channel,
|
||||
SysrootKind::None,
|
||||
&target_dir,
|
||||
cg_clif_build_dir,
|
||||
&host_triple,
|
||||
&target_triple,
|
||||
);
|
||||
|
||||
let _ = fs::remove_dir_all(Path::new("target").join("out"));
|
||||
runner.run_testsuite(NO_SYSROOT_SUITE);
|
||||
} else {
|
||||
eprintln!("[SKIP] no_sysroot tests");
|
||||
}
|
||||
|
||||
let run_base_sysroot = config::get_bool("testsuite.base_sysroot");
|
||||
let run_extended_sysroot = config::get_bool("testsuite.extended_sysroot");
|
||||
|
||||
if run_base_sysroot || run_extended_sysroot {
|
||||
build_sysroot::build_sysroot(
|
||||
channel,
|
||||
sysroot_kind,
|
||||
&target_dir,
|
||||
cg_clif_build_dir,
|
||||
&host_triple,
|
||||
&target_triple,
|
||||
);
|
||||
}
|
||||
|
||||
if run_base_sysroot {
|
||||
runner.run_testsuite(BASE_SYSROOT_SUITE);
|
||||
} else {
|
||||
eprintln!("[SKIP] base_sysroot tests");
|
||||
}
|
||||
|
||||
if run_extended_sysroot {
|
||||
runner.run_testsuite(EXTENDED_SYSROOT_SUITE);
|
||||
} else {
|
||||
eprintln!("[SKIP] extended_sysroot tests");
|
||||
}
|
||||
}
|
||||
|
||||
struct TestRunner {
|
||||
root_dir: PathBuf,
|
||||
out_dir: PathBuf,
|
||||
jit_supported: bool,
|
||||
rust_flags: String,
|
||||
run_wrapper: Vec<String>,
|
||||
host_triple: String,
|
||||
target_triple: String,
|
||||
}
|
||||
|
||||
impl TestRunner {
|
||||
pub fn new(host_triple: String, target_triple: String) -> Self {
|
||||
let root_dir = env::current_dir().unwrap();
|
||||
|
||||
let mut out_dir = root_dir.clone();
|
||||
out_dir.push("target");
|
||||
out_dir.push("out");
|
||||
|
||||
let is_native = host_triple == target_triple;
|
||||
let jit_supported =
|
||||
target_triple.contains("x86_64") && is_native && !host_triple.contains("windows");
|
||||
|
||||
let mut rust_flags = env::var("RUSTFLAGS").ok().unwrap_or("".to_string());
|
||||
let mut run_wrapper = Vec::new();
|
||||
|
||||
if !is_native {
|
||||
match target_triple.as_str() {
|
||||
"aarch64-unknown-linux-gnu" => {
|
||||
// We are cross-compiling for aarch64. Use the correct linker and run tests in qemu.
|
||||
rust_flags = format!("-Clinker=aarch64-linux-gnu-gcc{}", rust_flags);
|
||||
run_wrapper = vec!["qemu-aarch64", "-L", "/usr/aarch64-linux-gnu"];
|
||||
}
|
||||
"x86_64-pc-windows-gnu" => {
|
||||
// We are cross-compiling for Windows. Run tests in wine.
|
||||
run_wrapper = vec!["wine"];
|
||||
}
|
||||
_ => {
|
||||
println!("Unknown non-native platform");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME fix `#[linkage = "extern_weak"]` without this
|
||||
if host_triple.contains("darwin") {
|
||||
rust_flags = format!("{} -Clink-arg=-undefined -Clink-arg=dynamic_lookup", rust_flags);
|
||||
}
|
||||
|
||||
Self {
|
||||
root_dir,
|
||||
out_dir,
|
||||
jit_supported,
|
||||
rust_flags,
|
||||
run_wrapper: run_wrapper.iter().map(|s| s.to_string()).collect(),
|
||||
host_triple,
|
||||
target_triple,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_testsuite(&self, tests: &[TestCase]) {
|
||||
for &TestCase { config, func } in tests {
|
||||
let (tag, testname) = config.split_once('.').unwrap();
|
||||
let tag = tag.to_uppercase();
|
||||
let is_jit_test = tag == "JIT";
|
||||
|
||||
if !config::get_bool(config) || (is_jit_test && !self.jit_supported) {
|
||||
eprintln!("[{tag}] {testname} (skipped)");
|
||||
continue;
|
||||
} else {
|
||||
eprintln!("[{tag}] {testname}");
|
||||
}
|
||||
|
||||
func(self);
|
||||
}
|
||||
}
|
||||
|
||||
fn in_dir<'a, I, F>(&self, dir: I, callback: F)
|
||||
where
|
||||
I: IntoIterator<Item = &'a str>,
|
||||
F: FnOnce(&TestRunner),
|
||||
{
|
||||
let current = env::current_dir().unwrap();
|
||||
let mut new = current.clone();
|
||||
for d in dir {
|
||||
new.push(d);
|
||||
}
|
||||
|
||||
env::set_current_dir(new).unwrap();
|
||||
callback(self);
|
||||
env::set_current_dir(current).unwrap();
|
||||
}
|
||||
|
||||
fn rustc_command<I, S>(&self, args: I) -> Command
|
||||
where
|
||||
I: IntoIterator<Item = S>,
|
||||
S: AsRef<OsStr>,
|
||||
{
|
||||
let mut rustc_clif = self.root_dir.clone();
|
||||
rustc_clif.push("build");
|
||||
rustc_clif.push(get_wrapper_file_name("rustc-clif", "bin"));
|
||||
|
||||
let mut cmd = Command::new(rustc_clif);
|
||||
cmd.args(self.rust_flags.split_whitespace());
|
||||
cmd.arg("-L");
|
||||
cmd.arg(format!("crate={}", self.out_dir.display()));
|
||||
cmd.arg("--out-dir");
|
||||
cmd.arg(format!("{}", self.out_dir.display()));
|
||||
cmd.arg("-Cdebuginfo=2");
|
||||
cmd.args(args);
|
||||
cmd
|
||||
}
|
||||
|
||||
fn run_rustc<I, S>(&self, args: I)
|
||||
where
|
||||
I: IntoIterator<Item = S>,
|
||||
S: AsRef<OsStr>,
|
||||
{
|
||||
spawn_and_wait(self.rustc_command(args));
|
||||
}
|
||||
|
||||
fn run_out_command<'a, I>(&self, name: &str, args: I)
|
||||
where
|
||||
I: IntoIterator<Item = &'a str>,
|
||||
{
|
||||
let mut full_cmd = vec![];
|
||||
|
||||
// Prepend the RUN_WRAPPER's
|
||||
if !self.run_wrapper.is_empty() {
|
||||
full_cmd.extend(self.run_wrapper.iter().cloned());
|
||||
}
|
||||
|
||||
full_cmd.push({
|
||||
let mut out_path = self.out_dir.clone();
|
||||
out_path.push(name);
|
||||
out_path.to_str().unwrap().to_string()
|
||||
});
|
||||
|
||||
for arg in args.into_iter() {
|
||||
full_cmd.push(arg.to_string());
|
||||
}
|
||||
|
||||
let mut cmd_iter = full_cmd.into_iter();
|
||||
let first = cmd_iter.next().unwrap();
|
||||
|
||||
let mut cmd = Command::new(first);
|
||||
cmd.args(cmd_iter);
|
||||
|
||||
spawn_and_wait(cmd);
|
||||
}
|
||||
|
||||
fn cargo_command<I, S>(&self, args: I) -> Command
|
||||
where
|
||||
I: IntoIterator<Item = S>,
|
||||
S: AsRef<OsStr>,
|
||||
{
|
||||
let mut cargo_clif = self.root_dir.clone();
|
||||
cargo_clif.push("build");
|
||||
cargo_clif.push(get_wrapper_file_name("cargo-clif", "bin"));
|
||||
|
||||
let mut cmd = Command::new(cargo_clif);
|
||||
cmd.args(args);
|
||||
cmd.env("RUSTFLAGS", &self.rust_flags);
|
||||
cmd
|
||||
}
|
||||
|
||||
fn run_cargo<'a, I>(&self, args: I)
|
||||
where
|
||||
I: IntoIterator<Item = &'a str>,
|
||||
{
|
||||
spawn_and_wait(self.cargo_command(args));
|
||||
}
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
use std::env;
|
||||
use std::fs;
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
use std::process::{self, Command};
|
||||
use std::process::{self, Command, Stdio};
|
||||
|
||||
#[track_caller]
|
||||
pub(crate) fn try_hard_link(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
|
||||
|
@ -18,6 +20,27 @@ pub(crate) fn spawn_and_wait(mut cmd: Command) {
|
|||
}
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
pub(crate) fn spawn_and_wait_with_input(mut cmd: Command, input: String) -> String {
|
||||
let mut child = cmd
|
||||
.stdin(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
.expect("Failed to spawn child process");
|
||||
|
||||
let mut stdin = child.stdin.take().expect("Failed to open stdin");
|
||||
std::thread::spawn(move || {
|
||||
stdin.write_all(input.as_bytes()).expect("Failed to write to stdin");
|
||||
});
|
||||
|
||||
let output = child.wait_with_output().expect("Failed to read stdout");
|
||||
if !output.status.success() {
|
||||
process::exit(1);
|
||||
}
|
||||
|
||||
String::from_utf8(output.stdout).unwrap()
|
||||
}
|
||||
|
||||
pub(crate) fn copy_dir_recursively(from: &Path, to: &Path) {
|
||||
for entry in fs::read_dir(from).unwrap() {
|
||||
let entry = entry.unwrap();
|
||||
|
@ -33,3 +56,7 @@ pub(crate) fn copy_dir_recursively(from: &Path, to: &Path) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn is_ci() -> bool {
|
||||
env::var("CI").as_ref().map(|val| &**val) == Ok("true")
|
||||
}
|
||||
|
|
|
@ -3,4 +3,4 @@ set -e
|
|||
|
||||
rm -rf build_sysroot/{sysroot_src/,target/,compiler-builtins/,rustc_version}
|
||||
rm -rf target/ build/ perf.data{,.old} y.bin
|
||||
rm -rf rand/ regex/ simple-raytracer/ portable-simd/
|
||||
rm -rf rand/ regex/ simple-raytracer/ portable-simd/ abi-checker/
|
||||
|
|
|
@ -15,3 +15,38 @@
|
|||
# This option can be changed while the build system is already running for as long as sysroot
|
||||
# building hasn't started yet.
|
||||
#keep_sysroot
|
||||
|
||||
|
||||
# Testsuite
|
||||
#
|
||||
# Each test suite item has a corresponding key here. The default is to run all tests.
|
||||
# Comment any of these lines to skip individual tests.
|
||||
|
||||
testsuite.no_sysroot
|
||||
build.mini_core
|
||||
build.example
|
||||
jit.mini_core_hello_world
|
||||
aot.mini_core_hello_world
|
||||
|
||||
testsuite.base_sysroot
|
||||
aot.arbitrary_self_types_pointers_and_wrappers
|
||||
aot.issue_91827_extern_types
|
||||
build.alloc_system
|
||||
aot.alloc_example
|
||||
jit.std_example
|
||||
aot.std_example
|
||||
aot.dst_field_align
|
||||
aot.subslice-patterns-const-eval
|
||||
aot.track-caller-attribute
|
||||
aot.float-minmax-pass
|
||||
aot.mod_bench
|
||||
|
||||
testsuite.extended_sysroot
|
||||
test.rust-random/rand
|
||||
bench.simple-raytracer
|
||||
test.libcore
|
||||
test.regex-shootout-regex-dna
|
||||
test.regex
|
||||
test.portable-simd
|
||||
|
||||
testsuite.abi-checker
|
||||
|
|
|
@ -94,7 +94,7 @@ mod platform {
|
|||
struct Header(*mut u8);
|
||||
const HEAP_ZERO_MEMORY: DWORD = 0x00000008;
|
||||
unsafe fn get_header<'a>(ptr: *mut u8) -> &'a mut Header {
|
||||
&mut *(ptr as *mut Header).offset(-1)
|
||||
&mut *(ptr as *mut Header).sub(1)
|
||||
}
|
||||
unsafe fn align_ptr(ptr: *mut u8, align: usize) -> *mut u8 {
|
||||
let aligned = ptr.add(align - (ptr as usize & (align - 1)));
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue