Auto merge of #3414 - RalfJung:rustup, r=RalfJung

Rustup

Fixes https://github.com/rust-lang/miri/issues/3404
This commit is contained in:
bors 2024-03-25 16:34:41 +00:00
commit cf1eb93a02
170 changed files with 1784 additions and 748 deletions

View File

@ -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

View File

@ -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

View File

@ -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]]

View File

@ -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, '*');

View File

@ -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.

View File

@ -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) };

View File

@ -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)
}
}

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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);
}

View File

@ -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 {

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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)
};

View File

@ -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) {

View File

@ -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());

View File

@ -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;

View File

@ -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);
}

View File

@ -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
{

View File

@ -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());
}

View File

@ -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,
})
});
}

View File

@ -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)",
));
},
);

View File

@ -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];

View File

@ -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);

View File

@ -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) => {

View File

@ -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 }

View File

@ -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] <-

View File

@ -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>;
}

View File

@ -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"),

View File

@ -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
}

View File

@ -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) {
}

View File

@ -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

View File

@ -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);
}

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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(),
_ => (),
}

View File

@ -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);
}

View File

@ -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,
}
})

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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(...)`.

View File

@ -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)

View File

@ -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

View File

@ -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]

View File

@ -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
}

View File

@ -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)
}

View File

@ -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,
}
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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),

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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,

View File

@ -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(_) => {

View File

@ -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))

View File

@ -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)
}

View File

@ -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)

View File

@ -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>>>();

View File

@ -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.

View File

@ -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)]

View File

@ -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,

View File

@ -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

View File

@ -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(!);

View File

@ -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;

View File

@ -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`

View File

@ -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")),

View File

@ -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();
}
}
}

View File

@ -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,
});

View File

@ -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

View File

@ -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 }}

View File

@ -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(),
}
}
}

View File

@ -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/"));

View File

@ -1 +1 @@
9b8d12cf4c2311203aea83315552b15993bd4f81
cb7c63606e53715f94f3ba04d38e50772e4cd23d

View File

@ -276,7 +276,7 @@ fn run_compiler(
// If no `--sysroot` is given, the `MIRI_SYSROOT` env var is consulted to find where
// that sysroot lives, and that is passed to rustc.
let sysroot_flag = "--sysroot";
if !args.iter().any(|e| e == sysroot_flag) {
if !args.iter().any(|e| e.starts_with(sysroot_flag)) {
// Using the built-in default here would be plain wrong, so we *require*
// the env var to make sure things make sense.
let miri_sysroot = env::var("MIRI_SYSROOT").unwrap_or_else(|_| {

View File

@ -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)?;

View File

@ -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),

View File

@ -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 {

View File

@ -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"}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,7 @@
pub trait Bar: Super<SuperAssoc: Bound> {}
pub trait Super {
type SuperAssoc;
}
pub trait Bound {}

View 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() {}

View File

@ -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();
}

Some files were not shown because too many files have changed in this diff Show More