mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Merge from rustc
This commit is contained in:
commit
d8be714fee
6
.github/workflows/ci.yml
vendored
6
.github/workflows/ci.yml
vendored
@ -166,7 +166,7 @@ jobs:
|
||||
run: src/ci/scripts/create-doc-artifacts.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: upload artifacts to github
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: "${{ env.DOC_ARTIFACT_NAME }}"
|
||||
path: obj/artifacts/doc
|
||||
@ -576,7 +576,7 @@ jobs:
|
||||
run: src/ci/scripts/create-doc-artifacts.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: upload artifacts to github
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: "${{ env.DOC_ARTIFACT_NAME }}"
|
||||
path: obj/artifacts/doc
|
||||
@ -715,7 +715,7 @@ jobs:
|
||||
run: src/ci/scripts/create-doc-artifacts.sh
|
||||
if: success() && !env.SKIP_JOB
|
||||
- name: upload artifacts to github
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: "${{ env.DOC_ARTIFACT_NAME }}"
|
||||
path: obj/artifacts/doc
|
||||
|
4
.github/workflows/dependencies.yml
vendored
4
.github/workflows/dependencies.yml
vendored
@ -70,13 +70,13 @@ jobs:
|
||||
cargo update 2>&1 | sed '/crates.io index/d' | tee -a cargo_update.log
|
||||
git status --porcelain | grep -q Cargo.lock || gh run cancel ${{ github.run_id }}
|
||||
- name: upload Cargo.lock artifact for use in PR
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Cargo-lock
|
||||
path: Cargo.lock
|
||||
retention-days: 1
|
||||
- name: upload cargo-update log artifact for use in PR
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: cargo-updates
|
||||
path: cargo_update.log
|
||||
|
159
Cargo.lock
159
Cargo.lock
@ -49,9 +49,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.2"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
|
||||
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
@ -246,7 +246,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -272,9 +272,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.69"
|
||||
version = "0.3.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837"
|
||||
checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cc",
|
||||
@ -317,9 +317,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.4.2"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
|
||||
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
@ -400,9 +400,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.5.0"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
|
||||
checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9"
|
||||
|
||||
[[package]]
|
||||
name = "camino"
|
||||
@ -428,9 +428,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cargo-platform"
|
||||
version = "0.1.7"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "694c8807f2ae16faecc43dc17d74b3eb042482789fd0eb64b39a2e04e087053f"
|
||||
checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
@ -563,7 +563,7 @@ dependencies = [
|
||||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -590,7 +590,7 @@ dependencies = [
|
||||
"regex",
|
||||
"rustc_tools_util",
|
||||
"serde",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.55",
|
||||
"tempfile",
|
||||
"termize",
|
||||
"tester",
|
||||
@ -949,7 +949,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim 0.10.0",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -960,7 +960,7 @@ checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -975,7 +975,7 @@ version = "0.1.79"
|
||||
dependencies = [
|
||||
"itertools 0.12.1",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1016,7 +1016,7 @@ dependencies = [
|
||||
"darling",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1026,7 +1026,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "206868b8242f27cecce124c19fd88157fbd0dd334df2587f36417bafbc85097b"
|
||||
dependencies = [
|
||||
"derive_builder_core",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1049,7 +1049,7 @@ dependencies = [
|
||||
"darling",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1138,7 +1138,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1293,9 +1293,9 @@ checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "2.0.1"
|
||||
version = "2.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
|
||||
checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984"
|
||||
|
||||
[[package]]
|
||||
name = "field-offset"
|
||||
@ -1484,7 +1484,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1922,7 +1922,7 @@ checksum = "d2abdd3a62551e8337af119c5899e600ca0c88ec8f23a46c60ba216c803dcf1a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1972,9 +1972,9 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.2.5"
|
||||
version = "2.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4"
|
||||
checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
@ -2205,7 +2205,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets 0.48.5",
|
||||
"windows-targets 0.52.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2220,16 +2220,16 @@ version = "0.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8"
|
||||
dependencies = [
|
||||
"bitflags 2.4.2",
|
||||
"bitflags 2.5.0",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libz-sys"
|
||||
version = "1.1.15"
|
||||
version = "1.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "037731f5d3aaa87a5675e895b63ddff1a87624bc29f77004ea829809654e48f6"
|
||||
checksum = "5e143b5e666b2695d28f6bca6497720813f699c9602dd7f5cac91008b8ada7f9"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
@ -2546,7 +2546,7 @@ version = "0.28.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4"
|
||||
dependencies = [
|
||||
"bitflags 2.4.2",
|
||||
"bitflags 2.5.0",
|
||||
"cfg-if",
|
||||
"cfg_aliases",
|
||||
"libc",
|
||||
@ -2683,7 +2683,7 @@ version = "0.10.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f"
|
||||
dependencies = [
|
||||
"bitflags 2.4.2",
|
||||
"bitflags 2.5.0",
|
||||
"cfg-if",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
@ -2700,7 +2700,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2893,7 +2893,7 @@ dependencies = [
|
||||
"pest_meta",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3055,7 +3055,7 @@ version = "0.9.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b"
|
||||
dependencies = [
|
||||
"bitflags 2.4.2",
|
||||
"bitflags 2.5.0",
|
||||
"memchr",
|
||||
"unicase",
|
||||
]
|
||||
@ -3066,7 +3066,7 @@ version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dce76ce678ffc8e5675b22aa1405de0b7037e2fdf8913fea40d1926c6fe1e6e7"
|
||||
dependencies = [
|
||||
"bitflags 2.4.2",
|
||||
"bitflags 2.5.0",
|
||||
"memchr",
|
||||
"pulldown-cmark-escape",
|
||||
"unicase",
|
||||
@ -3170,9 +3170,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.9.0"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e4963ed1bc86e4f3ee217022bd855b297cef07fb9eac5dfa1f788b220b49b3bd"
|
||||
checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
|
||||
dependencies = [
|
||||
"either",
|
||||
"rayon-core",
|
||||
@ -3285,9 +3285,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.11.26"
|
||||
version = "0.11.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78bf93c4af7a8bb7d879d51cebe797356ff10ae8516ace542b5182d9dcac10b2"
|
||||
checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bytes",
|
||||
@ -3448,7 +3448,7 @@ dependencies = [
|
||||
name = "rustc_abi"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bitflags 2.4.2",
|
||||
"bitflags 2.5.0",
|
||||
"rand",
|
||||
"rand_xoshiro",
|
||||
"rustc_data_structures",
|
||||
@ -3479,7 +3479,7 @@ dependencies = [
|
||||
name = "rustc_ast"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bitflags 2.4.2",
|
||||
"bitflags 2.5.0",
|
||||
"memchr",
|
||||
"rustc_ast_ir",
|
||||
"rustc_data_structures",
|
||||
@ -3642,7 +3642,7 @@ dependencies = [
|
||||
name = "rustc_codegen_llvm"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bitflags 2.4.2",
|
||||
"bitflags 2.5.0",
|
||||
"itertools 0.12.1",
|
||||
"libc",
|
||||
"measureme",
|
||||
@ -3677,7 +3677,7 @@ name = "rustc_codegen_ssa"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"ar_archive_writer",
|
||||
"bitflags 2.4.2",
|
||||
"bitflags 2.5.0",
|
||||
"cc",
|
||||
"itertools 0.12.1",
|
||||
"jobserver",
|
||||
@ -3746,7 +3746,7 @@ name = "rustc_data_structures"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"bitflags 2.4.2",
|
||||
"bitflags 2.5.0",
|
||||
"either",
|
||||
"elsa",
|
||||
"ena",
|
||||
@ -3929,7 +3929,7 @@ dependencies = [
|
||||
"fluent-syntax",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.55",
|
||||
"unic-langid",
|
||||
]
|
||||
|
||||
@ -4064,7 +4064,7 @@ version = "0.0.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.55",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
@ -4210,7 +4210,7 @@ version = "0.0.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.55",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
@ -4218,7 +4218,7 @@ dependencies = [
|
||||
name = "rustc_metadata"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bitflags 2.4.2",
|
||||
"bitflags 2.5.0",
|
||||
"libloading",
|
||||
"odht",
|
||||
"rustc_ast",
|
||||
@ -4248,7 +4248,7 @@ dependencies = [
|
||||
name = "rustc_middle"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bitflags 2.4.2",
|
||||
"bitflags 2.5.0",
|
||||
"derivative",
|
||||
"either",
|
||||
"field-offset",
|
||||
@ -4385,7 +4385,7 @@ dependencies = [
|
||||
name = "rustc_parse"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bitflags 2.4.2",
|
||||
"bitflags 2.5.0",
|
||||
"rustc_ast",
|
||||
"rustc_ast_pretty",
|
||||
"rustc_data_structures",
|
||||
@ -4525,7 +4525,7 @@ dependencies = [
|
||||
name = "rustc_resolve"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bitflags 2.4.2",
|
||||
"bitflags 2.5.0",
|
||||
"pulldown-cmark 0.9.6",
|
||||
"rustc_arena",
|
||||
"rustc_ast",
|
||||
@ -4564,7 +4564,7 @@ dependencies = [
|
||||
name = "rustc_session"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bitflags 2.4.2",
|
||||
"bitflags 2.5.0",
|
||||
"getopts",
|
||||
"libc",
|
||||
"rustc_ast",
|
||||
@ -4624,7 +4624,7 @@ dependencies = [
|
||||
name = "rustc_symbol_mangling"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bitflags 2.4.2",
|
||||
"bitflags 2.5.0",
|
||||
"punycode",
|
||||
"rustc-demangle",
|
||||
"rustc_data_structures",
|
||||
@ -4634,6 +4634,7 @@ dependencies = [
|
||||
"rustc_session",
|
||||
"rustc_span",
|
||||
"rustc_target",
|
||||
"rustc_trait_selection",
|
||||
"tracing",
|
||||
"twox-hash",
|
||||
]
|
||||
@ -4642,7 +4643,7 @@ dependencies = [
|
||||
name = "rustc_target"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bitflags 2.4.2",
|
||||
"bitflags 2.5.0",
|
||||
"object 0.32.2",
|
||||
"rustc_abi",
|
||||
"rustc_data_structures",
|
||||
@ -4666,7 +4667,7 @@ checksum = "8ba09476327c4b70ccefb6180f046ef588c26a24cf5d269a9feba316eb4f029f"
|
||||
name = "rustc_trait_selection"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bitflags 2.4.2",
|
||||
"bitflags 2.5.0",
|
||||
"itertools 0.12.1",
|
||||
"rustc_ast",
|
||||
"rustc_ast_ir",
|
||||
@ -4745,7 +4746,7 @@ dependencies = [
|
||||
name = "rustc_type_ir"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bitflags 2.4.2",
|
||||
"bitflags 2.5.0",
|
||||
"derivative",
|
||||
"rustc_ast_ir",
|
||||
"rustc_data_structures",
|
||||
@ -4838,7 +4839,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4873,11 +4874,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.31"
|
||||
version = "0.38.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949"
|
||||
checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89"
|
||||
dependencies = [
|
||||
"bitflags 2.4.2",
|
||||
"bitflags 2.5.0",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
@ -5021,7 +5022,7 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -5117,9 +5118,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.13.1"
|
||||
version = "1.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
|
||||
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||
|
||||
[[package]]
|
||||
name = "snap"
|
||||
@ -5328,9 +5329,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.53"
|
||||
version = "2.0.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032"
|
||||
checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -5351,7 +5352,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -5530,7 +5531,7 @@ checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -5753,7 +5754,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -5970,7 +5971,7 @@ checksum = "fea2a4c80deb4fb3ca51f66b5e2dd91e3642bbce52234bcf22e41668281208e4"
|
||||
dependencies = [
|
||||
"proc-macro-hack",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.55",
|
||||
"unic-langid-impl",
|
||||
]
|
||||
|
||||
@ -6126,9 +6127,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.7.0"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a"
|
||||
checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
@ -6202,7 +6203,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.55",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@ -6236,7 +6237,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.55",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
@ -6327,7 +6328,7 @@ dependencies = [
|
||||
"rayon",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.55",
|
||||
"windows-metadata",
|
||||
]
|
||||
|
||||
@ -6581,7 +6582,7 @@ checksum = "9e6936f0cce458098a201c245a11bef556c6a0181129c7034d10d76d1ec3a2b8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.55",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
@ -6602,7 +6603,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -6622,7 +6623,7 @@ checksum = "e6a647510471d372f2e6c2e6b7219e44d8c574d24fdc11c610a61455782f18c3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.55",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
@ -6645,7 +6646,7 @@ checksum = "7b4e5997cbf58990550ef1f0e5124a05e47e1ebd33a84af25739be6031a62c20"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.55",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4,7 +4,6 @@ use crate::session_diagnostics::{
|
||||
CaptureArgLabel, CaptureReasonLabel, CaptureReasonNote, CaptureReasonSuggest, CaptureVarCause,
|
||||
CaptureVarKind, CaptureVarPathUseCause, OnClosureNote,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use rustc_errors::{Applicability, Diag};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{CtorKind, Namespace};
|
||||
@ -226,16 +225,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
}
|
||||
} else {
|
||||
if autoderef_index.is_none() {
|
||||
autoderef_index =
|
||||
match place.projection.into_iter().rev().find_position(|elem| {
|
||||
!matches!(
|
||||
elem,
|
||||
ProjectionElem::Deref | ProjectionElem::Downcast(..)
|
||||
)
|
||||
}) {
|
||||
Some((index, _)) => Some(place.projection.len() - index),
|
||||
None => Some(0),
|
||||
};
|
||||
autoderef_index = match place.projection.iter().rposition(|elem| {
|
||||
!matches!(
|
||||
elem,
|
||||
ProjectionElem::Deref | ProjectionElem::Downcast(..)
|
||||
)
|
||||
}) {
|
||||
Some(index) => Some(index + 1),
|
||||
None => Some(0),
|
||||
};
|
||||
}
|
||||
if index >= autoderef_index.unwrap() {
|
||||
buf.insert(0, '*');
|
||||
|
@ -541,7 +541,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
|
||||
let builtin_unreachable: RValue<'gcc> = unsafe {
|
||||
std::mem::transmute(builtin_unreachable)
|
||||
};
|
||||
self.call(self.type_void(), None, None, builtin_unreachable, &[], None);
|
||||
self.call(self.type_void(), None, None, builtin_unreachable, &[], None, None);
|
||||
}
|
||||
|
||||
// Write results to outputs.
|
||||
|
@ -25,7 +25,7 @@ use rustc_middle::ty::layout::{
|
||||
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError, LayoutOfHelpers,
|
||||
TyAndLayout,
|
||||
};
|
||||
use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{ParamEnv, Ty, TyCtxt, Instance};
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::Span;
|
||||
use rustc_target::abi::{
|
||||
@ -592,12 +592,13 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
|
||||
then: Block<'gcc>,
|
||||
catch: Block<'gcc>,
|
||||
_funclet: Option<&Funclet>,
|
||||
instance: Option<Instance<'tcx>>,
|
||||
) -> RValue<'gcc> {
|
||||
let try_block = self.current_func().new_block("try");
|
||||
|
||||
let current_block = self.block.clone();
|
||||
self.block = try_block;
|
||||
let call = self.call(typ, fn_attrs, None, func, args, None); // TODO(antoyo): use funclet here?
|
||||
let call = self.call(typ, fn_attrs, None, func, args, None, instance); // TODO(antoyo): use funclet here?
|
||||
self.block = current_block;
|
||||
|
||||
let return_value =
|
||||
@ -1667,6 +1668,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
|
||||
func: RValue<'gcc>,
|
||||
args: &[RValue<'gcc>],
|
||||
funclet: Option<&Funclet>,
|
||||
_instance: Option<Instance<'tcx>>,
|
||||
) -> RValue<'gcc> {
|
||||
// FIXME(antoyo): remove when having a proper API.
|
||||
let gcc_func = unsafe { std::mem::transmute(func) };
|
||||
|
@ -1,11 +1,11 @@
|
||||
use rustc_codegen_ssa::traits::CoverageInfoBuilderMethods;
|
||||
use rustc_middle::mir::Coverage;
|
||||
use rustc_middle::mir::coverage::CoverageKind;
|
||||
use rustc_middle::ty::Instance;
|
||||
|
||||
use crate::builder::Builder;
|
||||
|
||||
impl<'a, 'gcc, 'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
|
||||
fn add_coverage(&mut self, _instance: Instance<'tcx>, _coverage: &Coverage) {
|
||||
fn add_coverage(&mut self, _instance: Instance<'tcx>, _kind: &CoverageKind) {
|
||||
// TODO(antoyo)
|
||||
}
|
||||
}
|
||||
|
@ -133,6 +133,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
|
||||
func,
|
||||
&args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(),
|
||||
None,
|
||||
None,
|
||||
)
|
||||
}
|
||||
sym::likely => self.expect(args[0].immediate(), true),
|
||||
@ -401,7 +402,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
|
||||
fn abort(&mut self) {
|
||||
let func = self.context.get_builtin_function("abort");
|
||||
let func: RValue<'gcc> = unsafe { std::mem::transmute(func) };
|
||||
self.call(self.type_void(), None, None, func, &[], None);
|
||||
self.call(self.type_void(), None, None, func, &[], None, None);
|
||||
}
|
||||
|
||||
fn assume(&mut self, value: Self::Value) {
|
||||
@ -1103,7 +1104,7 @@ fn try_intrinsic<'a, 'b, 'gcc, 'tcx>(
|
||||
dest: RValue<'gcc>,
|
||||
) {
|
||||
if bx.sess().panic_strategy() == PanicStrategy::Abort {
|
||||
bx.call(bx.type_void(), None, None, try_func, &[data], None);
|
||||
bx.call(bx.type_void(), None, None, try_func, &[data], None, None);
|
||||
// Return 0 unconditionally from the intrinsic call;
|
||||
// we can never unwind.
|
||||
let ret_align = bx.tcx.data_layout.i32_align.abi;
|
||||
@ -1177,21 +1178,21 @@ fn codegen_gnu_try<'gcc>(
|
||||
let zero = bx.cx.context.new_rvalue_zero(bx.int_type);
|
||||
let ptr = bx.cx.context.new_call(None, eh_pointer_builtin, &[zero]);
|
||||
let catch_ty = bx.type_func(&[bx.type_i8p(), bx.type_i8p()], bx.type_void());
|
||||
bx.call(catch_ty, None, None, catch_func, &[data, ptr], None);
|
||||
bx.call(catch_ty, None, None, catch_func, &[data, ptr], None, None);
|
||||
bx.ret(bx.const_i32(1));
|
||||
|
||||
// NOTE: the blocks must be filled before adding the try/catch, otherwise gcc will not
|
||||
// generate a try/catch.
|
||||
// FIXME(antoyo): add a check in the libgccjit API to prevent this.
|
||||
bx.switch_to_block(current_block);
|
||||
bx.invoke(try_func_ty, None, None, try_func, &[data], then, catch, None);
|
||||
bx.invoke(try_func_ty, None, None, try_func, &[data], then, catch, None, None);
|
||||
});
|
||||
|
||||
let func = unsafe { std::mem::transmute(func) };
|
||||
|
||||
// Note that no invoke is used here because by definition this function
|
||||
// can't panic (that's what it's catching).
|
||||
let ret = bx.call(llty, None, None, func, &[try_func, data, catch_func], None);
|
||||
let ret = bx.call(llty, None, None, func, &[try_func, data, catch_func], None, None);
|
||||
let i32_align = bx.tcx().data_layout.i32_align.abi;
|
||||
bx.store(ret, dest, i32_align);
|
||||
}
|
||||
|
@ -466,11 +466,11 @@ pub(crate) fn inline_asm_call<'ll>(
|
||||
|
||||
let call = if !labels.is_empty() {
|
||||
assert!(catch_funclet.is_none());
|
||||
bx.callbr(fty, None, None, v, inputs, dest.unwrap(), labels, None)
|
||||
bx.callbr(fty, None, None, v, inputs, dest.unwrap(), labels, None, None)
|
||||
} else if let Some((catch, funclet)) = catch_funclet {
|
||||
bx.invoke(fty, None, None, v, inputs, dest.unwrap(), catch, funclet)
|
||||
bx.invoke(fty, None, None, v, inputs, dest.unwrap(), catch, funclet, None)
|
||||
} else {
|
||||
bx.call(fty, None, None, v, inputs, None)
|
||||
bx.call(fty, None, None, v, inputs, None, None)
|
||||
};
|
||||
|
||||
// Store mark in a metadata node so we can map LLVM errors
|
||||
|
@ -19,9 +19,12 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
|
||||
use rustc_middle::ty::layout::{
|
||||
FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers, TyAndLayout,
|
||||
};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
|
||||
use rustc_span::Span;
|
||||
use rustc_symbol_mangling::typeid::{kcfi_typeid_for_fnabi, typeid_for_fnabi, TypeIdOptions};
|
||||
use rustc_symbol_mangling::typeid::{
|
||||
kcfi_typeid_for_fnabi, kcfi_typeid_for_instance, typeid_for_fnabi, typeid_for_instance,
|
||||
TypeIdOptions,
|
||||
};
|
||||
use rustc_target::abi::{self, call::FnAbi, Align, Size, WrappingRange};
|
||||
use rustc_target::spec::{HasTargetSpec, SanitizerSet, Target};
|
||||
use smallvec::SmallVec;
|
||||
@ -221,6 +224,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
||||
then: &'ll BasicBlock,
|
||||
catch: &'ll BasicBlock,
|
||||
funclet: Option<&Funclet<'ll>>,
|
||||
instance: Option<Instance<'tcx>>,
|
||||
) -> &'ll Value {
|
||||
debug!("invoke {:?} with args ({:?})", llfn, args);
|
||||
|
||||
@ -233,10 +237,10 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
||||
}
|
||||
|
||||
// Emit CFI pointer type membership test
|
||||
self.cfi_type_test(fn_attrs, fn_abi, llfn);
|
||||
self.cfi_type_test(fn_attrs, fn_abi, instance, llfn);
|
||||
|
||||
// Emit KCFI operand bundle
|
||||
let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, llfn);
|
||||
let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, instance, llfn);
|
||||
let kcfi_bundle = kcfi_bundle.as_ref().map(|b| &*b.raw);
|
||||
if let Some(kcfi_bundle) = kcfi_bundle {
|
||||
bundles.push(kcfi_bundle);
|
||||
@ -1231,6 +1235,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
||||
llfn: &'ll Value,
|
||||
args: &[&'ll Value],
|
||||
funclet: Option<&Funclet<'ll>>,
|
||||
instance: Option<Instance<'tcx>>,
|
||||
) -> &'ll Value {
|
||||
debug!("call {:?} with args ({:?})", llfn, args);
|
||||
|
||||
@ -1243,10 +1248,10 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
||||
}
|
||||
|
||||
// Emit CFI pointer type membership test
|
||||
self.cfi_type_test(fn_attrs, fn_abi, llfn);
|
||||
self.cfi_type_test(fn_attrs, fn_abi, instance, llfn);
|
||||
|
||||
// Emit KCFI operand bundle
|
||||
let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, llfn);
|
||||
let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, instance, llfn);
|
||||
let kcfi_bundle = kcfi_bundle.as_ref().map(|b| &*b.raw);
|
||||
if let Some(kcfi_bundle) = kcfi_bundle {
|
||||
bundles.push(kcfi_bundle);
|
||||
@ -1468,7 +1473,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
|
||||
|
||||
pub(crate) fn call_intrinsic(&mut self, intrinsic: &str, args: &[&'ll Value]) -> &'ll Value {
|
||||
let (ty, f) = self.cx.get_intrinsic(intrinsic);
|
||||
self.call(ty, None, None, f, args, None)
|
||||
self.call(ty, None, None, f, args, None, None)
|
||||
}
|
||||
|
||||
fn call_lifetime_intrinsic(&mut self, intrinsic: &str, ptr: &'ll Value, size: Size) {
|
||||
@ -1526,7 +1531,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
|
||||
format!("llvm.{instr}.sat.i{int_width}.f{float_width}")
|
||||
};
|
||||
let f = self.declare_cfn(&name, llvm::UnnamedAddr::No, self.type_func(&[src_ty], dest_ty));
|
||||
self.call(self.type_func(&[src_ty], dest_ty), None, None, f, &[val], None)
|
||||
self.call(self.type_func(&[src_ty], dest_ty), None, None, f, &[val], None, None)
|
||||
}
|
||||
|
||||
pub(crate) fn landing_pad(
|
||||
@ -1554,6 +1559,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
|
||||
default_dest: &'ll BasicBlock,
|
||||
indirect_dest: &[&'ll BasicBlock],
|
||||
funclet: Option<&Funclet<'ll>>,
|
||||
instance: Option<Instance<'tcx>>,
|
||||
) -> &'ll Value {
|
||||
debug!("invoke {:?} with args ({:?})", llfn, args);
|
||||
|
||||
@ -1566,10 +1572,10 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
|
||||
}
|
||||
|
||||
// Emit CFI pointer type membership test
|
||||
self.cfi_type_test(fn_attrs, fn_abi, llfn);
|
||||
self.cfi_type_test(fn_attrs, fn_abi, instance, llfn);
|
||||
|
||||
// Emit KCFI operand bundle
|
||||
let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, llfn);
|
||||
let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, instance, llfn);
|
||||
let kcfi_bundle = kcfi_bundle.as_ref().map(|b| &*b.raw);
|
||||
if let Some(kcfi_bundle) = kcfi_bundle {
|
||||
bundles.push(kcfi_bundle);
|
||||
@ -1601,6 +1607,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
|
||||
&mut self,
|
||||
fn_attrs: Option<&CodegenFnAttrs>,
|
||||
fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
|
||||
instance: Option<Instance<'tcx>>,
|
||||
llfn: &'ll Value,
|
||||
) {
|
||||
let is_indirect_call = unsafe { llvm::LLVMRustIsNonGVFunctionPointerTy(llfn) };
|
||||
@ -1622,7 +1629,11 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
|
||||
options.insert(TypeIdOptions::NORMALIZE_INTEGERS);
|
||||
}
|
||||
|
||||
let typeid = typeid_for_fnabi(self.tcx, fn_abi, options);
|
||||
let typeid = if let Some(instance) = instance {
|
||||
typeid_for_instance(self.tcx, &instance, options)
|
||||
} else {
|
||||
typeid_for_fnabi(self.tcx, fn_abi, options)
|
||||
};
|
||||
let typeid_metadata = self.cx.typeid_metadata(typeid).unwrap();
|
||||
|
||||
// Test whether the function pointer is associated with the type identifier.
|
||||
@ -1644,6 +1655,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
|
||||
&mut self,
|
||||
fn_attrs: Option<&CodegenFnAttrs>,
|
||||
fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
|
||||
instance: Option<Instance<'tcx>>,
|
||||
llfn: &'ll Value,
|
||||
) -> Option<llvm::OperandBundleDef<'ll>> {
|
||||
let is_indirect_call = unsafe { llvm::LLVMRustIsNonGVFunctionPointerTy(llfn) };
|
||||
@ -1665,7 +1677,12 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
|
||||
options.insert(TypeIdOptions::NORMALIZE_INTEGERS);
|
||||
}
|
||||
|
||||
let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi, options);
|
||||
let kcfi_typeid = if let Some(instance) = instance {
|
||||
kcfi_typeid_for_instance(self.tcx, &instance, options)
|
||||
} else {
|
||||
kcfi_typeid_for_fnabi(self.tcx, fn_abi, options)
|
||||
};
|
||||
|
||||
Some(llvm::OperandBundleDef::new("kcfi", &[self.const_u32(kcfi_typeid)]))
|
||||
} else {
|
||||
None
|
||||
|
@ -14,7 +14,6 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
|
||||
use rustc_llvm::RustString;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::mir::coverage::CoverageKind;
|
||||
use rustc_middle::mir::Coverage;
|
||||
use rustc_middle::ty::layout::HasTyCtxt;
|
||||
use rustc_middle::ty::Instance;
|
||||
|
||||
@ -75,7 +74,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
|
||||
|
||||
impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn add_coverage(&mut self, instance: Instance<'tcx>, coverage: &Coverage) {
|
||||
fn add_coverage(&mut self, instance: Instance<'tcx>, kind: &CoverageKind) {
|
||||
// Our caller should have already taken care of inlining subtleties,
|
||||
// so we can assume that counter/expression IDs in this coverage
|
||||
// statement are meaningful for the given instance.
|
||||
@ -98,7 +97,6 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
|
||||
.entry(instance)
|
||||
.or_insert_with(|| FunctionCoverageCollector::new(instance, function_coverage_info));
|
||||
|
||||
let Coverage { kind } = coverage;
|
||||
match *kind {
|
||||
CoverageKind::SpanMarker | CoverageKind::BlockMarker { .. } => unreachable!(
|
||||
"marker statement {kind:?} should have been removed by CleanupPostBorrowck"
|
||||
|
@ -181,6 +181,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
|
||||
simple_fn,
|
||||
&args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(),
|
||||
None,
|
||||
Some(instance),
|
||||
)
|
||||
}
|
||||
sym::likely => {
|
||||
@ -539,7 +540,7 @@ fn catch_unwind_intrinsic<'ll>(
|
||||
) {
|
||||
if bx.sess().panic_strategy() == PanicStrategy::Abort {
|
||||
let try_func_ty = bx.type_func(&[bx.type_ptr()], bx.type_void());
|
||||
bx.call(try_func_ty, None, None, try_func, &[data], None);
|
||||
bx.call(try_func_ty, None, None, try_func, &[data], None, None);
|
||||
// Return 0 unconditionally from the intrinsic call;
|
||||
// we can never unwind.
|
||||
let ret_align = bx.tcx().data_layout.i32_align.abi;
|
||||
@ -640,7 +641,7 @@ fn codegen_msvc_try<'ll>(
|
||||
let ptr_align = bx.tcx().data_layout.pointer_align.abi;
|
||||
let slot = bx.alloca(bx.type_ptr(), ptr_align);
|
||||
let try_func_ty = bx.type_func(&[bx.type_ptr()], bx.type_void());
|
||||
bx.invoke(try_func_ty, None, None, try_func, &[data], normal, catchswitch, None);
|
||||
bx.invoke(try_func_ty, None, None, try_func, &[data], normal, catchswitch, None, None);
|
||||
|
||||
bx.switch_to_block(normal);
|
||||
bx.ret(bx.const_i32(0));
|
||||
@ -684,7 +685,7 @@ fn codegen_msvc_try<'ll>(
|
||||
let funclet = bx.catch_pad(cs, &[tydesc, flags, slot]);
|
||||
let ptr = bx.load(bx.type_ptr(), slot, ptr_align);
|
||||
let catch_ty = bx.type_func(&[bx.type_ptr(), bx.type_ptr()], bx.type_void());
|
||||
bx.call(catch_ty, None, None, catch_func, &[data, ptr], Some(&funclet));
|
||||
bx.call(catch_ty, None, None, catch_func, &[data, ptr], Some(&funclet), None);
|
||||
bx.catch_ret(&funclet, caught);
|
||||
|
||||
// The flag value of 64 indicates a "catch-all".
|
||||
@ -692,7 +693,7 @@ fn codegen_msvc_try<'ll>(
|
||||
let flags = bx.const_i32(64);
|
||||
let null = bx.const_null(bx.type_ptr());
|
||||
let funclet = bx.catch_pad(cs, &[null, flags, null]);
|
||||
bx.call(catch_ty, None, None, catch_func, &[data, null], Some(&funclet));
|
||||
bx.call(catch_ty, None, None, catch_func, &[data, null], Some(&funclet), None);
|
||||
bx.catch_ret(&funclet, caught);
|
||||
|
||||
bx.switch_to_block(caught);
|
||||
@ -701,7 +702,7 @@ fn codegen_msvc_try<'ll>(
|
||||
|
||||
// Note that no invoke is used here because by definition this function
|
||||
// can't panic (that's what it's catching).
|
||||
let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None);
|
||||
let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None, None);
|
||||
let i32_align = bx.tcx().data_layout.i32_align.abi;
|
||||
bx.store(ret, dest, i32_align);
|
||||
}
|
||||
@ -750,7 +751,7 @@ fn codegen_wasm_try<'ll>(
|
||||
// }
|
||||
//
|
||||
let try_func_ty = bx.type_func(&[bx.type_ptr()], bx.type_void());
|
||||
bx.invoke(try_func_ty, None, None, try_func, &[data], normal, catchswitch, None);
|
||||
bx.invoke(try_func_ty, None, None, try_func, &[data], normal, catchswitch, None, None);
|
||||
|
||||
bx.switch_to_block(normal);
|
||||
bx.ret(bx.const_i32(0));
|
||||
@ -766,7 +767,7 @@ fn codegen_wasm_try<'ll>(
|
||||
let _sel = bx.call_intrinsic("llvm.wasm.get.ehselector", &[funclet.cleanuppad()]);
|
||||
|
||||
let catch_ty = bx.type_func(&[bx.type_ptr(), bx.type_ptr()], bx.type_void());
|
||||
bx.call(catch_ty, None, None, catch_func, &[data, ptr], Some(&funclet));
|
||||
bx.call(catch_ty, None, None, catch_func, &[data, ptr], Some(&funclet), None);
|
||||
bx.catch_ret(&funclet, caught);
|
||||
|
||||
bx.switch_to_block(caught);
|
||||
@ -775,7 +776,7 @@ fn codegen_wasm_try<'ll>(
|
||||
|
||||
// Note that no invoke is used here because by definition this function
|
||||
// can't panic (that's what it's catching).
|
||||
let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None);
|
||||
let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None, None);
|
||||
let i32_align = bx.tcx().data_layout.i32_align.abi;
|
||||
bx.store(ret, dest, i32_align);
|
||||
}
|
||||
@ -818,7 +819,7 @@ fn codegen_gnu_try<'ll>(
|
||||
let data = llvm::get_param(bx.llfn(), 1);
|
||||
let catch_func = llvm::get_param(bx.llfn(), 2);
|
||||
let try_func_ty = bx.type_func(&[bx.type_ptr()], bx.type_void());
|
||||
bx.invoke(try_func_ty, None, None, try_func, &[data], then, catch, None);
|
||||
bx.invoke(try_func_ty, None, None, try_func, &[data], then, catch, None, None);
|
||||
|
||||
bx.switch_to_block(then);
|
||||
bx.ret(bx.const_i32(0));
|
||||
@ -836,13 +837,13 @@ fn codegen_gnu_try<'ll>(
|
||||
bx.add_clause(vals, tydesc);
|
||||
let ptr = bx.extract_value(vals, 0);
|
||||
let catch_ty = bx.type_func(&[bx.type_ptr(), bx.type_ptr()], bx.type_void());
|
||||
bx.call(catch_ty, None, None, catch_func, &[data, ptr], None);
|
||||
bx.call(catch_ty, None, None, catch_func, &[data, ptr], None, None);
|
||||
bx.ret(bx.const_i32(1));
|
||||
});
|
||||
|
||||
// Note that no invoke is used here because by definition this function
|
||||
// can't panic (that's what it's catching).
|
||||
let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None);
|
||||
let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None, None);
|
||||
let i32_align = bx.tcx().data_layout.i32_align.abi;
|
||||
bx.store(ret, dest, i32_align);
|
||||
}
|
||||
@ -882,7 +883,7 @@ fn codegen_emcc_try<'ll>(
|
||||
let data = llvm::get_param(bx.llfn(), 1);
|
||||
let catch_func = llvm::get_param(bx.llfn(), 2);
|
||||
let try_func_ty = bx.type_func(&[bx.type_ptr()], bx.type_void());
|
||||
bx.invoke(try_func_ty, None, None, try_func, &[data], then, catch, None);
|
||||
bx.invoke(try_func_ty, None, None, try_func, &[data], then, catch, None, None);
|
||||
|
||||
bx.switch_to_block(then);
|
||||
bx.ret(bx.const_i32(0));
|
||||
@ -920,13 +921,13 @@ fn codegen_emcc_try<'ll>(
|
||||
bx.store(is_rust_panic, catch_data_1, i8_align);
|
||||
|
||||
let catch_ty = bx.type_func(&[bx.type_ptr(), bx.type_ptr()], bx.type_void());
|
||||
bx.call(catch_ty, None, None, catch_func, &[data, catch_data], None);
|
||||
bx.call(catch_ty, None, None, catch_func, &[data, catch_data], None, None);
|
||||
bx.ret(bx.const_i32(1));
|
||||
});
|
||||
|
||||
// Note that no invoke is used here because by definition this function
|
||||
// can't panic (that's what it's catching).
|
||||
let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None);
|
||||
let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None, None);
|
||||
let i32_align = bx.tcx().data_layout.i32_align.abi;
|
||||
bx.store(ret, dest, i32_align);
|
||||
}
|
||||
@ -1439,6 +1440,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
f,
|
||||
&args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(),
|
||||
None,
|
||||
None,
|
||||
);
|
||||
Ok(c)
|
||||
}
|
||||
@ -1607,6 +1609,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
f,
|
||||
&[args[1].immediate(), alignment, mask, args[0].immediate()],
|
||||
None,
|
||||
None,
|
||||
);
|
||||
return Ok(v);
|
||||
}
|
||||
@ -1706,6 +1709,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
f,
|
||||
&[args[1].immediate(), alignment, mask, args[2].immediate()],
|
||||
None,
|
||||
None,
|
||||
);
|
||||
return Ok(v);
|
||||
}
|
||||
@ -1799,6 +1803,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
f,
|
||||
&[args[2].immediate(), args[1].immediate(), alignment, mask],
|
||||
None,
|
||||
None,
|
||||
);
|
||||
return Ok(v);
|
||||
}
|
||||
@ -1904,6 +1909,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
f,
|
||||
&[args[0].immediate(), args[1].immediate(), alignment, mask],
|
||||
None,
|
||||
None,
|
||||
);
|
||||
return Ok(v);
|
||||
}
|
||||
@ -2352,11 +2358,12 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
f,
|
||||
&[args[0].immediate(), bx.const_int(bx.type_i1(), 0)],
|
||||
None,
|
||||
None,
|
||||
))
|
||||
} else {
|
||||
let fn_ty = bx.type_func(&[vec_ty], vec_ty);
|
||||
let f = bx.declare_cfn(llvm_intrinsic, llvm::UnnamedAddr::No, fn_ty);
|
||||
Ok(bx.call(fn_ty, None, None, f, &[args[0].immediate()], None))
|
||||
Ok(bx.call(fn_ty, None, None, f, &[args[0].immediate()], None, None))
|
||||
};
|
||||
}
|
||||
|
||||
@ -2409,7 +2416,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
|
||||
|
||||
let fn_ty = bx.type_func(&[vec_ty, vec_ty], vec_ty);
|
||||
let f = bx.declare_cfn(llvm_intrinsic, llvm::UnnamedAddr::No, fn_ty);
|
||||
let v = bx.call(fn_ty, None, None, f, &[lhs, rhs], None);
|
||||
let v = bx.call(fn_ty, None, None, f, &[lhs, rhs], None, None);
|
||||
return Ok(v);
|
||||
}
|
||||
|
||||
|
@ -462,27 +462,34 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
||||
let ptr_ty = cx.type_ptr();
|
||||
let (arg_argc, arg_argv) = get_argc_argv(cx, &mut bx);
|
||||
|
||||
let (start_fn, start_ty, args) = if let EntryFnType::Main { sigpipe } = entry_type {
|
||||
let (start_fn, start_ty, args, instance) = if let EntryFnType::Main { sigpipe } = entry_type
|
||||
{
|
||||
let start_def_id = cx.tcx().require_lang_item(LangItem::Start, None);
|
||||
let start_fn = cx.get_fn_addr(ty::Instance::expect_resolve(
|
||||
let start_instance = ty::Instance::expect_resolve(
|
||||
cx.tcx(),
|
||||
ty::ParamEnv::reveal_all(),
|
||||
start_def_id,
|
||||
cx.tcx().mk_args(&[main_ret_ty.into()]),
|
||||
));
|
||||
);
|
||||
let start_fn = cx.get_fn_addr(start_instance);
|
||||
|
||||
let i8_ty = cx.type_i8();
|
||||
let arg_sigpipe = bx.const_u8(sigpipe);
|
||||
|
||||
let start_ty = cx.type_func(&[cx.val_ty(rust_main), isize_ty, ptr_ty, i8_ty], isize_ty);
|
||||
(start_fn, start_ty, vec![rust_main, arg_argc, arg_argv, arg_sigpipe])
|
||||
(
|
||||
start_fn,
|
||||
start_ty,
|
||||
vec![rust_main, arg_argc, arg_argv, arg_sigpipe],
|
||||
Some(start_instance),
|
||||
)
|
||||
} else {
|
||||
debug!("using user-defined start fn");
|
||||
let start_ty = cx.type_func(&[isize_ty, ptr_ty], isize_ty);
|
||||
(rust_main, start_ty, vec![arg_argc, arg_argv])
|
||||
(rust_main, start_ty, vec![arg_argc, arg_argv], None)
|
||||
};
|
||||
|
||||
let result = bx.call(start_ty, None, None, start_fn, &args, None);
|
||||
let result = bx.call(start_ty, None, None, start_fn, &args, None, instance);
|
||||
if cx.sess().target.os.contains("uefi") {
|
||||
bx.ret(result);
|
||||
} else {
|
||||
|
@ -232,6 +232,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
|
||||
ret_llbb,
|
||||
unwind_block,
|
||||
self.funclet(fx),
|
||||
instance,
|
||||
);
|
||||
if fx.mir[self.bb].is_cleanup {
|
||||
bx.apply_attrs_to_cleanup_callsite(invokeret);
|
||||
@ -247,7 +248,8 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
|
||||
}
|
||||
MergingSucc::False
|
||||
} else {
|
||||
let llret = bx.call(fn_ty, fn_attrs, Some(fn_abi), fn_ptr, llargs, self.funclet(fx));
|
||||
let llret =
|
||||
bx.call(fn_ty, fn_attrs, Some(fn_abi), fn_ptr, llargs, self.funclet(fx), instance);
|
||||
if fx.mir[self.bb].is_cleanup {
|
||||
bx.apply_attrs_to_cleanup_callsite(llret);
|
||||
}
|
||||
@ -502,7 +504,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
let ty = location.ty(self.mir, bx.tcx()).ty;
|
||||
let ty = self.monomorphize(ty);
|
||||
let drop_fn = Instance::resolve_drop_in_place(bx.tcx(), ty);
|
||||
let instance = drop_fn.clone();
|
||||
|
||||
if let ty::InstanceDef::DropGlue(_, None) = drop_fn.def {
|
||||
// we don't actually need to drop anything.
|
||||
@ -518,7 +519,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
args1 = [place.llval];
|
||||
&args1[..]
|
||||
};
|
||||
let (drop_fn, fn_abi) =
|
||||
let (drop_fn, fn_abi, drop_instance) =
|
||||
match ty.kind() {
|
||||
// FIXME(eddyb) perhaps move some of this logic into
|
||||
// `Instance::resolve_drop_in_place`?
|
||||
@ -550,6 +551,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
meth::VirtualIndex::from_index(ty::COMMON_VTABLE_ENTRIES_DROPINPLACE)
|
||||
.get_fn(bx, vtable, ty, fn_abi),
|
||||
fn_abi,
|
||||
virtual_drop,
|
||||
)
|
||||
}
|
||||
ty::Dynamic(_, _, ty::DynStar) => {
|
||||
@ -592,9 +594,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
meth::VirtualIndex::from_index(ty::COMMON_VTABLE_ENTRIES_DROPINPLACE)
|
||||
.get_fn(bx, meta.immediate(), ty, fn_abi),
|
||||
fn_abi,
|
||||
virtual_drop,
|
||||
)
|
||||
}
|
||||
_ => (bx.get_fn_addr(drop_fn), bx.fn_abi_of_instance(drop_fn, ty::List::empty())),
|
||||
_ => (
|
||||
bx.get_fn_addr(drop_fn),
|
||||
bx.fn_abi_of_instance(drop_fn, ty::List::empty()),
|
||||
drop_fn,
|
||||
),
|
||||
};
|
||||
helper.do_call(
|
||||
self,
|
||||
@ -605,7 +612,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
Some((ReturnDest::Nothing, target)),
|
||||
unwind,
|
||||
&[],
|
||||
Some(instance),
|
||||
Some(drop_instance),
|
||||
mergeable_succ,
|
||||
)
|
||||
}
|
||||
@ -1699,7 +1706,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
} else {
|
||||
let fn_ty = bx.fn_decl_backend_type(fn_abi);
|
||||
|
||||
let llret = bx.call(fn_ty, None, Some(fn_abi), fn_ptr, &[], funclet.as_ref());
|
||||
let llret = bx.call(fn_ty, None, Some(fn_abi), fn_ptr, &[], funclet.as_ref(), None);
|
||||
bx.apply_attrs_to_cleanup_callsite(llret);
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
use crate::traits::*;
|
||||
|
||||
use rustc_middle::mir::Coverage;
|
||||
use rustc_middle::mir::coverage::CoverageKind;
|
||||
use rustc_middle::mir::SourceScope;
|
||||
|
||||
use super::FunctionCx;
|
||||
|
||||
impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
pub fn codegen_coverage(&self, bx: &mut Bx, coverage: &Coverage, scope: SourceScope) {
|
||||
pub fn codegen_coverage(&self, bx: &mut Bx, kind: &CoverageKind, scope: SourceScope) {
|
||||
// Determine the instance that coverage data was originally generated for.
|
||||
let instance = if let Some(inlined) = scope.inlined_instance(&self.mir.source_scopes) {
|
||||
self.monomorphize(inlined)
|
||||
@ -15,6 +15,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
};
|
||||
|
||||
// Handle the coverage info in a backend-specific way.
|
||||
bx.add_coverage(instance, coverage);
|
||||
bx.add_coverage(instance, kind);
|
||||
}
|
||||
}
|
||||
|
@ -709,7 +709,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
} else {
|
||||
None
|
||||
};
|
||||
bx.call(fn_ty, fn_attrs, Some(fn_abi), fn_ptr, &[], None)
|
||||
bx.call(fn_ty, fn_attrs, Some(fn_abi), fn_ptr, &[], None, Some(instance))
|
||||
} else {
|
||||
bx.get_static(def_id)
|
||||
};
|
||||
|
@ -64,8 +64,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
cg_indirect_place.storage_dead(bx);
|
||||
}
|
||||
}
|
||||
mir::StatementKind::Coverage(box ref coverage) => {
|
||||
self.codegen_coverage(bx, coverage, statement.source_info.scope);
|
||||
mir::StatementKind::Coverage(ref kind) => {
|
||||
self.codegen_coverage(bx, kind, statement.source_info.scope);
|
||||
}
|
||||
mir::StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(ref op)) => {
|
||||
if !matches!(bx.tcx().sess.opts.optimize, OptLevel::No | OptLevel::Less) {
|
||||
|
@ -70,7 +70,15 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
||||
// (But we are in good company, this code is duplicated plenty of times.)
|
||||
let fn_ty = bx.fn_decl_backend_type(fn_abi);
|
||||
|
||||
bx.call(fn_ty, /* fn_attrs */ None, Some(fn_abi), llfn, &[msg.0, msg.1], None);
|
||||
bx.call(
|
||||
fn_ty,
|
||||
/* fn_attrs */ None,
|
||||
Some(fn_abi),
|
||||
llfn,
|
||||
&[msg.0, msg.1],
|
||||
None,
|
||||
None,
|
||||
);
|
||||
|
||||
// This function does not return so we can now return whatever we want.
|
||||
let size = bx.const_usize(layout.size.bytes());
|
||||
|
@ -17,7 +17,7 @@ use crate::MemFlags;
|
||||
|
||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
|
||||
use rustc_middle::ty::layout::{HasParamEnv, TyAndLayout};
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_middle::ty::{Instance, Ty};
|
||||
use rustc_session::config::OptLevel;
|
||||
use rustc_span::Span;
|
||||
use rustc_target::abi::call::FnAbi;
|
||||
@ -82,6 +82,7 @@ pub trait BuilderMethods<'a, 'tcx>:
|
||||
then: Self::BasicBlock,
|
||||
catch: Self::BasicBlock,
|
||||
funclet: Option<&Self::Funclet>,
|
||||
instance: Option<Instance<'tcx>>,
|
||||
) -> Self::Value;
|
||||
fn unreachable(&mut self);
|
||||
|
||||
@ -389,6 +390,7 @@ pub trait BuilderMethods<'a, 'tcx>:
|
||||
llfn: Self::Value,
|
||||
args: &[Self::Value],
|
||||
funclet: Option<&Self::Funclet>,
|
||||
instance: Option<Instance<'tcx>>,
|
||||
) -> Self::Value;
|
||||
fn zext(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
use super::BackendTypes;
|
||||
use rustc_middle::mir::Coverage;
|
||||
use rustc_middle::mir::coverage::CoverageKind;
|
||||
use rustc_middle::ty::Instance;
|
||||
|
||||
pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes {
|
||||
@ -7,5 +7,5 @@ pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes {
|
||||
///
|
||||
/// This can potentially be a no-op in backends that don't support
|
||||
/// coverage instrumentation.
|
||||
fn add_coverage(&mut self, instance: Instance<'tcx>, coverage: &Coverage);
|
||||
fn add_coverage(&mut self, instance: Instance<'tcx>, kind: &CoverageKind);
|
||||
}
|
||||
|
@ -346,8 +346,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
|
||||
self.fail(location, format!("explicit `{kind:?}` is forbidden"));
|
||||
}
|
||||
}
|
||||
StatementKind::Coverage(coverage) => {
|
||||
let kind = &coverage.kind;
|
||||
StatementKind::Coverage(kind) => {
|
||||
if self.mir_phase >= MirPhase::Analysis(AnalysisPhase::PostCleanup)
|
||||
&& let CoverageKind::BlockMarker { .. } | CoverageKind::SpanMarker { .. } = kind
|
||||
{
|
||||
|
@ -541,6 +541,7 @@ pub struct SilentEmitter {
|
||||
pub fallback_bundle: LazyFallbackBundle,
|
||||
pub fatal_dcx: DiagCtxt,
|
||||
pub fatal_note: Option<String>,
|
||||
pub emit_fatal_diagnostic: bool,
|
||||
}
|
||||
|
||||
impl Translate for SilentEmitter {
|
||||
@ -561,7 +562,7 @@ impl Emitter for SilentEmitter {
|
||||
}
|
||||
|
||||
fn emit_diagnostic(&mut self, mut diag: DiagInner) {
|
||||
if diag.level == Level::Fatal {
|
||||
if self.emit_fatal_diagnostic && diag.level == Level::Fatal {
|
||||
if let Some(fatal_note) = &self.fatal_note {
|
||||
diag.sub(Level::Note, fatal_note.clone(), MultiSpan::new());
|
||||
}
|
||||
|
@ -612,12 +612,18 @@ impl DiagCtxt {
|
||||
Self { inner: Lock::new(DiagCtxtInner::new(emitter)) }
|
||||
}
|
||||
|
||||
pub fn make_silent(&mut self, fallback_bundle: LazyFallbackBundle, fatal_note: Option<String>) {
|
||||
pub fn make_silent(
|
||||
&mut self,
|
||||
fallback_bundle: LazyFallbackBundle,
|
||||
fatal_note: Option<String>,
|
||||
emit_fatal_diagnostic: bool,
|
||||
) {
|
||||
self.wrap_emitter(|old_dcx| {
|
||||
Box::new(emitter::SilentEmitter {
|
||||
fallback_bundle,
|
||||
fatal_dcx: DiagCtxt { inner: Lock::new(old_dcx) },
|
||||
fatal_note,
|
||||
emit_fatal_diagnostic,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
@ -6,7 +6,9 @@ use rustc_session::lint;
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
use rustc_span::Symbol;
|
||||
use rustc_target::abi::FieldIdx;
|
||||
use rustc_target::asm::{InlineAsmReg, InlineAsmRegClass, InlineAsmRegOrRegClass, InlineAsmType};
|
||||
use rustc_target::asm::{
|
||||
InlineAsmReg, InlineAsmRegClass, InlineAsmRegOrRegClass, InlineAsmType, ModifierInfo,
|
||||
};
|
||||
|
||||
pub struct InlineAsmCtxt<'a, 'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
@ -251,8 +253,11 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
// Check whether a modifier is suggested for using this type.
|
||||
if let Some((suggested_modifier, suggested_result)) =
|
||||
reg_class.suggest_modifier(asm_arch, asm_ty)
|
||||
if let Some(ModifierInfo {
|
||||
modifier: suggested_modifier,
|
||||
result: suggested_result,
|
||||
size: suggested_size,
|
||||
}) = reg_class.suggest_modifier(asm_arch, asm_ty)
|
||||
{
|
||||
// Search for any use of this operand without a modifier and emit
|
||||
// the suggestion for them.
|
||||
@ -266,8 +271,11 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
if !spans.is_empty() {
|
||||
let (default_modifier, default_result) =
|
||||
reg_class.default_modifier(asm_arch).unwrap();
|
||||
let ModifierInfo {
|
||||
modifier: default_modifier,
|
||||
result: default_result,
|
||||
size: default_size,
|
||||
} = reg_class.default_modifier(asm_arch).unwrap();
|
||||
self.tcx.node_span_lint(
|
||||
lint::builtin::ASM_SUB_REGISTER,
|
||||
expr.hir_id,
|
||||
@ -276,10 +284,10 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
|
||||
|lint| {
|
||||
lint.span_label(expr.span, "for this argument");
|
||||
lint.help(format!(
|
||||
"use `{{{idx}:{suggested_modifier}}}` to have the register formatted as `{suggested_result}`",
|
||||
"use `{{{idx}:{suggested_modifier}}}` to have the register formatted as `{suggested_result}` (for {suggested_size}-bit values)",
|
||||
));
|
||||
lint.help(format!(
|
||||
"or use `{{{idx}:{default_modifier}}}` to keep the default formatting of `{default_result}`",
|
||||
"or use `{{{idx}:{default_modifier}}}` to keep the default formatting of `{default_result}` (for {default_size}-bit values)",
|
||||
));
|
||||
},
|
||||
);
|
||||
|
@ -65,7 +65,7 @@ const BASE_HIR: &[&str] = &[
|
||||
const BASE_IMPL: &[&str] =
|
||||
&[label_strs::associated_item_def_ids, label_strs::generics_of, label_strs::impl_trait_header];
|
||||
|
||||
/// DepNodes for mir_built/Optimized, which is relevant in "executable"
|
||||
/// DepNodes for exported mir bodies, which is relevant in "executable"
|
||||
/// code, i.e., functions+methods
|
||||
const BASE_MIR: &[&str] = &[label_strs::optimized_mir, label_strs::promoted_mir];
|
||||
|
||||
|
@ -48,6 +48,7 @@ pub(crate) fn parse_cfg(dcx: &DiagCtxt, cfgs: Vec<String>) -> Cfg {
|
||||
let psess = ParseSess::with_silent_emitter(
|
||||
vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE],
|
||||
format!("this error occurred on the command line: `--cfg={s}`"),
|
||||
true,
|
||||
);
|
||||
let filename = FileName::cfg_spec_source_code(&s);
|
||||
|
||||
@ -111,6 +112,7 @@ pub(crate) fn parse_check_cfg(dcx: &DiagCtxt, specs: Vec<String>) -> CheckCfg {
|
||||
let psess = ParseSess::with_silent_emitter(
|
||||
vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE],
|
||||
format!("this error occurred on the command line: `--check-cfg={s}`"),
|
||||
true,
|
||||
);
|
||||
let filename = FileName::cfg_spec_source_code(&s);
|
||||
|
||||
|
@ -389,6 +389,15 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
|
||||
None
|
||||
}
|
||||
|
||||
// The `dependency` type is determined by the command line arguments(`--extern`) and
|
||||
// `private_dep`. However, sometimes the directly dependent crate is not specified by
|
||||
// `--extern`, in this case, `private-dep` is none during loading. This is equivalent to the
|
||||
// scenario where the command parameter is set to `public-dependency`
|
||||
fn is_private_dep(&self, name: &str, private_dep: Option<bool>) -> bool {
|
||||
self.sess.opts.externs.get(name).map_or(private_dep.unwrap_or(false), |e| e.is_private_dep)
|
||||
&& private_dep.unwrap_or(true)
|
||||
}
|
||||
|
||||
fn register_crate(
|
||||
&mut self,
|
||||
host_lib: Option<Library>,
|
||||
@ -404,14 +413,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
|
||||
let Library { source, metadata } = lib;
|
||||
let crate_root = metadata.get_root();
|
||||
let host_hash = host_lib.as_ref().map(|lib| lib.metadata.get_root().hash());
|
||||
|
||||
let private_dep = self
|
||||
.sess
|
||||
.opts
|
||||
.externs
|
||||
.get(name.as_str())
|
||||
.map_or(private_dep.unwrap_or(false), |e| e.is_private_dep)
|
||||
&& private_dep.unwrap_or(true);
|
||||
let private_dep = self.is_private_dep(name.as_str(), private_dep);
|
||||
|
||||
// Claim this crate number and cache it
|
||||
let cnum = self.cstore.intern_stable_crate_id(&crate_root)?;
|
||||
@ -601,14 +603,17 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
|
||||
|
||||
match result {
|
||||
(LoadResult::Previous(cnum), None) => {
|
||||
// When `private_dep` is none, it indicates the directly dependent crate. If it is
|
||||
// not specified by `--extern` on command line parameters, it may be
|
||||
// `private-dependency` when `register_crate` is called for the first time. Then it must be updated to
|
||||
// `public-dependency` here.
|
||||
let private_dep = self.is_private_dep(name.as_str(), private_dep);
|
||||
let data = self.cstore.get_crate_data_mut(cnum);
|
||||
if data.is_proc_macro_crate() {
|
||||
dep_kind = CrateDepKind::MacrosOnly;
|
||||
}
|
||||
data.set_dep_kind(cmp::max(data.dep_kind(), dep_kind));
|
||||
if let Some(private_dep) = private_dep {
|
||||
data.update_and_private_dep(private_dep);
|
||||
}
|
||||
data.update_and_private_dep(private_dep);
|
||||
Ok(cnum)
|
||||
}
|
||||
(LoadResult::Loaded(library), host_library) => {
|
||||
|
@ -211,6 +211,7 @@ provide! { tcx, def_id, other, cdata,
|
||||
generics_of => { table }
|
||||
inferred_outlives_of => { table_defaulted_array }
|
||||
super_predicates_of => { table }
|
||||
implied_predicates_of => { table }
|
||||
type_of => { table }
|
||||
type_alias_is_lazy => { cdata.root.tables.type_alias_is_lazy.get(cdata, def_id.index) }
|
||||
variances_of => { table }
|
||||
@ -276,18 +277,6 @@ provide! { tcx, def_id, other, cdata,
|
||||
.map(|lazy| lazy.decode((cdata, tcx)))
|
||||
.process_decoded(tcx, || panic!("{def_id:?} does not have trait_impl_trait_tys")))
|
||||
}
|
||||
implied_predicates_of => {
|
||||
cdata
|
||||
.root
|
||||
.tables
|
||||
.implied_predicates_of
|
||||
.get(cdata, def_id.index)
|
||||
.map(|lazy| lazy.decode((cdata, tcx)))
|
||||
.unwrap_or_else(|| {
|
||||
debug_assert_eq!(tcx.def_kind(def_id), DefKind::Trait);
|
||||
tcx.super_predicates_of(def_id)
|
||||
})
|
||||
}
|
||||
|
||||
associated_types_for_impl_traits_in_associated_fn => { table_defaulted_array }
|
||||
|
||||
|
@ -1435,6 +1435,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||
if let DefKind::Trait = def_kind {
|
||||
record!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id));
|
||||
record!(self.tables.super_predicates_of[def_id] <- self.tcx.super_predicates_of(def_id));
|
||||
record!(self.tables.implied_predicates_of[def_id] <- self.tcx.implied_predicates_of(def_id));
|
||||
|
||||
let module_children = self.tcx.module_children_local(local_id);
|
||||
record_array!(self.tables.module_children_non_reexports[def_id] <-
|
||||
|
@ -77,4 +77,10 @@ declare_hooks! {
|
||||
///
|
||||
/// (Eligible functions might nevertheless be skipped for other reasons.)
|
||||
hook is_eligible_for_coverage(key: LocalDefId) -> bool;
|
||||
|
||||
/// Create the MIR for a given `DefId` - this includes
|
||||
/// unreachable code.
|
||||
/// You do not want to call this yourself, instead use the cached version
|
||||
/// via `mir_built`
|
||||
hook build_mir(key: LocalDefId) -> mir::Body<'tcx>;
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ use rustc_middle::mir::interpret::{
|
||||
Provenance,
|
||||
};
|
||||
use rustc_middle::mir::visit::Visitor;
|
||||
use rustc_middle::mir::{self, *};
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_target::abi::Size;
|
||||
|
||||
const INDENT: &str = " ";
|
||||
@ -711,7 +711,7 @@ impl Debug for Statement<'_> {
|
||||
AscribeUserType(box (ref place, ref c_ty), ref variance) => {
|
||||
write!(fmt, "AscribeUserType({place:?}, {variance:?}, {c_ty:?})")
|
||||
}
|
||||
Coverage(box mir::Coverage { ref kind }) => write!(fmt, "Coverage::{kind:?}"),
|
||||
Coverage(ref kind) => write!(fmt, "Coverage::{kind:?}"),
|
||||
Intrinsic(box ref intrinsic) => write!(fmt, "{intrinsic}"),
|
||||
ConstEvalCounter => write!(fmt, "ConstEvalCounter"),
|
||||
Nop => write!(fmt, "nop"),
|
||||
|
@ -373,7 +373,7 @@ pub enum StatementKind<'tcx> {
|
||||
///
|
||||
/// Interpreters and codegen backends that don't support coverage instrumentation
|
||||
/// can usually treat this as a no-op.
|
||||
Coverage(Box<Coverage>),
|
||||
Coverage(CoverageKind),
|
||||
|
||||
/// Denotes a call to an intrinsic that does not require an unwind path and always returns.
|
||||
/// This avoids adding a new block and a terminator for simple intrinsics.
|
||||
@ -517,12 +517,6 @@ pub enum FakeReadCause {
|
||||
ForIndex,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)]
|
||||
#[derive(TypeFoldable, TypeVisitable)]
|
||||
pub struct Coverage {
|
||||
pub kind: CoverageKind,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)]
|
||||
#[derive(TypeFoldable, TypeVisitable)]
|
||||
pub struct CopyNonOverlapping<'tcx> {
|
||||
@ -1458,5 +1452,6 @@ mod size_asserts {
|
||||
static_assert_size!(Place<'_>, 16);
|
||||
static_assert_size!(PlaceElem<'_>, 24);
|
||||
static_assert_size!(Rvalue<'_>, 40);
|
||||
static_assert_size!(StatementKind<'_>, 16);
|
||||
// tidy-alphabetical-end
|
||||
}
|
||||
|
@ -156,10 +156,10 @@ macro_rules! make_mir_visitor {
|
||||
|
||||
fn visit_coverage(
|
||||
&mut self,
|
||||
coverage: & $($mutability)? Coverage,
|
||||
kind: & $($mutability)? coverage::CoverageKind,
|
||||
location: Location,
|
||||
) {
|
||||
self.super_coverage(coverage, location);
|
||||
self.super_coverage(kind, location);
|
||||
}
|
||||
|
||||
fn visit_retag(
|
||||
@ -803,7 +803,7 @@ macro_rules! make_mir_visitor {
|
||||
}
|
||||
|
||||
fn super_coverage(&mut self,
|
||||
_coverage: & $($mutability)? Coverage,
|
||||
_kind: & $($mutability)? coverage::CoverageKind,
|
||||
_location: Location) {
|
||||
}
|
||||
|
||||
|
@ -505,21 +505,15 @@ rustc_queries! {
|
||||
separate_provide_extern
|
||||
}
|
||||
|
||||
/// Fetch the MIR for a given `DefId` right after it's built - this includes
|
||||
/// unreachable code.
|
||||
/// Build the MIR for a given `DefId` and prepare it for const qualification.
|
||||
///
|
||||
/// See the [rustc dev guide] for more info.
|
||||
///
|
||||
/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/mir/construction.html
|
||||
query mir_built(key: LocalDefId) -> &'tcx Steal<mir::Body<'tcx>> {
|
||||
desc { |tcx| "building MIR for `{}`", tcx.def_path_str(key) }
|
||||
}
|
||||
|
||||
/// Fetch the MIR for a given `DefId` up till the point where it is
|
||||
/// ready for const qualification.
|
||||
///
|
||||
/// See the README for the `mir` module for details.
|
||||
query mir_const(key: LocalDefId) -> &'tcx Steal<mir::Body<'tcx>> {
|
||||
desc { |tcx| "preparing `{}` for borrow checking", tcx.def_path_str(key) }
|
||||
no_hash
|
||||
}
|
||||
|
||||
/// Try to build an abstract representation of the given constant.
|
||||
query thir_abstract_const(
|
||||
key: DefId
|
||||
|
@ -107,9 +107,7 @@ impl<'tcx> CFG<'tcx> {
|
||||
/// This results in more accurate coverage reports for certain kinds of
|
||||
/// syntax (e.g. `continue` or `if !`) that would otherwise not appear in MIR.
|
||||
pub(crate) fn push_coverage_span_marker(&mut self, block: BasicBlock, source_info: SourceInfo) {
|
||||
let kind = StatementKind::Coverage(Box::new(Coverage {
|
||||
kind: coverage::CoverageKind::SpanMarker,
|
||||
}));
|
||||
let kind = StatementKind::Coverage(coverage::CoverageKind::SpanMarker);
|
||||
let stmt = Statement { source_info, kind };
|
||||
self.push(block, stmt);
|
||||
}
|
||||
|
@ -127,9 +127,7 @@ impl Builder<'_, '_> {
|
||||
|
||||
let marker_statement = mir::Statement {
|
||||
source_info,
|
||||
kind: mir::StatementKind::Coverage(Box::new(mir::Coverage {
|
||||
kind: CoverageKind::BlockMarker { id },
|
||||
})),
|
||||
kind: mir::StatementKind::Coverage(CoverageKind::BlockMarker { id }),
|
||||
};
|
||||
self.cfg.push(block, marker_statement);
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
//! present, and if so we branch off into this module, which implements the attribute by
|
||||
//! implementing a custom lowering from THIR to MIR.
|
||||
//!
|
||||
//! The result of this lowering is returned "normally" from the `mir_built` query, with the only
|
||||
//! The result of this lowering is returned "normally" from the `build_mir` hook, with the only
|
||||
//! notable difference being that the `injected` field in the body is set. Various components of the
|
||||
//! MIR pipeline, like borrowck and the pass manager will then consult this field (via
|
||||
//! `body.should_skip()`) to skip the parts of the MIR pipeline that precede the MIR phase the user
|
||||
|
@ -18,6 +18,7 @@ use rustc_middle::hir::place::PlaceBase as HirPlaceBase;
|
||||
use rustc_middle::middle::region;
|
||||
use rustc_middle::mir::interpret::Scalar;
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::query::TyCtxtAt;
|
||||
use rustc_middle::thir::{
|
||||
self, BindingMode, ExprId, LintLevel, LocalVarId, Param, ParamId, PatKind, Thir,
|
||||
};
|
||||
@ -30,13 +31,6 @@ use rustc_target::spec::abi::Abi;
|
||||
|
||||
use super::lints;
|
||||
|
||||
pub(crate) fn mir_built(
|
||||
tcx: TyCtxt<'_>,
|
||||
def: LocalDefId,
|
||||
) -> &rustc_data_structures::steal::Steal<Body<'_>> {
|
||||
tcx.alloc_steal_mir(mir_build(tcx, def))
|
||||
}
|
||||
|
||||
pub(crate) fn closure_saved_names_of_captured_variables<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_id: LocalDefId,
|
||||
@ -54,7 +48,8 @@ pub(crate) fn closure_saved_names_of_captured_variables<'tcx>(
|
||||
}
|
||||
|
||||
/// Construct the MIR for a given `DefId`.
|
||||
fn mir_build<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Body<'tcx> {
|
||||
pub(crate) fn mir_build<'tcx>(tcx: TyCtxtAt<'tcx>, def: LocalDefId) -> Body<'tcx> {
|
||||
let tcx = tcx.tcx;
|
||||
tcx.ensure_with_value().thir_abstract_const(def);
|
||||
if let Err(e) = tcx.check_match(def) {
|
||||
return construct_error(tcx, def, e);
|
||||
|
@ -22,14 +22,14 @@ mod errors;
|
||||
pub mod lints;
|
||||
mod thir;
|
||||
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::util::Providers;
|
||||
|
||||
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
|
||||
|
||||
pub fn provide(providers: &mut Providers) {
|
||||
providers.check_match = thir::pattern::check_match;
|
||||
providers.lit_to_const = thir::constant::lit_to_const;
|
||||
providers.mir_built = build::mir_built;
|
||||
providers.hooks.build_mir = build::mir_build;
|
||||
providers.closure_saved_names_of_captured_variables =
|
||||
build::closure_saved_names_of_captured_variables;
|
||||
providers.check_unsafety = check_unsafety::check_unsafety;
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
use crate::MirPass;
|
||||
use rustc_middle::mir::coverage::CoverageKind;
|
||||
use rustc_middle::mir::{Body, BorrowKind, Coverage, Rvalue, StatementKind, TerminatorKind};
|
||||
use rustc_middle::mir::{Body, BorrowKind, Rvalue, StatementKind, TerminatorKind};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
|
||||
pub struct CleanupPostBorrowck;
|
||||
@ -30,12 +30,11 @@ impl<'tcx> MirPass<'tcx> for CleanupPostBorrowck {
|
||||
match statement.kind {
|
||||
StatementKind::AscribeUserType(..)
|
||||
| StatementKind::Assign(box (_, Rvalue::Ref(_, BorrowKind::Fake, _)))
|
||||
| StatementKind::Coverage(box Coverage {
|
||||
| StatementKind::Coverage(
|
||||
// These kinds of coverage statements are markers inserted during
|
||||
// MIR building, and are not needed after InstrumentCoverage.
|
||||
kind: CoverageKind::BlockMarker { .. } | CoverageKind::SpanMarker { .. },
|
||||
..
|
||||
})
|
||||
CoverageKind::BlockMarker { .. } | CoverageKind::SpanMarker { .. },
|
||||
)
|
||||
| StatementKind::FakeRead(..) => statement.make_nop(),
|
||||
_ => (),
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ use crate::MirPass;
|
||||
|
||||
use rustc_middle::mir::coverage::*;
|
||||
use rustc_middle::mir::{
|
||||
self, BasicBlock, BasicBlockData, Coverage, SourceInfo, Statement, StatementKind, Terminator,
|
||||
self, BasicBlock, BasicBlockData, SourceInfo, Statement, StatementKind, Terminator,
|
||||
TerminatorKind,
|
||||
};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
@ -230,10 +230,7 @@ fn inject_statement(mir_body: &mut mir::Body<'_>, counter_kind: CoverageKind, bb
|
||||
debug!(" injecting statement {counter_kind:?} for {bb:?}");
|
||||
let data = &mut mir_body[bb];
|
||||
let source_info = data.terminator().source_info;
|
||||
let statement = Statement {
|
||||
source_info,
|
||||
kind: StatementKind::Coverage(Box::new(Coverage { kind: counter_kind })),
|
||||
};
|
||||
let statement = Statement { source_info, kind: StatementKind::Coverage(counter_kind) };
|
||||
data.statements.insert(0, statement);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
use rustc_data_structures::captures::Captures;
|
||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||
use rustc_middle::mir::coverage::{CounterId, CoverageKind};
|
||||
use rustc_middle::mir::{Body, Coverage, CoverageIdsInfo, Statement, StatementKind};
|
||||
use rustc_middle::mir::{Body, CoverageIdsInfo, Statement, StatementKind};
|
||||
use rustc_middle::query::TyCtxtAt;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_middle::util::Providers;
|
||||
@ -54,7 +54,7 @@ fn coverage_ids_info<'tcx>(
|
||||
let mir_body = tcx.instance_mir(instance_def);
|
||||
|
||||
let max_counter_id = all_coverage_in_mir_body(mir_body)
|
||||
.filter_map(|coverage| match coverage.kind {
|
||||
.filter_map(|kind| match *kind {
|
||||
CoverageKind::CounterIncrement { id } => Some(id),
|
||||
_ => None,
|
||||
})
|
||||
@ -66,12 +66,10 @@ fn coverage_ids_info<'tcx>(
|
||||
|
||||
fn all_coverage_in_mir_body<'a, 'tcx>(
|
||||
body: &'a Body<'tcx>,
|
||||
) -> impl Iterator<Item = &'a Coverage> + Captures<'tcx> {
|
||||
) -> impl Iterator<Item = &'a CoverageKind> + Captures<'tcx> {
|
||||
body.basic_blocks.iter().flat_map(|bb_data| &bb_data.statements).filter_map(|statement| {
|
||||
match statement.kind {
|
||||
StatementKind::Coverage(box ref coverage) if !is_inlined(body, statement) => {
|
||||
Some(coverage)
|
||||
}
|
||||
StatementKind::Coverage(ref kind) if !is_inlined(body, statement) => Some(kind),
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
|
@ -187,9 +187,7 @@ fn filtered_statement_span(statement: &Statement<'_>) -> Option<Span> {
|
||||
// for their parent `BasicBlock`.
|
||||
StatementKind::StorageLive(_)
|
||||
| StatementKind::StorageDead(_)
|
||||
// Ignore `ConstEvalCounter`s
|
||||
| StatementKind::ConstEvalCounter
|
||||
// Ignore `Nop`s
|
||||
| StatementKind::Nop => None,
|
||||
|
||||
// FIXME(#78546): MIR InstrumentCoverage - Can the source_info.span for `FakeRead`
|
||||
@ -211,30 +209,28 @@ fn filtered_statement_span(statement: &Statement<'_>) -> Option<Span> {
|
||||
StatementKind::FakeRead(box (FakeReadCause::ForGuardBinding, _)) => None,
|
||||
|
||||
// Retain spans from most other statements.
|
||||
StatementKind::FakeRead(box (_, _)) // Not including `ForGuardBinding`
|
||||
StatementKind::FakeRead(_)
|
||||
| StatementKind::Intrinsic(..)
|
||||
| StatementKind::Coverage(box mir::Coverage {
|
||||
| StatementKind::Coverage(
|
||||
// The purpose of `SpanMarker` is to be matched and accepted here.
|
||||
kind: CoverageKind::SpanMarker
|
||||
})
|
||||
CoverageKind::SpanMarker,
|
||||
)
|
||||
| StatementKind::Assign(_)
|
||||
| StatementKind::SetDiscriminant { .. }
|
||||
| StatementKind::Deinit(..)
|
||||
| StatementKind::Retag(_, _)
|
||||
| StatementKind::PlaceMention(..)
|
||||
| StatementKind::AscribeUserType(_, _) => {
|
||||
Some(statement.source_info.span)
|
||||
}
|
||||
| StatementKind::AscribeUserType(_, _) => Some(statement.source_info.span),
|
||||
|
||||
StatementKind::Coverage(box mir::Coverage {
|
||||
// Block markers are used for branch coverage, so ignore them here.
|
||||
kind: CoverageKind::BlockMarker {..}
|
||||
}) => None,
|
||||
// Block markers are used for branch coverage, so ignore them here.
|
||||
StatementKind::Coverage(CoverageKind::BlockMarker { .. }) => None,
|
||||
|
||||
StatementKind::Coverage(box mir::Coverage {
|
||||
// These coverage statements should not exist prior to coverage instrumentation.
|
||||
kind: CoverageKind::CounterIncrement { .. } | CoverageKind::ExpressionUsed { .. }
|
||||
}) => bug!("Unexpected coverage statement found during coverage instrumentation: {statement:?}"),
|
||||
// These coverage statements should not exist prior to coverage instrumentation.
|
||||
StatementKind::Coverage(
|
||||
CoverageKind::CounterIncrement { .. } | CoverageKind::ExpressionUsed { .. },
|
||||
) => bug!(
|
||||
"Unexpected coverage statement found during coverage instrumentation: {statement:?}"
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
@ -382,9 +378,7 @@ pub(super) fn extract_branch_mappings(
|
||||
// Fill out the mapping from block marker IDs to their enclosing blocks.
|
||||
for (bb, data) in mir_body.basic_blocks.iter_enumerated() {
|
||||
for statement in &data.statements {
|
||||
if let StatementKind::Coverage(coverage) = &statement.kind
|
||||
&& let CoverageKind::BlockMarker { id } = coverage.kind
|
||||
{
|
||||
if let StatementKind::Coverage(CoverageKind::BlockMarker { id }) = statement.kind {
|
||||
block_markers[id] = Some(bb);
|
||||
}
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ pub fn provide(providers: &mut Providers) {
|
||||
cross_crate_inline::provide(providers);
|
||||
providers.queries = query::Providers {
|
||||
mir_keys,
|
||||
mir_const,
|
||||
mir_built,
|
||||
mir_const_qualif,
|
||||
mir_promoted,
|
||||
mir_drops_elaborated_and_const_checked,
|
||||
@ -259,9 +259,9 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs {
|
||||
|
||||
// N.B., this `borrow()` is guaranteed to be valid (i.e., the value
|
||||
// cannot yet be stolen), because `mir_promoted()`, which steals
|
||||
// from `mir_const()`, forces this query to execute before
|
||||
// from `mir_built()`, forces this query to execute before
|
||||
// performing the steal.
|
||||
let body = &tcx.mir_const(def).borrow();
|
||||
let body = &tcx.mir_built(def).borrow();
|
||||
|
||||
if body.return_ty().references_error() {
|
||||
// It's possible to reach here without an error being emitted (#121103).
|
||||
@ -279,19 +279,13 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs {
|
||||
validator.qualifs_in_return_place()
|
||||
}
|
||||
|
||||
/// Make MIR ready for const evaluation. This is run on all MIR, not just on consts!
|
||||
/// FIXME(oli-obk): it's unclear whether we still need this phase (and its corresponding query).
|
||||
/// We used to have this for pre-miri MIR based const eval.
|
||||
fn mir_const(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal<Body<'_>> {
|
||||
fn mir_built(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal<Body<'_>> {
|
||||
// MIR unsafety check uses the raw mir, so make sure it is run.
|
||||
if !tcx.sess.opts.unstable_opts.thir_unsafeck {
|
||||
tcx.ensure_with_value().mir_unsafety_check_result(def);
|
||||
}
|
||||
|
||||
// has_ffi_unwind_calls query uses the raw mir, so make sure it is run.
|
||||
tcx.ensure_with_value().has_ffi_unwind_calls(def);
|
||||
|
||||
let mut body = tcx.mir_built(def).steal();
|
||||
let mut body = tcx.build_mir(def);
|
||||
|
||||
pass_manager::dump_mir_for_phase_change(tcx, &body);
|
||||
|
||||
@ -339,7 +333,9 @@ fn mir_promoted(
|
||||
| DefKind::AnonConst => tcx.mir_const_qualif(def),
|
||||
_ => ConstQualifs::default(),
|
||||
};
|
||||
let mut body = tcx.mir_const(def).steal();
|
||||
// has_ffi_unwind_calls query uses the raw mir, so make sure it is run.
|
||||
tcx.ensure_with_value().has_ffi_unwind_calls(def);
|
||||
let mut body = tcx.mir_built(def).steal();
|
||||
if let Some(error_reported) = const_qualifs.tainted_by_errors {
|
||||
body.tainted_by_errors = Some(error_reported);
|
||||
}
|
||||
|
@ -16,7 +16,6 @@ use core::mem;
|
||||
use core::ops::ControlFlow;
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::token::{self, Delimiter, Token, TokenKind};
|
||||
use rustc_ast::tokenstream::Spacing;
|
||||
use rustc_ast::util::case::Case;
|
||||
use rustc_ast::util::classify;
|
||||
use rustc_ast::util::parser::{prec_let_scrutinee_needs_par, AssocOp, Fixity};
|
||||
@ -999,13 +998,57 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
pub fn parse_dot_suffix_expr(&mut self, lo: Span, base: P<Expr>) -> PResult<'a, P<Expr>> {
|
||||
// At this point we've consumed something like `expr.` and `self.token` holds the token
|
||||
// after the dot.
|
||||
match self.token.uninterpolate().kind {
|
||||
token::Ident(..) => self.parse_dot_suffix(base, lo),
|
||||
token::Literal(token::Lit { kind: token::Integer, symbol, suffix }) => {
|
||||
Ok(self.parse_expr_tuple_field_access(lo, base, symbol, suffix, None))
|
||||
let ident_span = self.token.span;
|
||||
self.bump();
|
||||
Ok(self.mk_expr_tuple_field_access(lo, ident_span, base, symbol, suffix))
|
||||
}
|
||||
token::Literal(token::Lit { kind: token::Float, symbol, suffix }) => {
|
||||
Ok(self.parse_expr_tuple_field_access_float(lo, base, symbol, suffix))
|
||||
Ok(match self.break_up_float(symbol, self.token.span) {
|
||||
// 1e2
|
||||
DestructuredFloat::Single(sym, _sp) => {
|
||||
// `foo.1e2`: a single complete dot access, fully consumed. We end up with
|
||||
// the `1e2` token in `self.prev_token` and the following token in
|
||||
// `self.token`.
|
||||
let ident_span = self.token.span;
|
||||
self.bump();
|
||||
self.mk_expr_tuple_field_access(lo, ident_span, base, sym, suffix)
|
||||
}
|
||||
// 1.
|
||||
DestructuredFloat::TrailingDot(sym, ident_span, dot_span) => {
|
||||
// `foo.1.`: a single complete dot access and the start of another.
|
||||
// We end up with the `sym` (`1`) token in `self.prev_token` and a dot in
|
||||
// `self.token`.
|
||||
assert!(suffix.is_none());
|
||||
self.token = Token::new(token::Ident(sym, IdentIsRaw::No), ident_span);
|
||||
self.bump_with((Token::new(token::Dot, dot_span), self.token_spacing));
|
||||
self.mk_expr_tuple_field_access(lo, ident_span, base, sym, None)
|
||||
}
|
||||
// 1.2 | 1.2e3
|
||||
DestructuredFloat::MiddleDot(
|
||||
sym1,
|
||||
ident1_span,
|
||||
_dot_span,
|
||||
sym2,
|
||||
ident2_span,
|
||||
) => {
|
||||
// `foo.1.2` (or `foo.1.2e3`): two complete dot accesses. We end up with
|
||||
// the `sym2` (`2` or `2e3`) token in `self.prev_token` and the following
|
||||
// token in `self.token`.
|
||||
let next_token2 =
|
||||
Token::new(token::Ident(sym2, IdentIsRaw::No), ident2_span);
|
||||
self.bump_with((next_token2, self.token_spacing));
|
||||
self.bump();
|
||||
let base1 =
|
||||
self.mk_expr_tuple_field_access(lo, ident1_span, base, sym1, None);
|
||||
self.mk_expr_tuple_field_access(lo, ident2_span, base1, sym2, suffix)
|
||||
}
|
||||
DestructuredFloat::Error => base,
|
||||
})
|
||||
}
|
||||
_ => {
|
||||
self.error_unexpected_after_dot();
|
||||
@ -1119,41 +1162,6 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_expr_tuple_field_access_float(
|
||||
&mut self,
|
||||
lo: Span,
|
||||
base: P<Expr>,
|
||||
float: Symbol,
|
||||
suffix: Option<Symbol>,
|
||||
) -> P<Expr> {
|
||||
match self.break_up_float(float, self.token.span) {
|
||||
// 1e2
|
||||
DestructuredFloat::Single(sym, _sp) => {
|
||||
self.parse_expr_tuple_field_access(lo, base, sym, suffix, None)
|
||||
}
|
||||
// 1.
|
||||
DestructuredFloat::TrailingDot(sym, ident_span, dot_span) => {
|
||||
assert!(suffix.is_none());
|
||||
self.token = Token::new(token::Ident(sym, IdentIsRaw::No), ident_span);
|
||||
let next_token = (Token::new(token::Dot, dot_span), self.token_spacing);
|
||||
self.parse_expr_tuple_field_access(lo, base, sym, None, Some(next_token))
|
||||
}
|
||||
// 1.2 | 1.2e3
|
||||
DestructuredFloat::MiddleDot(symbol1, ident1_span, dot_span, symbol2, ident2_span) => {
|
||||
self.token = Token::new(token::Ident(symbol1, IdentIsRaw::No), ident1_span);
|
||||
// This needs to be `Spacing::Alone` to prevent regressions.
|
||||
// See issue #76399 and PR #76285 for more details
|
||||
let next_token1 = (Token::new(token::Dot, dot_span), Spacing::Alone);
|
||||
let base1 =
|
||||
self.parse_expr_tuple_field_access(lo, base, symbol1, None, Some(next_token1));
|
||||
let next_token2 = Token::new(token::Ident(symbol2, IdentIsRaw::No), ident2_span);
|
||||
self.bump_with((next_token2, self.token_spacing)); // `.`
|
||||
self.parse_expr_tuple_field_access(lo, base1, symbol2, suffix, None)
|
||||
}
|
||||
DestructuredFloat::Error => base,
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse the field access used in offset_of, matched by `$(e:expr)+`.
|
||||
/// Currently returns a list of idents. However, it should be possible in
|
||||
/// future to also do array indices, which might be arbitrary expressions.
|
||||
@ -1255,24 +1263,18 @@ impl<'a> Parser<'a> {
|
||||
Ok(fields.into_iter().collect())
|
||||
}
|
||||
|
||||
fn parse_expr_tuple_field_access(
|
||||
fn mk_expr_tuple_field_access(
|
||||
&mut self,
|
||||
lo: Span,
|
||||
ident_span: Span,
|
||||
base: P<Expr>,
|
||||
field: Symbol,
|
||||
suffix: Option<Symbol>,
|
||||
next_token: Option<(Token, Spacing)>,
|
||||
) -> P<Expr> {
|
||||
match next_token {
|
||||
Some(next_token) => self.bump_with(next_token),
|
||||
None => self.bump(),
|
||||
}
|
||||
let span = self.prev_token.span;
|
||||
let field = ExprKind::Field(base, Ident::new(field, span));
|
||||
if let Some(suffix) = suffix {
|
||||
self.expect_no_tuple_index_suffix(span, suffix);
|
||||
self.expect_no_tuple_index_suffix(ident_span, suffix);
|
||||
}
|
||||
self.mk_expr(lo.to(span), field)
|
||||
self.mk_expr(lo.to(ident_span), ExprKind::Field(base, Ident::new(field, ident_span)))
|
||||
}
|
||||
|
||||
/// Parse a function call expression, `expr(...)`.
|
||||
|
@ -269,7 +269,11 @@ impl ParseSess {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_silent_emitter(locale_resources: Vec<&'static str>, fatal_note: String) -> Self {
|
||||
pub fn with_silent_emitter(
|
||||
locale_resources: Vec<&'static str>,
|
||||
fatal_note: String,
|
||||
emit_fatal_diagnostic: bool,
|
||||
) -> Self {
|
||||
let fallback_bundle = fallback_fluent_bundle(locale_resources, false);
|
||||
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
|
||||
let emitter = Box::new(HumanEmitter::new(
|
||||
@ -281,6 +285,7 @@ impl ParseSess {
|
||||
fallback_bundle,
|
||||
fatal_dcx,
|
||||
fatal_note: Some(fatal_note),
|
||||
emit_fatal_diagnostic,
|
||||
}))
|
||||
.disable_warnings();
|
||||
ParseSess::with_dcx(dcx, sm)
|
||||
|
@ -15,6 +15,7 @@ rustc_middle = { path = "../rustc_middle" }
|
||||
rustc_session = { path = "../rustc_session" }
|
||||
rustc_span = { path = "../rustc_span" }
|
||||
rustc_target = { path = "../rustc_target" }
|
||||
rustc_trait_selection = { path = "../rustc_trait_selection" }
|
||||
tracing = "0.1"
|
||||
twox-hash = "1.6.3"
|
||||
# tidy-alphabetical-end
|
||||
|
@ -90,6 +90,7 @@
|
||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
||||
#![doc(rust_logo)]
|
||||
#![feature(rustdoc_internals)]
|
||||
#![feature(let_chains)]
|
||||
#![allow(internal_features)]
|
||||
|
||||
#[macro_use]
|
||||
|
@ -36,7 +36,7 @@ pub fn typeid_for_instance<'tcx>(
|
||||
instance: &Instance<'tcx>,
|
||||
options: TypeIdOptions,
|
||||
) -> String {
|
||||
typeid_itanium_cxx_abi::typeid_for_instance(tcx, instance, options)
|
||||
typeid_itanium_cxx_abi::typeid_for_instance(tcx, *instance, options)
|
||||
}
|
||||
|
||||
/// Returns a KCFI type metadata identifier for the specified FnAbi.
|
||||
@ -61,6 +61,6 @@ pub fn kcfi_typeid_for_instance<'tcx>(
|
||||
// A KCFI type metadata identifier is a 32-bit constant produced by taking the lower half of the
|
||||
// xxHash64 of the type metadata identifier. (See llvm/llvm-project@cff5bef.)
|
||||
let mut hash: XxHash64 = Default::default();
|
||||
hash.write(typeid_itanium_cxx_abi::typeid_for_instance(tcx, instance, options).as_bytes());
|
||||
hash.write(typeid_itanium_cxx_abi::typeid_for_instance(tcx, *instance, options).as_bytes());
|
||||
hash.finish() as u32
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ use rustc_data_structures::base_n;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_hir as hir;
|
||||
use rustc_middle::ty::layout::IntegerExt;
|
||||
use rustc_middle::ty::TypeVisitableExt;
|
||||
use rustc_middle::ty::{
|
||||
self, Const, ExistentialPredicate, FloatTy, FnSig, Instance, IntTy, List, Region, RegionKind,
|
||||
TermKind, Ty, TyCtxt, UintTy,
|
||||
@ -21,7 +22,9 @@ use rustc_span::sym;
|
||||
use rustc_target::abi::call::{Conv, FnAbi, PassMode};
|
||||
use rustc_target::abi::Integer;
|
||||
use rustc_target::spec::abi::Abi;
|
||||
use rustc_trait_selection::traits;
|
||||
use std::fmt::Write as _;
|
||||
use std::iter;
|
||||
|
||||
use crate::typeid::TypeIdOptions;
|
||||
|
||||
@ -178,14 +181,14 @@ fn encode_fnsig<'tcx>(
|
||||
// Encode the return type
|
||||
let transform_ty_options = TransformTyOptions::from_bits(options.bits())
|
||||
.unwrap_or_else(|| bug!("encode_fnsig: invalid option(s) `{:?}`", options.bits()));
|
||||
let ty = transform_ty(tcx, fn_sig.output(), transform_ty_options);
|
||||
let ty = transform_ty(tcx, fn_sig.output(), &mut Vec::new(), transform_ty_options);
|
||||
s.push_str(&encode_ty(tcx, ty, dict, encode_ty_options));
|
||||
|
||||
// Encode the parameter types
|
||||
let tys = fn_sig.inputs();
|
||||
if !tys.is_empty() {
|
||||
for ty in tys {
|
||||
let ty = transform_ty(tcx, *ty, transform_ty_options);
|
||||
let ty = transform_ty(tcx, *ty, &mut Vec::new(), transform_ty_options);
|
||||
s.push_str(&encode_ty(tcx, ty, dict, encode_ty_options));
|
||||
}
|
||||
|
||||
@ -747,9 +750,8 @@ fn transform_predicates<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
predicates: &List<ty::PolyExistentialPredicate<'tcx>>,
|
||||
) -> &'tcx List<ty::PolyExistentialPredicate<'tcx>> {
|
||||
let predicates: Vec<ty::PolyExistentialPredicate<'tcx>> = predicates
|
||||
.iter()
|
||||
.filter_map(|predicate| match predicate.skip_binder() {
|
||||
tcx.mk_poly_existential_predicates_from_iter(predicates.iter().filter_map(|predicate| {
|
||||
match predicate.skip_binder() {
|
||||
ty::ExistentialPredicate::Trait(trait_ref) => {
|
||||
let trait_ref = ty::TraitRef::identity(tcx, trait_ref.def_id);
|
||||
Some(ty::Binder::dummy(ty::ExistentialPredicate::Trait(
|
||||
@ -758,20 +760,20 @@ fn transform_predicates<'tcx>(
|
||||
}
|
||||
ty::ExistentialPredicate::Projection(..) => None,
|
||||
ty::ExistentialPredicate::AutoTrait(..) => Some(predicate),
|
||||
})
|
||||
.collect();
|
||||
tcx.mk_poly_existential_predicates(&predicates)
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
/// Transforms args for being encoded and used in the substitution dictionary.
|
||||
fn transform_args<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
parents: &mut Vec<Ty<'tcx>>,
|
||||
options: TransformTyOptions,
|
||||
) -> GenericArgsRef<'tcx> {
|
||||
let args = args.iter().map(|arg| match arg.unpack() {
|
||||
GenericArgKind::Type(ty) if ty.is_c_void(tcx) => Ty::new_unit(tcx).into(),
|
||||
GenericArgKind::Type(ty) => transform_ty(tcx, ty, options).into(),
|
||||
GenericArgKind::Type(ty) => transform_ty(tcx, ty, parents, options).into(),
|
||||
_ => arg,
|
||||
});
|
||||
tcx.mk_args_from_iter(args)
|
||||
@ -781,9 +783,12 @@ fn transform_args<'tcx>(
|
||||
// c_void types into unit types unconditionally, generalizes pointers if
|
||||
// TransformTyOptions::GENERALIZE_POINTERS option is set, and normalizes integers if
|
||||
// TransformTyOptions::NORMALIZE_INTEGERS option is set.
|
||||
fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptions) -> Ty<'tcx> {
|
||||
let mut ty = ty;
|
||||
|
||||
fn transform_ty<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
mut ty: Ty<'tcx>,
|
||||
parents: &mut Vec<Ty<'tcx>>,
|
||||
options: TransformTyOptions,
|
||||
) -> Ty<'tcx> {
|
||||
match ty.kind() {
|
||||
ty::Float(..) | ty::Str | ty::Never | ty::Foreign(..) | ty::CoroutineWitness(..) => {}
|
||||
|
||||
@ -843,17 +848,20 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
|
||||
_ if ty.is_unit() => {}
|
||||
|
||||
ty::Tuple(tys) => {
|
||||
ty = Ty::new_tup_from_iter(tcx, tys.iter().map(|ty| transform_ty(tcx, ty, options)));
|
||||
ty = Ty::new_tup_from_iter(
|
||||
tcx,
|
||||
tys.iter().map(|ty| transform_ty(tcx, ty, parents, options)),
|
||||
);
|
||||
}
|
||||
|
||||
ty::Array(ty0, len) => {
|
||||
let len = len.eval_target_usize(tcx, ty::ParamEnv::reveal_all());
|
||||
|
||||
ty = Ty::new_array(tcx, transform_ty(tcx, *ty0, options), len);
|
||||
ty = Ty::new_array(tcx, transform_ty(tcx, *ty0, parents, options), len);
|
||||
}
|
||||
|
||||
ty::Slice(ty0) => {
|
||||
ty = Ty::new_slice(tcx, transform_ty(tcx, *ty0, options));
|
||||
ty = Ty::new_slice(tcx, transform_ty(tcx, *ty0, parents, options));
|
||||
}
|
||||
|
||||
ty::Adt(adt_def, args) => {
|
||||
@ -862,7 +870,8 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
|
||||
} else if options.contains(TransformTyOptions::GENERALIZE_REPR_C) && adt_def.repr().c()
|
||||
{
|
||||
ty = Ty::new_adt(tcx, *adt_def, ty::List::empty());
|
||||
} else if adt_def.repr().transparent() && adt_def.is_struct() {
|
||||
} else if adt_def.repr().transparent() && adt_def.is_struct() && !parents.contains(&ty)
|
||||
{
|
||||
// Don't transform repr(transparent) types with an user-defined CFI encoding to
|
||||
// preserve the user-defined CFI encoding.
|
||||
if let Some(_) = tcx.get_attr(adt_def.did(), sym::cfi_encoding) {
|
||||
@ -881,38 +890,48 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
|
||||
// Generalize any repr(transparent) user-defined type that is either a pointer
|
||||
// or reference, and either references itself or any other type that contains or
|
||||
// references itself, to avoid a reference cycle.
|
||||
|
||||
// If the self reference is not through a pointer, for example, due
|
||||
// to using `PhantomData`, need to skip normalizing it if we hit it again.
|
||||
parents.push(ty);
|
||||
if ty0.is_any_ptr() && ty0.contains(ty) {
|
||||
ty = transform_ty(
|
||||
tcx,
|
||||
ty0,
|
||||
parents,
|
||||
options | TransformTyOptions::GENERALIZE_POINTERS,
|
||||
);
|
||||
} else {
|
||||
ty = transform_ty(tcx, ty0, options);
|
||||
ty = transform_ty(tcx, ty0, parents, options);
|
||||
}
|
||||
parents.pop();
|
||||
} else {
|
||||
// Transform repr(transparent) types without non-ZST field into ()
|
||||
ty = Ty::new_unit(tcx);
|
||||
}
|
||||
} else {
|
||||
ty = Ty::new_adt(tcx, *adt_def, transform_args(tcx, args, options));
|
||||
ty = Ty::new_adt(tcx, *adt_def, transform_args(tcx, args, parents, options));
|
||||
}
|
||||
}
|
||||
|
||||
ty::FnDef(def_id, args) => {
|
||||
ty = Ty::new_fn_def(tcx, *def_id, transform_args(tcx, args, options));
|
||||
ty = Ty::new_fn_def(tcx, *def_id, transform_args(tcx, args, parents, options));
|
||||
}
|
||||
|
||||
ty::Closure(def_id, args) => {
|
||||
ty = Ty::new_closure(tcx, *def_id, transform_args(tcx, args, options));
|
||||
ty = Ty::new_closure(tcx, *def_id, transform_args(tcx, args, parents, options));
|
||||
}
|
||||
|
||||
ty::CoroutineClosure(def_id, args) => {
|
||||
ty = Ty::new_coroutine_closure(tcx, *def_id, transform_args(tcx, args, options));
|
||||
ty = Ty::new_coroutine_closure(
|
||||
tcx,
|
||||
*def_id,
|
||||
transform_args(tcx, args, parents, options),
|
||||
);
|
||||
}
|
||||
|
||||
ty::Coroutine(def_id, args) => {
|
||||
ty = Ty::new_coroutine(tcx, *def_id, transform_args(tcx, args, options));
|
||||
ty = Ty::new_coroutine(tcx, *def_id, transform_args(tcx, args, parents, options));
|
||||
}
|
||||
|
||||
ty::Ref(region, ty0, ..) => {
|
||||
@ -924,9 +943,9 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
|
||||
}
|
||||
} else {
|
||||
if ty.is_mutable_ptr() {
|
||||
ty = Ty::new_mut_ref(tcx, *region, transform_ty(tcx, *ty0, options));
|
||||
ty = Ty::new_mut_ref(tcx, *region, transform_ty(tcx, *ty0, parents, options));
|
||||
} else {
|
||||
ty = Ty::new_imm_ref(tcx, *region, transform_ty(tcx, *ty0, options));
|
||||
ty = Ty::new_imm_ref(tcx, *region, transform_ty(tcx, *ty0, parents, options));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -940,9 +959,9 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
|
||||
}
|
||||
} else {
|
||||
if ty.is_mutable_ptr() {
|
||||
ty = Ty::new_mut_ptr(tcx, transform_ty(tcx, *ptr_ty, options));
|
||||
ty = Ty::new_mut_ptr(tcx, transform_ty(tcx, *ptr_ty, parents, options));
|
||||
} else {
|
||||
ty = Ty::new_imm_ptr(tcx, transform_ty(tcx, *ptr_ty, options));
|
||||
ty = Ty::new_imm_ptr(tcx, transform_ty(tcx, *ptr_ty, parents, options));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -955,9 +974,9 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
|
||||
.skip_binder()
|
||||
.inputs()
|
||||
.iter()
|
||||
.map(|ty| transform_ty(tcx, *ty, options))
|
||||
.map(|ty| transform_ty(tcx, *ty, parents, options))
|
||||
.collect();
|
||||
let output = transform_ty(tcx, fn_sig.skip_binder().output(), options);
|
||||
let output = transform_ty(tcx, fn_sig.skip_binder().output(), parents, options);
|
||||
ty = Ty::new_fn_ptr(
|
||||
tcx,
|
||||
ty::Binder::bind_with_vars(
|
||||
@ -987,6 +1006,7 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
|
||||
ty = transform_ty(
|
||||
tcx,
|
||||
tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty),
|
||||
parents,
|
||||
options,
|
||||
);
|
||||
}
|
||||
@ -1037,7 +1057,7 @@ pub fn typeid_for_fnabi<'tcx>(
|
||||
// Encode the return type
|
||||
let transform_ty_options = TransformTyOptions::from_bits(options.bits())
|
||||
.unwrap_or_else(|| bug!("typeid_for_fnabi: invalid option(s) `{:?}`", options.bits()));
|
||||
let ty = transform_ty(tcx, fn_abi.ret.layout.ty, transform_ty_options);
|
||||
let ty = transform_ty(tcx, fn_abi.ret.layout.ty, &mut Vec::new(), transform_ty_options);
|
||||
typeid.push_str(&encode_ty(tcx, ty, &mut dict, encode_ty_options));
|
||||
|
||||
// Encode the parameter types
|
||||
@ -1049,7 +1069,7 @@ pub fn typeid_for_fnabi<'tcx>(
|
||||
let mut pushed_arg = false;
|
||||
for arg in fn_abi.args.iter().filter(|arg| arg.mode != PassMode::Ignore) {
|
||||
pushed_arg = true;
|
||||
let ty = transform_ty(tcx, arg.layout.ty, transform_ty_options);
|
||||
let ty = transform_ty(tcx, arg.layout.ty, &mut Vec::new(), transform_ty_options);
|
||||
typeid.push_str(&encode_ty(tcx, ty, &mut dict, encode_ty_options));
|
||||
}
|
||||
if !pushed_arg {
|
||||
@ -1062,7 +1082,8 @@ pub fn typeid_for_fnabi<'tcx>(
|
||||
if fn_abi.args[n].mode == PassMode::Ignore {
|
||||
continue;
|
||||
}
|
||||
let ty = transform_ty(tcx, fn_abi.args[n].layout.ty, transform_ty_options);
|
||||
let ty =
|
||||
transform_ty(tcx, fn_abi.args[n].layout.ty, &mut Vec::new(), transform_ty_options);
|
||||
typeid.push_str(&encode_ty(tcx, ty, &mut dict, encode_ty_options));
|
||||
}
|
||||
|
||||
@ -1088,53 +1109,108 @@ pub fn typeid_for_fnabi<'tcx>(
|
||||
/// vendor extended type qualifiers and types for Rust types that are not used at the FFI boundary.
|
||||
pub fn typeid_for_instance<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
instance: &Instance<'tcx>,
|
||||
mut instance: Instance<'tcx>,
|
||||
options: TypeIdOptions,
|
||||
) -> String {
|
||||
if matches!(instance.def, ty::InstanceDef::Virtual(..)) {
|
||||
instance.args = strip_receiver_auto(tcx, instance.args)
|
||||
}
|
||||
|
||||
if let Some(impl_id) = tcx.impl_of_method(instance.def_id())
|
||||
&& let Some(trait_ref) = tcx.impl_trait_ref(impl_id)
|
||||
{
|
||||
let impl_method = tcx.associated_item(instance.def_id());
|
||||
let method_id = impl_method
|
||||
.trait_item_def_id
|
||||
.expect("Part of a trait implementation, but not linked to the def_id?");
|
||||
let trait_method = tcx.associated_item(method_id);
|
||||
if traits::is_vtable_safe_method(tcx, trait_ref.skip_binder().def_id, trait_method) {
|
||||
// Trait methods will have a Self polymorphic parameter, where the concreteized
|
||||
// implementatation will not. We need to walk back to the more general trait method
|
||||
let trait_ref = tcx.instantiate_and_normalize_erasing_regions(
|
||||
instance.args,
|
||||
ty::ParamEnv::reveal_all(),
|
||||
trait_ref,
|
||||
);
|
||||
let invoke_ty = trait_object_ty(tcx, ty::Binder::dummy(trait_ref));
|
||||
|
||||
// At the call site, any call to this concrete function through a vtable will be
|
||||
// `Virtual(method_id, idx)` with appropriate arguments for the method. Since we have the
|
||||
// original method id, and we've recovered the trait arguments, we can make the callee
|
||||
// instance we're computing the alias set for match the caller instance.
|
||||
//
|
||||
// Right now, our code ignores the vtable index everywhere, so we use 0 as a placeholder.
|
||||
// If we ever *do* start encoding the vtable index, we will need to generate an alias set
|
||||
// based on which vtables we are putting this method into, as there will be more than one
|
||||
// index value when supertraits are involved.
|
||||
instance.def = ty::InstanceDef::Virtual(method_id, 0);
|
||||
let abstract_trait_args =
|
||||
tcx.mk_args_trait(invoke_ty, trait_ref.args.into_iter().skip(1));
|
||||
instance.args = instance.args.rebase_onto(tcx, impl_id, abstract_trait_args);
|
||||
}
|
||||
}
|
||||
|
||||
let fn_abi = tcx
|
||||
.fn_abi_of_instance(tcx.param_env(instance.def_id()).and((*instance, ty::List::empty())))
|
||||
.fn_abi_of_instance(tcx.param_env(instance.def_id()).and((instance, ty::List::empty())))
|
||||
.unwrap_or_else(|instance| {
|
||||
bug!("typeid_for_instance: couldn't get fn_abi of instance {:?}", instance)
|
||||
});
|
||||
|
||||
// If this instance is a method and self is a reference, get the impl it belongs to
|
||||
let impl_def_id = tcx.impl_of_method(instance.def_id());
|
||||
if impl_def_id.is_some() && !fn_abi.args.is_empty() && fn_abi.args[0].layout.ty.is_ref() {
|
||||
// If this impl is not an inherent impl, get the trait it implements
|
||||
if let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id.unwrap()) {
|
||||
// Transform the concrete self into a reference to a trait object
|
||||
let existential_predicate = trait_ref.map_bound(|trait_ref| {
|
||||
ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef::erase_self_ty(
|
||||
tcx, trait_ref,
|
||||
))
|
||||
});
|
||||
let existential_predicates = tcx.mk_poly_existential_predicates(&[ty::Binder::dummy(
|
||||
existential_predicate.skip_binder(),
|
||||
)]);
|
||||
// Is the concrete self mutable?
|
||||
let self_ty = if fn_abi.args[0].layout.ty.is_mutable_ptr() {
|
||||
Ty::new_mut_ref(
|
||||
tcx,
|
||||
tcx.lifetimes.re_erased,
|
||||
Ty::new_dynamic(tcx, existential_predicates, tcx.lifetimes.re_erased, ty::Dyn),
|
||||
)
|
||||
} else {
|
||||
Ty::new_imm_ref(
|
||||
tcx,
|
||||
tcx.lifetimes.re_erased,
|
||||
Ty::new_dynamic(tcx, existential_predicates, tcx.lifetimes.re_erased, ty::Dyn),
|
||||
)
|
||||
};
|
||||
|
||||
// Replace the concrete self in an fn_abi clone by the reference to a trait object
|
||||
let mut fn_abi = fn_abi.clone();
|
||||
// HACK(rcvalle): It is okay to not replace or update the entire ArgAbi here because the
|
||||
// other fields are never used.
|
||||
fn_abi.args[0].layout.ty = self_ty;
|
||||
|
||||
return typeid_for_fnabi(tcx, &fn_abi, options);
|
||||
}
|
||||
}
|
||||
|
||||
typeid_for_fnabi(tcx, fn_abi, options)
|
||||
}
|
||||
|
||||
fn strip_receiver_auto<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
args: ty::GenericArgsRef<'tcx>,
|
||||
) -> ty::GenericArgsRef<'tcx> {
|
||||
let ty = args.type_at(0);
|
||||
let ty::Dynamic(preds, lifetime, kind) = ty.kind() else {
|
||||
bug!("Tried to strip auto traits from non-dynamic type {ty}");
|
||||
};
|
||||
let new_rcvr = if preds.principal().is_some() {
|
||||
let filtered_preds =
|
||||
tcx.mk_poly_existential_predicates_from_iter(preds.into_iter().filter(|pred| {
|
||||
!matches!(pred.skip_binder(), ty::ExistentialPredicate::AutoTrait(..))
|
||||
}));
|
||||
Ty::new_dynamic(tcx, filtered_preds, *lifetime, *kind)
|
||||
} else {
|
||||
// If there's no principal type, re-encode it as a unit, since we don't know anything
|
||||
// about it. This technically discards the knowledge that it was a type that was made
|
||||
// into a trait object at some point, but that's not a lot.
|
||||
tcx.types.unit
|
||||
};
|
||||
tcx.mk_args_trait(new_rcvr, args.into_iter().skip(1))
|
||||
}
|
||||
|
||||
fn trait_object_ty<'tcx>(tcx: TyCtxt<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tcx>) -> Ty<'tcx> {
|
||||
assert!(!poly_trait_ref.has_non_region_param());
|
||||
let principal_pred = poly_trait_ref.map_bound(|trait_ref| {
|
||||
ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref))
|
||||
});
|
||||
let mut assoc_preds: Vec<_> = traits::supertraits(tcx, poly_trait_ref)
|
||||
.flat_map(|super_poly_trait_ref| {
|
||||
tcx.associated_items(super_poly_trait_ref.def_id())
|
||||
.in_definition_order()
|
||||
.filter(|item| item.kind == ty::AssocKind::Type)
|
||||
.map(move |assoc_ty| {
|
||||
super_poly_trait_ref.map_bound(|super_trait_ref| {
|
||||
let alias_ty = ty::AliasTy::new(tcx, assoc_ty.def_id, super_trait_ref.args);
|
||||
let resolved = tcx.normalize_erasing_regions(
|
||||
ty::ParamEnv::reveal_all(),
|
||||
alias_ty.to_ty(tcx),
|
||||
);
|
||||
ty::ExistentialPredicate::Projection(ty::ExistentialProjection {
|
||||
def_id: assoc_ty.def_id,
|
||||
args: ty::ExistentialTraitRef::erase_self_ty(tcx, super_trait_ref).args,
|
||||
term: resolved.into(),
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
assoc_preds.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder()));
|
||||
let preds = tcx.mk_poly_existential_predicates_from_iter(
|
||||
iter::once(principal_pred).chain(assoc_preds.into_iter()),
|
||||
);
|
||||
Ty::new_dynamic(tcx, preds, tcx.lifetimes.re_erased, ty::Dyn)
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::{InlineAsmArch, InlineAsmType};
|
||||
use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
|
||||
use crate::spec::{RelocModel, Target};
|
||||
use rustc_data_structures::fx::FxIndexSet;
|
||||
use rustc_macros::HashStable_Generic;
|
||||
@ -27,32 +27,28 @@ impl AArch64InlineAsmRegClass {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn suggest_modifier(
|
||||
self,
|
||||
_arch: InlineAsmArch,
|
||||
ty: InlineAsmType,
|
||||
) -> Option<(char, &'static str)> {
|
||||
pub fn suggest_modifier(self, _arch: InlineAsmArch, ty: InlineAsmType) -> Option<ModifierInfo> {
|
||||
match self {
|
||||
Self::reg => match ty.size().bits() {
|
||||
64 => None,
|
||||
_ => Some(('w', "w0")),
|
||||
_ => Some(('w', "w0", 32).into()),
|
||||
},
|
||||
Self::vreg | Self::vreg_low16 => match ty.size().bits() {
|
||||
8 => Some(('b', "b0")),
|
||||
16 => Some(('h', "h0")),
|
||||
32 => Some(('s', "s0")),
|
||||
64 => Some(('d', "d0")),
|
||||
128 => Some(('q', "q0")),
|
||||
8 => Some(('b', "b0", 8).into()),
|
||||
16 => Some(('h', "h0", 16).into()),
|
||||
32 => Some(('s', "s0", 32).into()),
|
||||
64 => Some(('d', "d0", 64).into()),
|
||||
128 => Some(('q', "q0", 128).into()),
|
||||
_ => None,
|
||||
},
|
||||
Self::preg => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
|
||||
pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<ModifierInfo> {
|
||||
match self {
|
||||
Self::reg => Some(('x', "x0")),
|
||||
Self::vreg | Self::vreg_low16 => Some(('v', "v0")),
|
||||
Self::reg => Some(('x', "x0", 64).into()),
|
||||
Self::vreg | Self::vreg_low16 => Some(('v', "v0", 128).into()),
|
||||
Self::preg => None,
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::{InlineAsmArch, InlineAsmType};
|
||||
use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
|
||||
use crate::spec::{RelocModel, Target};
|
||||
use rustc_data_structures::fx::FxIndexSet;
|
||||
use rustc_macros::HashStable_Generic;
|
||||
@ -35,11 +35,11 @@ impl ArmInlineAsmRegClass {
|
||||
self,
|
||||
_arch: InlineAsmArch,
|
||||
_ty: InlineAsmType,
|
||||
) -> Option<(char, &'static str)> {
|
||||
) -> Option<ModifierInfo> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
|
||||
pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<ModifierInfo> {
|
||||
None
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::{InlineAsmArch, InlineAsmType};
|
||||
use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use rustc_span::Symbol;
|
||||
use std::fmt;
|
||||
@ -29,11 +29,11 @@ impl AvrInlineAsmRegClass {
|
||||
self,
|
||||
_arch: InlineAsmArch,
|
||||
_ty: InlineAsmType,
|
||||
) -> Option<(char, &'static str)> {
|
||||
) -> Option<ModifierInfo> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
|
||||
pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<ModifierInfo> {
|
||||
None
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::{InlineAsmArch, InlineAsmType};
|
||||
use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use rustc_span::Symbol;
|
||||
use std::fmt;
|
||||
@ -23,11 +23,11 @@ impl BpfInlineAsmRegClass {
|
||||
self,
|
||||
_arch: InlineAsmArch,
|
||||
_ty: InlineAsmType,
|
||||
) -> Option<(char, &'static str)> {
|
||||
) -> Option<ModifierInfo> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
|
||||
pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<ModifierInfo> {
|
||||
None
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::{InlineAsmArch, InlineAsmType};
|
||||
use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use rustc_span::Symbol;
|
||||
use std::fmt;
|
||||
@ -23,11 +23,11 @@ impl CSKYInlineAsmRegClass {
|
||||
self,
|
||||
_arch: InlineAsmArch,
|
||||
_ty: InlineAsmType,
|
||||
) -> Option<(char, &'static str)> {
|
||||
) -> Option<ModifierInfo> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
|
||||
pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<ModifierInfo> {
|
||||
None
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::{InlineAsmArch, InlineAsmType};
|
||||
use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use rustc_span::Symbol;
|
||||
use std::fmt;
|
||||
@ -22,11 +22,11 @@ impl HexagonInlineAsmRegClass {
|
||||
self,
|
||||
_arch: InlineAsmArch,
|
||||
_ty: InlineAsmType,
|
||||
) -> Option<(char, &'static str)> {
|
||||
) -> Option<ModifierInfo> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
|
||||
pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<ModifierInfo> {
|
||||
None
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::{InlineAsmArch, InlineAsmType};
|
||||
use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use rustc_span::Symbol;
|
||||
use std::fmt;
|
||||
@ -23,11 +23,11 @@ impl LoongArchInlineAsmRegClass {
|
||||
self,
|
||||
_arch: InlineAsmArch,
|
||||
_ty: InlineAsmType,
|
||||
) -> Option<(char, &'static str)> {
|
||||
) -> Option<ModifierInfo> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
|
||||
pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<ModifierInfo> {
|
||||
None
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::{InlineAsmArch, InlineAsmType};
|
||||
use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use rustc_span::Symbol;
|
||||
use std::fmt;
|
||||
@ -24,11 +24,11 @@ impl M68kInlineAsmRegClass {
|
||||
self,
|
||||
_arch: InlineAsmArch,
|
||||
_ty: InlineAsmType,
|
||||
) -> Option<(char, &'static str)> {
|
||||
) -> Option<ModifierInfo> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
|
||||
pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<ModifierInfo> {
|
||||
None
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::{InlineAsmArch, InlineAsmType};
|
||||
use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use rustc_span::Symbol;
|
||||
use std::fmt;
|
||||
@ -23,11 +23,11 @@ impl MipsInlineAsmRegClass {
|
||||
self,
|
||||
_arch: InlineAsmArch,
|
||||
_ty: InlineAsmType,
|
||||
) -> Option<(char, &'static str)> {
|
||||
) -> Option<ModifierInfo> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
|
||||
pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<ModifierInfo> {
|
||||
None
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,18 @@ use rustc_span::Symbol;
|
||||
use std::fmt;
|
||||
use std::str::FromStr;
|
||||
|
||||
pub struct ModifierInfo {
|
||||
pub modifier: char,
|
||||
pub result: &'static str,
|
||||
pub size: u64,
|
||||
}
|
||||
|
||||
impl From<(char, &'static str, u64)> for ModifierInfo {
|
||||
fn from((modifier, result, size): (char, &'static str, u64)) -> Self {
|
||||
Self { modifier, result, size }
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! def_reg_class {
|
||||
($arch:ident $arch_regclass:ident {
|
||||
$(
|
||||
@ -512,11 +524,7 @@ impl InlineAsmRegClass {
|
||||
/// Such suggestions are useful if a type smaller than the full register
|
||||
/// size is used and a modifier can be used to point to the subregister of
|
||||
/// the correct size.
|
||||
pub fn suggest_modifier(
|
||||
self,
|
||||
arch: InlineAsmArch,
|
||||
ty: InlineAsmType,
|
||||
) -> Option<(char, &'static str)> {
|
||||
pub fn suggest_modifier(self, arch: InlineAsmArch, ty: InlineAsmType) -> Option<ModifierInfo> {
|
||||
match self {
|
||||
Self::X86(r) => r.suggest_modifier(arch, ty),
|
||||
Self::Arm(r) => r.suggest_modifier(arch, ty),
|
||||
@ -545,7 +553,7 @@ impl InlineAsmRegClass {
|
||||
/// This is only needed when the register class can suggest a modifier, so
|
||||
/// that the user can be shown how to get the default behavior without a
|
||||
/// warning.
|
||||
pub fn default_modifier(self, arch: InlineAsmArch) -> Option<(char, &'static str)> {
|
||||
pub fn default_modifier(self, arch: InlineAsmArch) -> Option<ModifierInfo> {
|
||||
match self {
|
||||
Self::X86(r) => r.default_modifier(arch),
|
||||
Self::Arm(r) => r.default_modifier(arch),
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::{InlineAsmArch, InlineAsmType};
|
||||
use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use rustc_span::Symbol;
|
||||
use std::fmt;
|
||||
@ -22,11 +22,11 @@ impl Msp430InlineAsmRegClass {
|
||||
self,
|
||||
_arch: InlineAsmArch,
|
||||
_ty: InlineAsmType,
|
||||
) -> Option<(char, &'static str)> {
|
||||
) -> Option<ModifierInfo> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
|
||||
pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<ModifierInfo> {
|
||||
None
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::{InlineAsmArch, InlineAsmType};
|
||||
use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use rustc_span::Symbol;
|
||||
|
||||
@ -23,11 +23,11 @@ impl NvptxInlineAsmRegClass {
|
||||
self,
|
||||
_arch: InlineAsmArch,
|
||||
_ty: InlineAsmType,
|
||||
) -> Option<(char, &'static str)> {
|
||||
) -> Option<ModifierInfo> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
|
||||
pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<ModifierInfo> {
|
||||
None
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::{InlineAsmArch, InlineAsmType};
|
||||
use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use rustc_span::Symbol;
|
||||
use std::fmt;
|
||||
@ -26,11 +26,11 @@ impl PowerPCInlineAsmRegClass {
|
||||
self,
|
||||
_arch: InlineAsmArch,
|
||||
_ty: InlineAsmType,
|
||||
) -> Option<(char, &'static str)> {
|
||||
) -> Option<ModifierInfo> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
|
||||
pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<ModifierInfo> {
|
||||
None
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::{InlineAsmArch, InlineAsmType};
|
||||
use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
|
||||
use crate::spec::{RelocModel, Target};
|
||||
use rustc_data_structures::fx::FxIndexSet;
|
||||
use rustc_macros::HashStable_Generic;
|
||||
@ -26,11 +26,11 @@ impl RiscVInlineAsmRegClass {
|
||||
self,
|
||||
_arch: InlineAsmArch,
|
||||
_ty: InlineAsmType,
|
||||
) -> Option<(char, &'static str)> {
|
||||
) -> Option<ModifierInfo> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
|
||||
pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<ModifierInfo> {
|
||||
None
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::{InlineAsmArch, InlineAsmType};
|
||||
use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use rustc_span::Symbol;
|
||||
use std::fmt;
|
||||
@ -24,11 +24,11 @@ impl S390xInlineAsmRegClass {
|
||||
self,
|
||||
_arch: InlineAsmArch,
|
||||
_ty: InlineAsmType,
|
||||
) -> Option<(char, &'static str)> {
|
||||
) -> Option<ModifierInfo> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
|
||||
pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<ModifierInfo> {
|
||||
None
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::{InlineAsmArch, InlineAsmType};
|
||||
use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use rustc_span::Symbol;
|
||||
|
||||
@ -21,11 +21,11 @@ impl SpirVInlineAsmRegClass {
|
||||
self,
|
||||
_arch: InlineAsmArch,
|
||||
_ty: InlineAsmType,
|
||||
) -> Option<(char, &'static str)> {
|
||||
) -> Option<ModifierInfo> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
|
||||
pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<ModifierInfo> {
|
||||
None
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::{InlineAsmArch, InlineAsmType};
|
||||
use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use rustc_span::Symbol;
|
||||
|
||||
@ -21,11 +21,11 @@ impl WasmInlineAsmRegClass {
|
||||
self,
|
||||
_arch: InlineAsmArch,
|
||||
_ty: InlineAsmType,
|
||||
) -> Option<(char, &'static str)> {
|
||||
) -> Option<ModifierInfo> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
|
||||
pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<ModifierInfo> {
|
||||
None
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::{InlineAsmArch, InlineAsmType};
|
||||
use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
|
||||
use crate::spec::{RelocModel, Target};
|
||||
use rustc_data_structures::fx::FxIndexSet;
|
||||
use rustc_macros::HashStable_Generic;
|
||||
@ -53,32 +53,28 @@ impl X86InlineAsmRegClass {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn suggest_modifier(
|
||||
self,
|
||||
arch: InlineAsmArch,
|
||||
ty: InlineAsmType,
|
||||
) -> Option<(char, &'static str)> {
|
||||
pub fn suggest_modifier(self, arch: InlineAsmArch, ty: InlineAsmType) -> Option<ModifierInfo> {
|
||||
match self {
|
||||
Self::reg => match ty.size().bits() {
|
||||
16 => Some(('x', "ax")),
|
||||
32 if arch == InlineAsmArch::X86_64 => Some(('e', "eax")),
|
||||
16 => Some(('x', "ax", 16).into()),
|
||||
32 if arch == InlineAsmArch::X86_64 => Some(('e', "eax", 32).into()),
|
||||
_ => None,
|
||||
},
|
||||
Self::reg_abcd => match ty.size().bits() {
|
||||
16 => Some(('x', "ax")),
|
||||
32 if arch == InlineAsmArch::X86_64 => Some(('e', "eax")),
|
||||
16 => Some(('x', "ax", 16).into()),
|
||||
32 if arch == InlineAsmArch::X86_64 => Some(('e', "eax", 32).into()),
|
||||
_ => None,
|
||||
},
|
||||
Self::reg_byte => None,
|
||||
Self::xmm_reg => None,
|
||||
Self::ymm_reg => match ty.size().bits() {
|
||||
256 => None,
|
||||
_ => Some(('x', "xmm0")),
|
||||
_ => Some(('x', "xmm0", 128).into()),
|
||||
},
|
||||
Self::zmm_reg => match ty.size().bits() {
|
||||
512 => None,
|
||||
256 => Some(('y', "ymm0")),
|
||||
_ => Some(('x', "xmm0")),
|
||||
256 => Some(('y', "ymm0", 256).into()),
|
||||
_ => Some(('x', "xmm0", 128).into()),
|
||||
},
|
||||
Self::kreg | Self::kreg0 => None,
|
||||
Self::mmx_reg | Self::x87_reg => None,
|
||||
@ -86,19 +82,19 @@ impl X86InlineAsmRegClass {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn default_modifier(self, arch: InlineAsmArch) -> Option<(char, &'static str)> {
|
||||
pub fn default_modifier(self, arch: InlineAsmArch) -> Option<ModifierInfo> {
|
||||
match self {
|
||||
Self::reg | Self::reg_abcd => {
|
||||
if arch == InlineAsmArch::X86_64 {
|
||||
Some(('r', "rax"))
|
||||
Some(('r', "rax", 64).into())
|
||||
} else {
|
||||
Some(('e', "eax"))
|
||||
Some(('e', "eax", 32).into())
|
||||
}
|
||||
}
|
||||
Self::reg_byte => None,
|
||||
Self::xmm_reg => Some(('x', "xmm0")),
|
||||
Self::ymm_reg => Some(('y', "ymm0")),
|
||||
Self::zmm_reg => Some(('z', "zmm0")),
|
||||
Self::xmm_reg => Some(('x', "xmm0", 128).into()),
|
||||
Self::ymm_reg => Some(('y', "ymm0", 256).into()),
|
||||
Self::zmm_reg => Some(('z', "zmm0", 512).into()),
|
||||
Self::kreg | Self::kreg0 => None,
|
||||
Self::mmx_reg | Self::x87_reg => None,
|
||||
Self::tmm_reg => None,
|
||||
|
@ -3536,12 +3536,39 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||
let mut err =
|
||||
self.dcx().struct_span_err(span, "unconstrained generic constant");
|
||||
let const_span = self.tcx.def_span(uv.def);
|
||||
|
||||
let const_ty = self.tcx.type_of(uv.def).instantiate(self.tcx, uv.args);
|
||||
let cast = if const_ty != self.tcx.types.usize { " as usize" } else { "" };
|
||||
let msg = "try adding a `where` bound";
|
||||
match self.tcx.sess.source_map().span_to_snippet(const_span) {
|
||||
Ok(snippet) => err.help(format!(
|
||||
"try adding a `where` bound using this expression: `where [(); {snippet}]:`"
|
||||
)),
|
||||
_ => err.help("consider adding a `where` bound using this expression"),
|
||||
};
|
||||
Ok(snippet) => {
|
||||
let code = format!("[(); {snippet}{cast}]:");
|
||||
let def_id = if let ObligationCauseCode::CompareImplItemObligation {
|
||||
trait_item_def_id,
|
||||
..
|
||||
} = obligation.cause.code()
|
||||
{
|
||||
trait_item_def_id.as_local()
|
||||
} else {
|
||||
Some(obligation.cause.body_id)
|
||||
};
|
||||
if let Some(def_id) = def_id
|
||||
&& let Some(generics) = self.tcx.hir().get_generics(def_id)
|
||||
{
|
||||
err.span_suggestion_verbose(
|
||||
generics.tail_span_for_predicate_suggestion(),
|
||||
msg,
|
||||
format!("{} {code}", generics.add_where_or_trailing_comma()),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
} else {
|
||||
err.help(format!("{msg}: where {code}"));
|
||||
};
|
||||
}
|
||||
_ => {
|
||||
err.help(msg);
|
||||
}
|
||||
};
|
||||
Ok(err)
|
||||
}
|
||||
ty::ConstKind::Expr(_) => {
|
||||
|
@ -55,7 +55,7 @@ impl IndexedVal for AllocId {
|
||||
/// Utility function used to read an allocation data into a unassigned integer.
|
||||
pub(crate) fn read_target_uint(mut bytes: &[u8]) -> Result<u128, Error> {
|
||||
let mut buf = [0u8; std::mem::size_of::<u128>()];
|
||||
match MachineInfo::target_endianess() {
|
||||
match MachineInfo::target_endianness() {
|
||||
Endian::Little => {
|
||||
bytes.read_exact(&mut buf[..bytes.len()])?;
|
||||
Ok(u128::from_le_bytes(buf))
|
||||
@ -70,7 +70,7 @@ pub(crate) fn read_target_uint(mut bytes: &[u8]) -> Result<u128, Error> {
|
||||
/// Utility function used to read an allocation data into an assigned integer.
|
||||
pub(crate) fn read_target_int(mut bytes: &[u8]) -> Result<i128, Error> {
|
||||
let mut buf = [0u8; std::mem::size_of::<i128>()];
|
||||
match MachineInfo::target_endianess() {
|
||||
match MachineInfo::target_endianness() {
|
||||
Endian::Little => {
|
||||
bytes.read_exact(&mut buf[..bytes.len()])?;
|
||||
Ok(i128::from_le_bytes(buf))
|
||||
|
@ -14,7 +14,7 @@ impl MachineInfo {
|
||||
with(|cx| cx.target_info())
|
||||
}
|
||||
|
||||
pub fn target_endianess() -> Endian {
|
||||
pub fn target_endianness() -> Endian {
|
||||
with(|cx| cx.target_info().endian)
|
||||
}
|
||||
|
||||
|
@ -201,7 +201,7 @@ pub trait Write {
|
||||
impl<W: Write + ?Sized> SpecWriteFmt for &mut W {
|
||||
#[inline]
|
||||
default fn spec_write_fmt(mut self, args: Arguments<'_>) -> Result {
|
||||
if let Some(s) = args.as_const_str() {
|
||||
if let Some(s) = args.as_statically_known_str() {
|
||||
self.write_str(s)
|
||||
} else {
|
||||
write(&mut self, args)
|
||||
@ -212,7 +212,7 @@ pub trait Write {
|
||||
impl<W: Write> SpecWriteFmt for &mut W {
|
||||
#[inline]
|
||||
fn spec_write_fmt(self, args: Arguments<'_>) -> Result {
|
||||
if let Some(s) = args.as_const_str() {
|
||||
if let Some(s) = args.as_statically_known_str() {
|
||||
self.write_str(s)
|
||||
} else {
|
||||
write(self, args)
|
||||
@ -442,7 +442,7 @@ impl<'a> Arguments<'a> {
|
||||
/// Same as [`Arguments::as_str`], but will only return `Some(s)` if it can be determined at compile time.
|
||||
#[must_use]
|
||||
#[inline]
|
||||
fn as_const_str(&self) -> Option<&'static str> {
|
||||
fn as_statically_known_str(&self) -> Option<&'static str> {
|
||||
let s = self.as_str();
|
||||
if core::intrinsics::is_val_statically_known(s.is_some()) { s } else { None }
|
||||
}
|
||||
@ -1617,7 +1617,11 @@ impl<'a> Formatter<'a> {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn write_fmt(&mut self, fmt: Arguments<'_>) -> Result {
|
||||
if let Some(s) = fmt.as_const_str() { self.buf.write_str(s) } else { write(self.buf, fmt) }
|
||||
if let Some(s) = fmt.as_statically_known_str() {
|
||||
self.buf.write_str(s)
|
||||
} else {
|
||||
write(self.buf, fmt)
|
||||
}
|
||||
}
|
||||
|
||||
/// Flags for formatting
|
||||
@ -2308,7 +2312,7 @@ impl Write for Formatter<'_> {
|
||||
|
||||
#[inline]
|
||||
fn write_fmt(&mut self, args: Arguments<'_>) -> Result {
|
||||
if let Some(s) = args.as_const_str() {
|
||||
if let Some(s) = args.as_statically_known_str() {
|
||||
self.buf.write_str(s)
|
||||
} else {
|
||||
write(self.buf, args)
|
||||
|
@ -1356,7 +1356,7 @@ extern "rust-intrinsic" {
|
||||
/// let v_clone = v_orig.clone();
|
||||
///
|
||||
/// // This is the suggested, safe way.
|
||||
/// // It does copy the entire vector, though, into a new array.
|
||||
/// // It may copy the entire vector into a new one though, but also may not.
|
||||
/// let v_collected = v_clone.into_iter()
|
||||
/// .map(Some)
|
||||
/// .collect::<Vec<Option<&i32>>>();
|
||||
|
@ -470,7 +470,7 @@ extern "rust-intrinsic" {
|
||||
/// No matter whether the output is an array or an unsigned integer, it is treated as a single
|
||||
/// contiguous list of bits. The bitmask is always packed on the least-significant side of the
|
||||
/// output, and padded with 0s in the most-significant bits. The order of the bits depends on
|
||||
/// endianess:
|
||||
/// endianness:
|
||||
///
|
||||
/// * On little endian, the least significant bit corresponds to the first vector element.
|
||||
/// * On big endian, the least significant bit corresponds to the last vector element.
|
||||
|
@ -328,6 +328,7 @@
|
||||
#![feature(float_gamma)]
|
||||
#![feature(float_minimum_maximum)]
|
||||
#![feature(float_next_up_down)]
|
||||
#![feature(fmt_internals)]
|
||||
#![feature(generic_nonzero)]
|
||||
#![feature(hasher_prefixfree_extras)]
|
||||
#![feature(hashmap_internals)]
|
||||
|
@ -391,6 +391,7 @@ pub mod panic_count {
|
||||
pub fn increase(run_panic_hook: bool) -> Option<MustAbort> {
|
||||
let global_count = GLOBAL_PANIC_COUNT.fetch_add(1, Ordering::Relaxed);
|
||||
if global_count & ALWAYS_ABORT_FLAG != 0 {
|
||||
// Do *not* access thread-local state, we might be after a `fork`.
|
||||
return Some(MustAbort::AlwaysAbort);
|
||||
}
|
||||
|
||||
@ -744,11 +745,14 @@ fn rust_panic_with_hook(
|
||||
if let Some(must_abort) = must_abort {
|
||||
match must_abort {
|
||||
panic_count::MustAbort::PanicInHook => {
|
||||
// Don't try to print the message in this case
|
||||
// - perhaps that is causing the recursive panics.
|
||||
// Don't try to format the message in this case, perhaps that is causing the
|
||||
// recursive panics. However if the message is just a string, no user-defined
|
||||
// code is involved in printing it, so that is risk-free.
|
||||
let msg_str = message.and_then(|m| m.as_str()).map(|m| [m]);
|
||||
let message = msg_str.as_ref().map(|m| fmt::Arguments::new_const(m));
|
||||
let panicinfo = PanicInfo::internal_constructor(
|
||||
None, // no message
|
||||
location, // but we want to show the location!
|
||||
message.as_ref(),
|
||||
location,
|
||||
can_unwind,
|
||||
force_no_backtrace,
|
||||
);
|
||||
@ -756,7 +760,7 @@ fn rust_panic_with_hook(
|
||||
}
|
||||
panic_count::MustAbort::AlwaysAbort => {
|
||||
// Unfortunately, this does not print a backtrace, because creating
|
||||
// a `Backtrace` will allocate, which we must to avoid here.
|
||||
// a `Backtrace` will allocate, which we must avoid here.
|
||||
let panicinfo = PanicInfo::internal_constructor(
|
||||
message,
|
||||
location,
|
||||
|
@ -10,14 +10,16 @@
|
||||
//! - More information about protocols can be found [here](https://edk2-docs.gitbook.io/edk-ii-uefi-driver-writer-s-guide/3_foundation/36_protocols_and_handles)
|
||||
|
||||
use r_efi::efi::{self, Guid};
|
||||
use r_efi::protocols::{device_path, device_path_to_text};
|
||||
|
||||
use crate::ffi::OsString;
|
||||
use crate::io::{self, const_io_error};
|
||||
use crate::mem::{size_of, MaybeUninit};
|
||||
use crate::os::uefi;
|
||||
use crate::os::uefi::{self, env::boot_services, ffi::OsStringExt};
|
||||
use crate::ptr::NonNull;
|
||||
use crate::{
|
||||
io::{self, const_io_error},
|
||||
os::uefi::env::boot_services,
|
||||
};
|
||||
use crate::slice;
|
||||
use crate::sync::atomic::{AtomicPtr, Ordering};
|
||||
use crate::sys_common::wstr::WStrUnits;
|
||||
|
||||
const BOOT_SERVICES_UNAVAILABLE: io::Error =
|
||||
const_io_error!(io::ErrorKind::Other, "Boot Services are no longer available");
|
||||
@ -142,9 +144,74 @@ pub(crate) unsafe fn close_event(evt: NonNull<crate::ffi::c_void>) -> io::Result
|
||||
|
||||
/// Get the Protocol for current system handle.
|
||||
/// Note: Some protocols need to be manually freed. It is the callers responsibility to do so.
|
||||
pub(crate) fn image_handle_protocol<T>(protocol_guid: Guid) -> Option<NonNull<T>> {
|
||||
let system_handle = uefi::env::try_image_handle()?;
|
||||
open_protocol(system_handle, protocol_guid).ok()
|
||||
pub(crate) fn image_handle_protocol<T>(protocol_guid: Guid) -> io::Result<NonNull<T>> {
|
||||
let system_handle = uefi::env::try_image_handle().ok_or(io::const_io_error!(
|
||||
io::ErrorKind::NotFound,
|
||||
"Protocol not found in Image handle"
|
||||
))?;
|
||||
open_protocol(system_handle, protocol_guid)
|
||||
}
|
||||
|
||||
pub(crate) fn device_path_to_text(path: NonNull<device_path::Protocol>) -> io::Result<OsString> {
|
||||
fn path_to_text(
|
||||
protocol: NonNull<device_path_to_text::Protocol>,
|
||||
path: NonNull<device_path::Protocol>,
|
||||
) -> io::Result<OsString> {
|
||||
let path_ptr: *mut r_efi::efi::Char16 = unsafe {
|
||||
((*protocol.as_ptr()).convert_device_path_to_text)(
|
||||
path.as_ptr(),
|
||||
// DisplayOnly
|
||||
r_efi::efi::Boolean::FALSE,
|
||||
// AllowShortcuts
|
||||
r_efi::efi::Boolean::FALSE,
|
||||
)
|
||||
};
|
||||
|
||||
// SAFETY: `convert_device_path_to_text` returns a pointer to a null-terminated UTF-16
|
||||
// string, and that string cannot be deallocated prior to dropping the `WStrUnits`, so
|
||||
// it's safe for `WStrUnits` to use.
|
||||
let path_len = unsafe {
|
||||
WStrUnits::new(path_ptr)
|
||||
.ok_or(io::const_io_error!(io::ErrorKind::InvalidData, "Invalid path"))?
|
||||
.count()
|
||||
};
|
||||
|
||||
let path = OsString::from_wide(unsafe { slice::from_raw_parts(path_ptr.cast(), path_len) });
|
||||
|
||||
if let Some(boot_services) = crate::os::uefi::env::boot_services() {
|
||||
let boot_services: NonNull<r_efi::efi::BootServices> = boot_services.cast();
|
||||
unsafe {
|
||||
((*boot_services.as_ptr()).free_pool)(path_ptr.cast());
|
||||
}
|
||||
}
|
||||
|
||||
Ok(path)
|
||||
}
|
||||
|
||||
static LAST_VALID_HANDLE: AtomicPtr<crate::ffi::c_void> =
|
||||
AtomicPtr::new(crate::ptr::null_mut());
|
||||
|
||||
if let Some(handle) = NonNull::new(LAST_VALID_HANDLE.load(Ordering::Acquire)) {
|
||||
if let Ok(protocol) = open_protocol::<device_path_to_text::Protocol>(
|
||||
handle,
|
||||
device_path_to_text::PROTOCOL_GUID,
|
||||
) {
|
||||
return path_to_text(protocol, path);
|
||||
}
|
||||
}
|
||||
|
||||
let device_path_to_text_handles = locate_handles(device_path_to_text::PROTOCOL_GUID)?;
|
||||
for handle in device_path_to_text_handles {
|
||||
if let Ok(protocol) = open_protocol::<device_path_to_text::Protocol>(
|
||||
handle,
|
||||
device_path_to_text::PROTOCOL_GUID,
|
||||
) {
|
||||
LAST_VALID_HANDLE.store(handle.as_ptr(), Ordering::Release);
|
||||
return path_to_text(protocol, path);
|
||||
}
|
||||
}
|
||||
|
||||
Err(io::const_io_error!(io::ErrorKind::NotFound, "No device path to text protocol found"))
|
||||
}
|
||||
|
||||
/// Get RuntimeServices
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::{unsupported, RawOsError};
|
||||
use super::{helpers, unsupported, RawOsError};
|
||||
use crate::error::Error as StdError;
|
||||
use crate::ffi::{OsStr, OsString};
|
||||
use crate::fmt;
|
||||
@ -7,6 +7,7 @@ use crate::marker::PhantomData;
|
||||
use crate::os::uefi;
|
||||
use crate::path::{self, PathBuf};
|
||||
use crate::ptr::NonNull;
|
||||
use r_efi::efi::protocols::{device_path, loaded_image_device_path};
|
||||
use r_efi::efi::Status;
|
||||
|
||||
pub fn errno() -> RawOsError {
|
||||
@ -164,7 +165,10 @@ impl fmt::Display for JoinPathsError {
|
||||
impl StdError for JoinPathsError {}
|
||||
|
||||
pub fn current_exe() -> io::Result<PathBuf> {
|
||||
unsupported()
|
||||
let protocol = helpers::image_handle_protocol::<device_path::Protocol>(
|
||||
loaded_image_device_path::PROTOCOL_GUID,
|
||||
)?;
|
||||
helpers::device_path_to_text(protocol).map(PathBuf::from)
|
||||
}
|
||||
|
||||
pub struct Env(!);
|
||||
|
@ -459,7 +459,7 @@ impl Socket {
|
||||
const AF_NAME_MAX: usize = 16;
|
||||
let mut buf = [0; AF_NAME_MAX];
|
||||
for (src, dst) in name.to_bytes().iter().zip(&mut buf[..AF_NAME_MAX - 1]) {
|
||||
*dst = *src as i8;
|
||||
*dst = *src as libc::c_char;
|
||||
}
|
||||
let mut arg: libc::accept_filter_arg = unsafe { mem::zeroed() };
|
||||
arg.af_name = buf;
|
||||
|
@ -355,8 +355,6 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> {
|
||||
target_os = "tvos",
|
||||
target_os = "linux",
|
||||
target_os = "macos",
|
||||
target_os = "solaris",
|
||||
target_os = "illumos",
|
||||
target_os = "aix",
|
||||
))] {
|
||||
#[allow(unused_assignments)]
|
||||
@ -483,6 +481,12 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> {
|
||||
.ok_or(io::const_io_error!(io::ErrorKind::NotFound, "The number of hardware threads is not known for the target platform"))
|
||||
}
|
||||
}
|
||||
} else if #[cfg(any(target_os = "solaris", target_os = "illumos"))] {
|
||||
let mut cpus = 0u32;
|
||||
if unsafe { libc::pset_info(libc::PS_MYID, core::ptr::null_mut(), &mut cpus, core::ptr::null_mut()) } != 0 {
|
||||
return Err(io::const_io_error!(io::ErrorKind::NotFound, "The number of hardware threads is not known for the target platform"));
|
||||
}
|
||||
Ok(unsafe { NonZero::new_unchecked(cpus as usize) })
|
||||
} else if #[cfg(target_os = "haiku")] {
|
||||
// system_info cpu_count field gets the static data set at boot time with `smp_set_num_cpus`
|
||||
// `get_system_info` calls then `smp_get_num_cpus`
|
||||
|
@ -4,6 +4,7 @@
|
||||
#![feature(staged_api)]
|
||||
#![feature(c_unwind)]
|
||||
#![feature(strict_provenance)]
|
||||
#![cfg_attr(target_arch = "wasm64", feature(simd_wasm64))]
|
||||
#![cfg_attr(not(target_env = "msvc"), feature(libc))]
|
||||
#![cfg_attr(
|
||||
all(target_family = "wasm", not(target_os = "emscripten")),
|
||||
|
@ -59,7 +59,10 @@ pub unsafe fn _Unwind_RaiseException(exception: *mut _Unwind_Exception) -> _Unwi
|
||||
wasm_throw(0, exception.cast())
|
||||
} else {
|
||||
let _ = exception;
|
||||
core::arch::wasm32::unreachable()
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
core::arch::wasm32::unreachable();
|
||||
#[cfg(target_arch = "wasm64")]
|
||||
core::arch::wasm64::unreachable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1289,9 +1289,9 @@ macro_rules! test_definitions {
|
||||
/// Adapted from [`test_definitions`].
|
||||
macro_rules! coverage_test_alias {
|
||||
($name:ident {
|
||||
alias_and_mode: $alias_and_mode:expr,
|
||||
default: $default:expr,
|
||||
only_hosts: $only_hosts:expr $(,)?
|
||||
alias_and_mode: $alias_and_mode:expr, // &'static str
|
||||
default: $default:expr, // bool
|
||||
only_hosts: $only_hosts:expr $(,)? // bool
|
||||
}) => {
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct $name {
|
||||
@ -1309,6 +1309,8 @@ macro_rules! coverage_test_alias {
|
||||
const ONLY_HOSTS: bool = $only_hosts;
|
||||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
// Register the mode name as a command-line alias.
|
||||
// This allows `x test coverage-map` and `x test coverage-run`.
|
||||
run.alias($alias_and_mode)
|
||||
}
|
||||
|
||||
@ -1319,8 +1321,7 @@ macro_rules! coverage_test_alias {
|
||||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
Coverage { compiler: self.compiler, target: self.target }
|
||||
.run_unified_suite(builder, Self::MODE)
|
||||
Coverage::run_coverage_tests(builder, self.compiler, self.target, Self::MODE);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -1449,11 +1450,20 @@ host_test!(RunMakeFullDeps {
|
||||
|
||||
default_test!(Assembly { path: "tests/assembly", mode: "assembly", suite: "assembly" });
|
||||
|
||||
/// Custom test step that is responsible for running the coverage tests
|
||||
/// in multiple different modes.
|
||||
/// Coverage tests are a bit more complicated than other test suites, because
|
||||
/// we want to run the same set of test files in multiple different modes,
|
||||
/// in a way that's convenient and flexible when invoked manually.
|
||||
///
|
||||
/// Each individual mode also has its own alias that will run the tests in
|
||||
/// just that mode.
|
||||
/// This combined step runs the specified tests (or all of `tests/coverage`)
|
||||
/// in both "coverage-map" and "coverage-run" modes.
|
||||
///
|
||||
/// Used by:
|
||||
/// - `x test coverage`
|
||||
/// - `x test tests/coverage`
|
||||
/// - `x test tests/coverage/trivial.rs` (etc)
|
||||
///
|
||||
/// (Each individual mode also has its own step that will run the tests in
|
||||
/// just that mode.)
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Coverage {
|
||||
pub compiler: Compiler,
|
||||
@ -1464,24 +1474,41 @@ impl Coverage {
|
||||
const PATH: &'static str = "tests/coverage";
|
||||
const SUITE: &'static str = "coverage";
|
||||
|
||||
fn run_unified_suite(&self, builder: &Builder<'_>, mode: &'static str) {
|
||||
/// Runs the coverage test suite (or a user-specified subset) in one mode.
|
||||
///
|
||||
/// This same function is used by the multi-mode step ([`Coverage`]) and by
|
||||
/// the single-mode steps ([`CoverageMap`] and [`CoverageRun`]), to help
|
||||
/// ensure that they all behave consistently with each other, regardless of
|
||||
/// how the coverage tests have been invoked.
|
||||
fn run_coverage_tests(
|
||||
builder: &Builder<'_>,
|
||||
compiler: Compiler,
|
||||
target: TargetSelection,
|
||||
mode: &'static str,
|
||||
) {
|
||||
// Like many other test steps, we delegate to a `Compiletest` step to
|
||||
// actually run the tests. (See `test_definitions!`.)
|
||||
builder.ensure(Compiletest {
|
||||
compiler: self.compiler,
|
||||
target: self.target,
|
||||
compiler,
|
||||
target,
|
||||
mode,
|
||||
suite: Self::SUITE,
|
||||
path: Self::PATH,
|
||||
compare_mode: None,
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl Step for Coverage {
|
||||
type Output = ();
|
||||
// We rely on the individual CoverageMap/CoverageRun steps to run themselves.
|
||||
const DEFAULT: bool = false;
|
||||
// When manually invoked, try to run as much as possible.
|
||||
// Compiletest will automatically skip the "coverage-run" tests if necessary.
|
||||
const ONLY_HOSTS: bool = false;
|
||||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
// Take responsibility for command-line paths within `tests/coverage`.
|
||||
run.suite_path(Self::PATH)
|
||||
}
|
||||
|
||||
@ -1492,20 +1519,26 @@ impl Step for Coverage {
|
||||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
self.run_unified_suite(builder, CoverageMap::MODE);
|
||||
self.run_unified_suite(builder, CoverageRun::MODE);
|
||||
// Run the specified coverage tests (possibly all of them) in both modes.
|
||||
Self::run_coverage_tests(builder, self.compiler, self.target, CoverageMap::MODE);
|
||||
Self::run_coverage_tests(builder, self.compiler, self.target, CoverageRun::MODE);
|
||||
}
|
||||
}
|
||||
|
||||
// Aliases for running the coverage tests in only one mode.
|
||||
// Runs `tests/coverage` in "coverage-map" mode only.
|
||||
// Used by `x test` and `x test coverage-map`.
|
||||
coverage_test_alias!(CoverageMap {
|
||||
alias_and_mode: "coverage-map",
|
||||
default: true,
|
||||
only_hosts: false,
|
||||
});
|
||||
// Runs `tests/coverage` in "coverage-run" mode only.
|
||||
// Used by `x test` and `x test coverage-run`.
|
||||
coverage_test_alias!(CoverageRun {
|
||||
alias_and_mode: "coverage-run",
|
||||
default: true,
|
||||
// Compiletest knows how to automatically skip these tests when cross-compiling,
|
||||
// but skipping the whole step here makes it clearer that they haven't run at all.
|
||||
only_hosts: true,
|
||||
});
|
||||
|
||||
|
@ -1,5 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
GIT_REPO="https://github.com/rust-lang/gcc"
|
||||
|
||||
# This commit hash needs to be updated to use a more recent gcc fork version.
|
||||
GIT_COMMIT="78dc50f0e50e6cd1433149520bd512a4e0eaa1bc"
|
||||
|
||||
set -ex
|
||||
|
||||
cd $1
|
||||
@ -7,13 +12,11 @@ cd $1
|
||||
source shared.sh
|
||||
|
||||
# Setting up folders for GCC
|
||||
git clone https://github.com/antoyo/gcc gcc-src
|
||||
cd gcc-src
|
||||
# This commit hash needs to be updated to use a more recent gcc fork version.
|
||||
git checkout 78dc50f0e50e6cd1433149520bd512a4e0eaa1bc
|
||||
curl -L "$GIT_REPO/archive/$GIT_COMMIT.tar.gz" |
|
||||
tar -xz --transform "s/gcc-$GIT_COMMIT/gcc-src/"
|
||||
|
||||
mkdir ../gcc-build ../gcc-install
|
||||
cd ../gcc-build
|
||||
mkdir gcc-build gcc-install
|
||||
pushd gcc-build
|
||||
|
||||
# Building GCC.
|
||||
hide_output \
|
||||
@ -28,6 +31,7 @@ hide_output \
|
||||
hide_output make -j$(nproc)
|
||||
hide_output make install
|
||||
|
||||
rm -rf ../gcc-src
|
||||
popd
|
||||
rm -rf gcc-src gcc-build
|
||||
ln -s /scripts/gcc-install/lib/libgccjit.so /usr/lib/x86_64-linux-gnu/libgccjit.so
|
||||
ln -s /scripts/gcc-install/lib/libgccjit.so /usr/lib/x86_64-linux-gnu/libgccjit.so.0
|
||||
|
@ -261,7 +261,7 @@ x--expand-yaml-anchors--remove:
|
||||
<<: *step
|
||||
|
||||
- name: upload artifacts to github
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
# name is set in previous step
|
||||
name: ${{ env.DOC_ARTIFACT_NAME }}
|
||||
|
@ -67,9 +67,6 @@ pub(crate) fn generate_args_file(file_path: &Path, options: &RustdocOptions) ->
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(sysroot) = &options.maybe_sysroot {
|
||||
content.push(format!("--sysroot={}", sysroot.display()));
|
||||
}
|
||||
for lib_str in &options.lib_strs {
|
||||
content.push(format!("-L{lib_str}"));
|
||||
}
|
||||
@ -411,6 +408,10 @@ fn run_test(
|
||||
|
||||
compiler.arg(&format!("@{}", rustdoc_options.arg_file.display()));
|
||||
|
||||
if let Some(sysroot) = &rustdoc_options.maybe_sysroot {
|
||||
compiler.arg(format!("--sysroot={}", sysroot.display()));
|
||||
}
|
||||
|
||||
compiler.arg("--edition").arg(&edition.to_string());
|
||||
compiler.env("UNSTABLE_RUSTDOC_TEST_PATH", path);
|
||||
compiler.env("UNSTABLE_RUSTDOC_TEST_LINE", format!("{}", line as isize - line_offset as isize));
|
||||
@ -950,6 +951,7 @@ pub(crate) struct IndividualTestOptions {
|
||||
runtool_args: Vec<String>,
|
||||
target: TargetTriple,
|
||||
test_id: String,
|
||||
maybe_sysroot: Option<PathBuf>,
|
||||
}
|
||||
|
||||
impl IndividualTestOptions {
|
||||
@ -982,6 +984,7 @@ impl IndividualTestOptions {
|
||||
runtool_args: options.runtool_args.clone(),
|
||||
target: options.target.clone(),
|
||||
test_id,
|
||||
maybe_sysroot: options.maybe_sysroot.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -609,6 +609,8 @@ fn common_inputs_stamp(config: &Config) -> Stamp {
|
||||
stamp.add_path(&rust_src_dir.join("src/etc/htmldocck.py"));
|
||||
}
|
||||
|
||||
stamp.add_dir(&rust_src_dir.join("src/tools/run-make-support"));
|
||||
|
||||
// Compiletest itself.
|
||||
stamp.add_dir(&rust_src_dir.join("src/tools/compiletest/"));
|
||||
|
||||
|
@ -457,7 +457,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
let bitmask_len = u32::try_from(bitmask_len).unwrap();
|
||||
|
||||
// To read the mask, we transmute it to an integer.
|
||||
// That does the right thing wrt endianess.
|
||||
// That does the right thing wrt endianness.
|
||||
let mask_ty = this.machine.layouts.uint(mask.layout.size).unwrap();
|
||||
let mask = mask.transmute(mask_ty, this)?;
|
||||
let mask: u64 = this.read_scalar(&mask)?.to_bits(mask_ty.size)?.try_into().unwrap();
|
||||
@ -509,7 +509,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
||||
}
|
||||
}
|
||||
// We have to change the type of the place to be able to write `res` into it. This
|
||||
// transmutes the integer to an array, which does the right thing wrt endianess.
|
||||
// transmutes the integer to an array, which does the right thing wrt endianness.
|
||||
let dest =
|
||||
dest.transmute(this.machine.layouts.uint(dest.layout.size).unwrap(), this)?;
|
||||
this.write_int(res, &dest)?;
|
||||
|
@ -38,7 +38,7 @@ impl FileDescriptor for Event {
|
||||
}
|
||||
|
||||
/// A write call adds the 8-byte integer value supplied in
|
||||
/// its buffer (in native endianess) to the counter. The maximum value that may be
|
||||
/// its buffer (in native endianness) to the counter. The maximum value that may be
|
||||
/// stored in the counter is the largest unsigned 64-bit value
|
||||
/// minus 1 (i.e., 0xfffffffffffffffe). If the addition would
|
||||
/// cause the counter's value to exceed the maximum, then the
|
||||
@ -57,7 +57,7 @@ impl FileDescriptor for Event {
|
||||
) -> InterpResult<'tcx, io::Result<usize>> {
|
||||
let v1 = self.val.get();
|
||||
let bytes: [u8; 8] = bytes.try_into().unwrap(); // FIXME fail gracefully when this has the wrong size
|
||||
// Convert from target endianess to host endianess.
|
||||
// Convert from target endianness to host endianness.
|
||||
let num = match tcx.sess.target.endian {
|
||||
Endian::Little => u64::from_le_bytes(bytes),
|
||||
Endian::Big => u64::from_be_bytes(bytes),
|
||||
|
@ -121,6 +121,7 @@ fn default_dcx(
|
||||
fallback_bundle,
|
||||
fatal_dcx: DiagCtxt::new(emitter),
|
||||
fatal_note: None,
|
||||
emit_fatal_diagnostic: false,
|
||||
})
|
||||
} else {
|
||||
emitter
|
||||
@ -209,7 +210,7 @@ impl ParseSess {
|
||||
rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(),
|
||||
false,
|
||||
);
|
||||
self.raw_psess.dcx.make_silent(fallback_bundle, None);
|
||||
self.raw_psess.dcx.make_silent(fallback_bundle, None, false);
|
||||
}
|
||||
|
||||
pub(crate) fn span_to_filename(&self, span: Span) -> FileName {
|
||||
|
@ -34,6 +34,12 @@ pub struct Bar(i32);
|
||||
#[repr(transparent)]
|
||||
pub struct Type3<T>(T);
|
||||
|
||||
// repr(transparent) wrapper which engages in self-reference
|
||||
#[repr(transparent)]
|
||||
pub struct Type4(Type4Helper<Type4>);
|
||||
#[repr(transparent)]
|
||||
pub struct Type4Helper<T>(*mut T);
|
||||
|
||||
pub fn foo1(_: Type1) { }
|
||||
// CHECK: define{{.*}}4foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
|
||||
pub fn foo2(_: Type1, _: Type1) { }
|
||||
@ -52,6 +58,13 @@ pub fn foo8(_: Type3<Bar>, _: Type3<Bar>) { }
|
||||
// CHECK: define{{.*}}4foo8{{.*}}!type ![[TYPE8:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
|
||||
pub fn foo9(_: Type3<Bar>, _: Type3<Bar>, _: Type3<Bar>) { }
|
||||
// CHECK: define{{.*}}4foo9{{.*}}!type ![[TYPE9:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
|
||||
pub fn foo10(_: Type4) { }
|
||||
// CHECK: define{{.*}}5foo10{{.*}}!type ![[TYPE10:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
|
||||
pub fn foo11(_: Type4, _: Type4) { }
|
||||
// CHECK: define{{.*}}5foo11{{.*}}!type ![[TYPE11:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
|
||||
pub fn foo12(_: Type4, _: Type4, _: Type4) { }
|
||||
// CHECK: define{{.*}}5foo12{{.*}}!type ![[TYPE12:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
|
||||
|
||||
|
||||
// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}3FooE"}
|
||||
// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}3FooS_E"}
|
||||
@ -62,3 +75,6 @@ pub fn foo9(_: Type3<Bar>, _: Type3<Bar>, _: Type3<Bar>) { }
|
||||
// CHECK: ![[TYPE7]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}3BarE"}
|
||||
// CHECK: ![[TYPE8]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}3BarS_E"}
|
||||
// CHECK: ![[TYPE9]] = !{i64 0, !"_ZTSFvu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}3BarS_S_E"}
|
||||
// CHECK: ![[TYPE10]] = !{i64 0, !"_ZTSFvPu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}5Type4E"}
|
||||
// CHECK: ![[TYPE11]] = !{i64 0, !"_ZTSFvPu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}5Type4S0_E"}
|
||||
// CHECK: ![[TYPE12]] = !{i64 0, !"_ZTSFvPu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}5Type4S0_S0_E"}
|
||||
|
@ -4,8 +4,8 @@ warning: formatting may not be suitable for sub-register argument
|
||||
LL | asm!("{}", in(reg) 0u8);
|
||||
| ^^ --- for this argument
|
||||
|
|
||||
= help: use `{0:w}` to have the register formatted as `w0`
|
||||
= help: or use `{0:x}` to keep the default formatting of `x0`
|
||||
= help: use `{0:w}` to have the register formatted as `w0` (for 32-bit values)
|
||||
= help: or use `{0:x}` to keep the default formatting of `x0` (for 64-bit values)
|
||||
= note: `#[warn(asm_sub_register)]` on by default
|
||||
|
||||
warning: formatting may not be suitable for sub-register argument
|
||||
@ -14,8 +14,8 @@ warning: formatting may not be suitable for sub-register argument
|
||||
LL | asm!("{}", in(reg) 0u16);
|
||||
| ^^ ---- for this argument
|
||||
|
|
||||
= help: use `{0:w}` to have the register formatted as `w0`
|
||||
= help: or use `{0:x}` to keep the default formatting of `x0`
|
||||
= help: use `{0:w}` to have the register formatted as `w0` (for 32-bit values)
|
||||
= help: or use `{0:x}` to keep the default formatting of `x0` (for 64-bit values)
|
||||
|
||||
warning: formatting may not be suitable for sub-register argument
|
||||
--> $DIR/type-check-3.rs:52:15
|
||||
@ -23,8 +23,8 @@ warning: formatting may not be suitable for sub-register argument
|
||||
LL | asm!("{}", in(reg) 0i32);
|
||||
| ^^ ---- for this argument
|
||||
|
|
||||
= help: use `{0:w}` to have the register formatted as `w0`
|
||||
= help: or use `{0:x}` to keep the default formatting of `x0`
|
||||
= help: use `{0:w}` to have the register formatted as `w0` (for 32-bit values)
|
||||
= help: or use `{0:x}` to keep the default formatting of `x0` (for 64-bit values)
|
||||
|
||||
warning: formatting may not be suitable for sub-register argument
|
||||
--> $DIR/type-check-3.rs:54:15
|
||||
@ -32,8 +32,8 @@ warning: formatting may not be suitable for sub-register argument
|
||||
LL | asm!("{}", in(reg) 0f32);
|
||||
| ^^ ---- for this argument
|
||||
|
|
||||
= help: use `{0:w}` to have the register formatted as `w0`
|
||||
= help: or use `{0:x}` to keep the default formatting of `x0`
|
||||
= help: use `{0:w}` to have the register formatted as `w0` (for 32-bit values)
|
||||
= help: or use `{0:x}` to keep the default formatting of `x0` (for 64-bit values)
|
||||
|
||||
warning: formatting may not be suitable for sub-register argument
|
||||
--> $DIR/type-check-3.rs:57:15
|
||||
@ -41,8 +41,8 @@ warning: formatting may not be suitable for sub-register argument
|
||||
LL | asm!("{}", in(vreg) 0i16);
|
||||
| ^^ ---- for this argument
|
||||
|
|
||||
= help: use `{0:h}` to have the register formatted as `h0`
|
||||
= help: or use `{0:v}` to keep the default formatting of `v0`
|
||||
= help: use `{0:h}` to have the register formatted as `h0` (for 16-bit values)
|
||||
= help: or use `{0:v}` to keep the default formatting of `v0` (for 128-bit values)
|
||||
|
||||
warning: formatting may not be suitable for sub-register argument
|
||||
--> $DIR/type-check-3.rs:59:15
|
||||
@ -50,8 +50,8 @@ warning: formatting may not be suitable for sub-register argument
|
||||
LL | asm!("{}", in(vreg) 0f32);
|
||||
| ^^ ---- for this argument
|
||||
|
|
||||
= help: use `{0:s}` to have the register formatted as `s0`
|
||||
= help: or use `{0:v}` to keep the default formatting of `v0`
|
||||
= help: use `{0:s}` to have the register formatted as `s0` (for 32-bit values)
|
||||
= help: or use `{0:v}` to keep the default formatting of `v0` (for 128-bit values)
|
||||
|
||||
warning: formatting may not be suitable for sub-register argument
|
||||
--> $DIR/type-check-3.rs:61:15
|
||||
@ -59,8 +59,8 @@ warning: formatting may not be suitable for sub-register argument
|
||||
LL | asm!("{}", in(vreg) 0f64);
|
||||
| ^^ ---- for this argument
|
||||
|
|
||||
= help: use `{0:d}` to have the register formatted as `d0`
|
||||
= help: or use `{0:v}` to keep the default formatting of `v0`
|
||||
= help: use `{0:d}` to have the register formatted as `d0` (for 64-bit values)
|
||||
= help: or use `{0:v}` to keep the default formatting of `v0` (for 128-bit values)
|
||||
|
||||
warning: formatting may not be suitable for sub-register argument
|
||||
--> $DIR/type-check-3.rs:63:15
|
||||
@ -68,8 +68,8 @@ warning: formatting may not be suitable for sub-register argument
|
||||
LL | asm!("{}", in(vreg_low16) 0f64);
|
||||
| ^^ ---- for this argument
|
||||
|
|
||||
= help: use `{0:d}` to have the register formatted as `d0`
|
||||
= help: or use `{0:v}` to keep the default formatting of `v0`
|
||||
= help: use `{0:d}` to have the register formatted as `d0` (for 64-bit values)
|
||||
= help: or use `{0:v}` to keep the default formatting of `v0` (for 128-bit values)
|
||||
|
||||
warning: formatting may not be suitable for sub-register argument
|
||||
--> $DIR/type-check-3.rs:66:15
|
||||
@ -77,8 +77,8 @@ warning: formatting may not be suitable for sub-register argument
|
||||
LL | asm!("{0} {0}", in(reg) 0i16);
|
||||
| ^^^ ^^^ ---- for this argument
|
||||
|
|
||||
= help: use `{0:w}` to have the register formatted as `w0`
|
||||
= help: or use `{0:x}` to keep the default formatting of `x0`
|
||||
= help: use `{0:w}` to have the register formatted as `w0` (for 32-bit values)
|
||||
= help: or use `{0:x}` to keep the default formatting of `x0` (for 64-bit values)
|
||||
|
||||
warning: formatting may not be suitable for sub-register argument
|
||||
--> $DIR/type-check-3.rs:68:15
|
||||
@ -86,8 +86,8 @@ warning: formatting may not be suitable for sub-register argument
|
||||
LL | asm!("{0} {0:x}", in(reg) 0i16);
|
||||
| ^^^ ---- for this argument
|
||||
|
|
||||
= help: use `{0:w}` to have the register formatted as `w0`
|
||||
= help: or use `{0:x}` to keep the default formatting of `x0`
|
||||
= help: use `{0:w}` to have the register formatted as `w0` (for 32-bit values)
|
||||
= help: or use `{0:x}` to keep the default formatting of `x0` (for 64-bit values)
|
||||
|
||||
error: type `i128` cannot be used with this register class
|
||||
--> $DIR/type-check-3.rs:73:28
|
||||
|
@ -194,8 +194,8 @@ warning: formatting may not be suitable for sub-register argument
|
||||
LL | asm!("{:foo}", in(reg) foo);
|
||||
| ^^^^^^ --- for this argument
|
||||
|
|
||||
= help: use `{0:w}` to have the register formatted as `w0`
|
||||
= help: or use `{0:x}` to keep the default formatting of `x0`
|
||||
= help: use `{0:w}` to have the register formatted as `w0` (for 32-bit values)
|
||||
= help: or use `{0:x}` to keep the default formatting of `x0` (for 64-bit values)
|
||||
= note: `#[warn(asm_sub_register)]` on by default
|
||||
|
||||
error: aborting due to 21 previous errors; 1 warning emitted
|
||||
|
@ -194,8 +194,8 @@ warning: formatting may not be suitable for sub-register argument
|
||||
LL | asm!("{:foo}", in(reg) foo);
|
||||
| ^^^^^^ --- for this argument
|
||||
|
|
||||
= help: use `{0:e}` to have the register formatted as `eax`
|
||||
= help: or use `{0:r}` to keep the default formatting of `rax`
|
||||
= help: use `{0:e}` to have the register formatted as `eax` (for 32-bit values)
|
||||
= help: or use `{0:r}` to keep the default formatting of `rax` (for 64-bit values)
|
||||
= note: `#[warn(asm_sub_register)]` on by default
|
||||
|
||||
error: aborting due to 21 previous errors; 1 warning emitted
|
||||
|
@ -44,8 +44,8 @@ warning: formatting may not be suitable for sub-register argument
|
||||
LL | asm!("{0} {0}", in(reg) 0i16);
|
||||
| ^^^ ^^^ ---- for this argument
|
||||
|
|
||||
= help: use `{0:x}` to have the register formatted as `ax`
|
||||
= help: or use `{0:r}` to keep the default formatting of `rax`
|
||||
= help: use `{0:x}` to have the register formatted as `ax` (for 16-bit values)
|
||||
= help: or use `{0:r}` to keep the default formatting of `rax` (for 64-bit values)
|
||||
= note: `#[warn(asm_sub_register)]` on by default
|
||||
|
||||
warning: formatting may not be suitable for sub-register argument
|
||||
@ -54,8 +54,8 @@ warning: formatting may not be suitable for sub-register argument
|
||||
LL | asm!("{0} {0:x}", in(reg) 0i16);
|
||||
| ^^^ ---- for this argument
|
||||
|
|
||||
= help: use `{0:x}` to have the register formatted as `ax`
|
||||
= help: or use `{0:r}` to keep the default formatting of `rax`
|
||||
= help: use `{0:x}` to have the register formatted as `ax` (for 16-bit values)
|
||||
= help: or use `{0:r}` to keep the default formatting of `rax` (for 64-bit values)
|
||||
|
||||
warning: formatting may not be suitable for sub-register argument
|
||||
--> $DIR/type-check-3.rs:38:15
|
||||
@ -63,8 +63,8 @@ warning: formatting may not be suitable for sub-register argument
|
||||
LL | asm!("{}", in(reg) 0i32);
|
||||
| ^^ ---- for this argument
|
||||
|
|
||||
= help: use `{0:e}` to have the register formatted as `eax`
|
||||
= help: or use `{0:r}` to keep the default formatting of `rax`
|
||||
= help: use `{0:e}` to have the register formatted as `eax` (for 32-bit values)
|
||||
= help: or use `{0:r}` to keep the default formatting of `rax` (for 64-bit values)
|
||||
|
||||
warning: formatting may not be suitable for sub-register argument
|
||||
--> $DIR/type-check-3.rs:41:15
|
||||
@ -72,8 +72,8 @@ warning: formatting may not be suitable for sub-register argument
|
||||
LL | asm!("{}", in(ymm_reg) 0i64);
|
||||
| ^^ ---- for this argument
|
||||
|
|
||||
= help: use `{0:x}` to have the register formatted as `xmm0`
|
||||
= help: or use `{0:y}` to keep the default formatting of `ymm0`
|
||||
= help: use `{0:x}` to have the register formatted as `xmm0` (for 128-bit values)
|
||||
= help: or use `{0:y}` to keep the default formatting of `ymm0` (for 256-bit values)
|
||||
|
||||
error: type `i8` cannot be used with this register class
|
||||
--> $DIR/type-check-3.rs:52:28
|
||||
|
@ -0,0 +1,7 @@
|
||||
pub trait Bar: Super<SuperAssoc: Bound> {}
|
||||
|
||||
pub trait Super {
|
||||
type SuperAssoc;
|
||||
}
|
||||
|
||||
pub trait Bound {}
|
9
tests/ui/associated-type-bounds/implied-predicates.rs
Normal file
9
tests/ui/associated-type-bounds/implied-predicates.rs
Normal file
@ -0,0 +1,9 @@
|
||||
//@ aux-build:implied-predicates.rs
|
||||
//@ check-pass
|
||||
|
||||
extern crate implied_predicates;
|
||||
use implied_predicates::Bar;
|
||||
|
||||
fn bar<B: Bar>() {}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,42 @@
|
||||
// ICE #90691 Encountered error `Unimplemented` selecting ...
|
||||
//@ build-pass
|
||||
// issue: rust-lang/rust#90691
|
||||
|
||||
trait TError: std::fmt::Debug {}
|
||||
impl TError for () {}
|
||||
|
||||
trait SuperTrait {
|
||||
type Error;
|
||||
}
|
||||
|
||||
trait Trait: SuperTrait<Error: TError> {}
|
||||
|
||||
impl<T> Trait for T
|
||||
where
|
||||
T: SuperTrait,
|
||||
<T as SuperTrait>::Error: TError,
|
||||
{
|
||||
}
|
||||
|
||||
struct SomeTrait<S>(S);
|
||||
struct BoxedTrait(Box<dyn Trait<Error = ()>>);
|
||||
|
||||
impl<S: 'static> From<SomeTrait<S>> for BoxedTrait {
|
||||
fn from(other: SomeTrait<S>) -> Self {
|
||||
Self(Box::new(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> SuperTrait for SomeTrait<S> {
|
||||
type Error = ();
|
||||
}
|
||||
|
||||
impl From<()> for BoxedTrait {
|
||||
fn from(c: ()) -> Self {
|
||||
Self::from(SomeTrait(c))
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _: BoxedTrait = ().into();
|
||||
}
|
@ -1,3 +1,23 @@
|
||||
error[E0793]: reference to packed field is unaligned
|
||||
--> $DIR/issue-53114-safety-checks.rs:23:13
|
||||
|
|
||||
LL | let _ = &p.b;
|
||||
| ^^^^
|
||||
|
|
||||
= note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
|
||||
= note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
|
||||
|
||||
error[E0793]: reference to packed field is unaligned
|
||||
--> $DIR/issue-53114-safety-checks.rs:28:17
|
||||
|
|
||||
LL | let (_,) = (&p.b,);
|
||||
| ^^^^
|
||||
|
|
||||
= note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
|
||||
= note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
|
||||
|
||||
error[E0133]: access to union field is unsafe and requires unsafe function or block
|
||||
--> $DIR/issue-53114-safety-checks.rs:24:13
|
||||
|
|
||||
@ -31,20 +51,20 @@ LL | let (_,) = (&u2.a,);
|
||||
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
|
||||
|
||||
error[E0793]: reference to packed field is unaligned
|
||||
--> $DIR/issue-53114-safety-checks.rs:23:13
|
||||
--> $DIR/issue-53114-safety-checks.rs:37:16
|
||||
|
|
||||
LL | let _ = &p.b;
|
||||
| ^^^^
|
||||
LL | let _: _ = &p.b;
|
||||
| ^^^^
|
||||
|
|
||||
= note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
|
||||
= note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
|
||||
|
||||
error[E0793]: reference to packed field is unaligned
|
||||
--> $DIR/issue-53114-safety-checks.rs:28:17
|
||||
--> $DIR/issue-53114-safety-checks.rs:42:20
|
||||
|
|
||||
LL | let (_,) = (&p.b,);
|
||||
| ^^^^
|
||||
LL | let (_,): _ = (&p.b,);
|
||||
| ^^^^
|
||||
|
|
||||
= note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
|
||||
= note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||
@ -83,20 +103,20 @@ LL | let (_,): _ = (&u2.a,);
|
||||
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
|
||||
|
||||
error[E0793]: reference to packed field is unaligned
|
||||
--> $DIR/issue-53114-safety-checks.rs:37:16
|
||||
--> $DIR/issue-53114-safety-checks.rs:51:11
|
||||
|
|
||||
LL | let _: _ = &p.b;
|
||||
| ^^^^
|
||||
LL | match &p.b { _ => { } }
|
||||
| ^^^^
|
||||
|
|
||||
= note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
|
||||
= note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
|
||||
|
||||
error[E0793]: reference to packed field is unaligned
|
||||
--> $DIR/issue-53114-safety-checks.rs:42:20
|
||||
--> $DIR/issue-53114-safety-checks.rs:56:12
|
||||
|
|
||||
LL | let (_,): _ = (&p.b,);
|
||||
| ^^^^
|
||||
LL | match (&p.b,) { (_,) => { } }
|
||||
| ^^^^
|
||||
|
|
||||
= note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
|
||||
= note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||
@ -134,26 +154,6 @@ LL | match (&u2.a,) { (_,) => { } }
|
||||
|
|
||||
= note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
|
||||
|
||||
error[E0793]: reference to packed field is unaligned
|
||||
--> $DIR/issue-53114-safety-checks.rs:51:11
|
||||
|
|
||||
LL | match &p.b { _ => { } }
|
||||
| ^^^^
|
||||
|
|
||||
= note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
|
||||
= note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
|
||||
|
||||
error[E0793]: reference to packed field is unaligned
|
||||
--> $DIR/issue-53114-safety-checks.rs:56:12
|
||||
|
|
||||
LL | match (&p.b,) { (_,) => { } }
|
||||
| ^^^^
|
||||
|
|
||||
= note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
|
||||
= note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
|
||||
= help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
|
||||
|
||||
error: aborting due to 18 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0133, E0793.
|
||||
|
@ -4,7 +4,10 @@ error: unconstrained generic constant
|
||||
LL | pad: [u8; is_zst::<T>()],
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: try adding a `where` bound using this expression: `where [(); is_zst::<T>()]:`
|
||||
help: try adding a `where` bound
|
||||
|
|
||||
LL | pub struct AtLeastByte<T: ?Sized> where [(); is_zst::<T>()]: {
|
||||
| ++++++++++++++++++++++++++
|
||||
|
||||
error[E0277]: the size for values of type `T` cannot be known at compilation time
|
||||
--> $DIR/const-argument-if-length.rs:16:12
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user