Auto merge of #99745 - JohnTitor:rollup-lvrie64, r=JohnTitor
Rollup of 7 pull requests Successful merges: - #98211 (Implement `fs::get_path` for FreeBSD.) - #99353 (Slightly improve mismatched GAT where clause error) - #99593 (Suggest removing the tuple struct field for the unwrapped value) - #99615 (Remove some explicit `self.infcx` for `FnCtxt`, which already derefs into `InferCtxt`) - #99711 (Remove reachable coverage without counters) - #99718 (Avoid `&str`/`Symbol` to `String` conversions) - #99720 (Sync rustc_codegen_cranelift) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
b629c85bd7
@ -850,13 +850,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
debug!("trait spans found: {:?}", traits);
|
||||
for span in &traits {
|
||||
let mut multi_span: MultiSpan = vec![*span].into();
|
||||
multi_span.push_span_label(
|
||||
*span,
|
||||
"this has an implicit `'static` lifetime requirement".to_string(),
|
||||
);
|
||||
multi_span
|
||||
.push_span_label(*span, "this has an implicit `'static` lifetime requirement");
|
||||
multi_span.push_span_label(
|
||||
ident.span,
|
||||
"calling this method introduces the `impl`'s 'static` requirement".to_string(),
|
||||
"calling this method introduces the `impl`'s 'static` requirement",
|
||||
);
|
||||
err.span_note(multi_span, "the used `impl` has a `'static` requirement");
|
||||
err.span_suggestion_verbose(
|
||||
|
@ -1,10 +1,9 @@
|
||||
{
|
||||
// source for rustc_* is not included in the rust-src component; disable the errors about this
|
||||
"rust-analyzer.diagnostics.disabled": ["unresolved-extern-crate", "unresolved-macro-call"],
|
||||
"rust-analyzer.assist.importGranularity": "module",
|
||||
"rust-analyzer.assist.importEnforceGranularity": true,
|
||||
"rust-analyzer.assist.importPrefix": "crate",
|
||||
"rust-analyzer.cargo.runBuildScripts": true,
|
||||
"rust-analyzer.imports.granularity.enforce": true,
|
||||
"rust-analyzer.imports.granularity.group": "module",
|
||||
"rust-analyzer.imports.prefix": "crate",
|
||||
"rust-analyzer.cargo.features": ["unstable-features"],
|
||||
"rust-analyzer.linkedProjects": [
|
||||
"./Cargo.toml",
|
||||
|
@ -2,6 +2,17 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.56"
|
||||
@ -25,6 +36,12 @@ version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
@ -33,56 +50,57 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-bforest"
|
||||
version = "0.83.0"
|
||||
version = "0.85.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed44413e7e2fe3260d0ed73e6956ab188b69c10ee92b892e401e0f4f6808c68b"
|
||||
checksum = "749d0d6022c9038dccf480bdde2a38d435937335bf2bb0f14e815d94517cdce8"
|
||||
dependencies = [
|
||||
"cranelift-entity",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-codegen"
|
||||
version = "0.83.0"
|
||||
version = "0.85.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b5d83f0f26bf213f971f45589d17e5b65e4861f9ed22392b0cbb6eaa5bd329c"
|
||||
checksum = "e94370cc7b37bf652ccd8bb8f09bd900997f7ccf97520edfc75554bb5c4abbea"
|
||||
dependencies = [
|
||||
"cranelift-bforest",
|
||||
"cranelift-codegen-meta",
|
||||
"cranelift-codegen-shared",
|
||||
"cranelift-entity",
|
||||
"cranelift-isle",
|
||||
"gimli",
|
||||
"log",
|
||||
"regalloc",
|
||||
"regalloc2",
|
||||
"smallvec",
|
||||
"target-lexicon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-codegen-meta"
|
||||
version = "0.83.0"
|
||||
version = "0.85.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6800dc386177df6ecc5a32680607ed8ba1fa0d31a2a59c8c61fbf44826b8191d"
|
||||
checksum = "e0a3cea8fdab90e44018c5b9a1dfd460d8ee265ac354337150222a354628bdb6"
|
||||
dependencies = [
|
||||
"cranelift-codegen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-codegen-shared"
|
||||
version = "0.83.0"
|
||||
version = "0.85.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c961f85070985ebc8fcdb81b838a5cf842294d1e6ed4852446161c7e246fd455"
|
||||
checksum = "5ac72f76f2698598951ab26d8c96eaa854810e693e7dd52523958b5909fde6b2"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-entity"
|
||||
version = "0.83.0"
|
||||
version = "0.85.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2347b2b8d1d5429213668f2a8e36c85ee3c73984a2f6a79007e365d3e575e7ed"
|
||||
checksum = "09eaeacfcd2356fe0e66b295e8f9d59fdd1ac3ace53ba50de14d628ec902f72d"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-frontend"
|
||||
version = "0.83.0"
|
||||
version = "0.85.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4cbcdbf7bed29e363568b778649b69dabc3d727256d5d25236096ef693757654"
|
||||
checksum = "dba69c9980d5ffd62c18a2bde927855fcd7c8dc92f29feaf8636052662cbd99c"
|
||||
dependencies = [
|
||||
"cranelift-codegen",
|
||||
"log",
|
||||
@ -91,10 +109,16 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-jit"
|
||||
version = "0.83.0"
|
||||
name = "cranelift-isle"
|
||||
version = "0.85.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c769d4e0d76f59c8b2a3bf0477d89ee149bb0731b53fbb245ee081d49063095"
|
||||
checksum = "d2920dc1e05cac40304456ed3301fde2c09bd6a9b0210bcfa2f101398d628d5b"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-jit"
|
||||
version = "0.85.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c3c5ed067f2c81577e431f3039148a9c187b33cc79e0d1731fede27d801ec56"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cranelift-codegen",
|
||||
@ -110,9 +134,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-module"
|
||||
version = "0.83.0"
|
||||
version = "0.85.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ab57d399a2401074bb0cc40b3031e420f3d66d46ec0cf21eeae53ac04bd73e2"
|
||||
checksum = "eee6784303bf9af235237a4885f7417e09a35df896d38ea969a0081064b3ede4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cranelift-codegen",
|
||||
@ -120,9 +144,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-native"
|
||||
version = "0.83.0"
|
||||
version = "0.85.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f4cdf93552e5ceb2e3c042829ebb4de4378492705f769eadc6a7c6c5251624c"
|
||||
checksum = "f04dfa45f9b2a6f587c564d6b63388e00cd6589d2df6ea2758cf79e1a13285e6"
|
||||
dependencies = [
|
||||
"cranelift-codegen",
|
||||
"libc",
|
||||
@ -131,9 +155,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-object"
|
||||
version = "0.83.0"
|
||||
version = "0.85.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf8e65f4839c26e6237fc0744911d79b0a2ac5e76b4e4eebd14db2b8d849fd31"
|
||||
checksum = "0bf38b2c505db749276793116c0cb30bd096206c7810e471677a453134881881"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cranelift-codegen",
|
||||
@ -152,6 +176,26 @@ dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fxhash"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.26.1"
|
||||
@ -161,6 +205,15 @@ dependencies = [
|
||||
"indexmap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
@ -174,14 +227,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
"hashbrown 0.12.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.119"
|
||||
version = "0.2.126"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4"
|
||||
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
@ -219,11 +272,12 @@ checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.27.1"
|
||||
version = "0.28.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67ac1d3f9a1d3616fd9a60c8d74296f22406a238b6a72f5cc1e6f314df4ffbf9"
|
||||
checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"hashbrown 0.11.2",
|
||||
"indexmap",
|
||||
"memchr",
|
||||
]
|
||||
@ -235,13 +289,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
|
||||
|
||||
[[package]]
|
||||
name = "regalloc"
|
||||
version = "0.0.34"
|
||||
name = "regalloc2"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62446b1d3ebf980bdc68837700af1d77b37bc430e524bf95319c6eada2a4cc02"
|
||||
checksum = "4a8d23b35d7177df3b9d31ed8a9ab4bf625c668be77a319d4f5efd4a5257701c"
|
||||
dependencies = [
|
||||
"fxhash",
|
||||
"log",
|
||||
"rustc-hash",
|
||||
"slice-group-by",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
@ -257,12 +312,6 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_codegen_cranelift"
|
||||
version = "0.1.0"
|
||||
@ -283,6 +332,12 @@ dependencies = [
|
||||
"target-lexicon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slice-group-by"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03b634d87b960ab1a38c4fe143b508576f075e7c978bfad18217645ebfdfa2ec"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.8.1"
|
||||
@ -295,6 +350,18 @@ version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7fa7e55043acb85fca6b3c01485a2eeb6b69c5d21002e273c79e465f43b7ac1"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.2+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
|
@ -8,15 +8,15 @@ crate-type = ["dylib"]
|
||||
|
||||
[dependencies]
|
||||
# These have to be in sync with each other
|
||||
cranelift-codegen = { version = "0.83.0", features = ["unwind", "all-arch"] }
|
||||
cranelift-frontend = "0.83.0"
|
||||
cranelift-module = "0.83.0"
|
||||
cranelift-native = "0.83.0"
|
||||
cranelift-jit = { version = "0.83.0", optional = true }
|
||||
cranelift-object = "0.83.0"
|
||||
cranelift-codegen = { version = "0.85.3", features = ["unwind", "all-arch"] }
|
||||
cranelift-frontend = "0.85.3"
|
||||
cranelift-module = "0.85.3"
|
||||
cranelift-native = "0.85.3"
|
||||
cranelift-jit = { version = "0.85.3", optional = true }
|
||||
cranelift-object = "0.85.3"
|
||||
target-lexicon = "0.12.0"
|
||||
gimli = { version = "0.26.0", default-features = false, features = ["write"]}
|
||||
object = { version = "0.27.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
|
||||
object = { version = "0.28.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
|
||||
|
||||
ar = { git = "https://github.com/bjorn3/rust-ar.git", branch = "do_not_remove_cg_clif_ranlib" }
|
||||
indexmap = "1.9.1"
|
||||
|
@ -56,9 +56,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "compiler_builtins"
|
||||
version = "0.1.72"
|
||||
version = "0.1.75"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "afdbb35d279238cf77f0c9e8d90ad50d6c7bff476ab342baafa29440f0f10bff"
|
||||
checksum = "c6e3183e88f659a862835db8f4b67dbeed3d93e44dd4927eef78edb1c149d784"
|
||||
dependencies = [
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
@ -112,9 +112,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.1"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"rustc-std-workspace-alloc",
|
||||
@ -123,20 +123,21 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.2.0"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ab7905ea95c6d9af62940f9d7dd9596d54c334ae2c15300c482051292d5637f"
|
||||
checksum = "7668753748e445859e4e373c3d41117235d9feed578392f5a3a73efdc751ca4a"
|
||||
dependencies = [
|
||||
"compiler_builtins",
|
||||
"libc",
|
||||
"rustc-std-workspace-alloc",
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.125"
|
||||
version = "0.2.126"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b"
|
||||
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
|
||||
dependencies = [
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
@ -205,7 +205,7 @@ fn build_clif_sysroot_for_triple(
|
||||
{
|
||||
let entry = entry.unwrap();
|
||||
if let Some(ext) = entry.path().extension() {
|
||||
if ext == "rmeta" || ext == "d" || ext == "dSYM" {
|
||||
if ext == "rmeta" || ext == "d" || ext == "dSYM" || ext == "clif" {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
|
@ -458,7 +458,7 @@ pub trait FnMut<Args>: FnOnce<Args> {
|
||||
|
||||
#[lang = "panic"]
|
||||
#[track_caller]
|
||||
pub fn panic(_msg: &str) -> ! {
|
||||
pub fn panic(_msg: &'static str) -> ! {
|
||||
unsafe {
|
||||
libc::puts("Panicking\n\0" as *const str as *const i8);
|
||||
intrinsics::abort();
|
||||
@ -497,7 +497,7 @@ pub trait Deref {
|
||||
#[repr(transparent)]
|
||||
#[rustc_layout_scalar_valid_range_start(1)]
|
||||
#[rustc_nonnull_optimization_guaranteed]
|
||||
pub struct NonNull<T: ?Sized>(pub *mut T);
|
||||
pub struct NonNull<T: ?Sized>(pub *const T);
|
||||
|
||||
impl<T: ?Sized, U: ?Sized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> {}
|
||||
impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NonNull<U>> for NonNull<T> where T: Unsize<U> {}
|
||||
@ -521,7 +521,7 @@ impl<T: ?Sized> Drop for Box<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Deref for Box<T> {
|
||||
impl<T: ?Sized> Deref for Box<T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
|
@ -124,6 +124,23 @@ fn call_return_u128_pair() {
|
||||
return_u128_pair();
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct bool_11 {
|
||||
field0: bool,
|
||||
field1: bool,
|
||||
field2: bool,
|
||||
field3: bool,
|
||||
field4: bool,
|
||||
field5: bool,
|
||||
field6: bool,
|
||||
field7: bool,
|
||||
field8: bool,
|
||||
field9: bool,
|
||||
field10: bool,
|
||||
}
|
||||
|
||||
extern "C" fn bool_struct_in_11(arg0: bool_11) {}
|
||||
|
||||
#[allow(unreachable_code)] // FIXME false positive
|
||||
fn main() {
|
||||
take_unique(Unique {
|
||||
@ -134,6 +151,20 @@ fn main() {
|
||||
|
||||
call_return_u128_pair();
|
||||
|
||||
bool_struct_in_11(bool_11 {
|
||||
field0: true,
|
||||
field1: true,
|
||||
field2: true,
|
||||
field3: true,
|
||||
field4: true,
|
||||
field5: true,
|
||||
field6: true,
|
||||
field7: true,
|
||||
field8: true,
|
||||
field9: true,
|
||||
field10: true,
|
||||
});
|
||||
|
||||
let slice = &[0, 1] as &[i32];
|
||||
let slice_ptr = slice as *const [i32] as *const i32;
|
||||
|
||||
@ -299,6 +330,17 @@ fn main() {
|
||||
static REF1: &u8 = &42;
|
||||
static REF2: &u8 = REF1;
|
||||
assert_eq!(*REF1, *REF2);
|
||||
|
||||
extern "C" {
|
||||
type A;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x: &A = unsafe { &*(1usize as *const A) };
|
||||
|
||||
assert_eq!(unsafe { intrinsics::size_of_val(x) }, 0);
|
||||
assert_eq!(unsafe { intrinsics::min_align_of_val(x) }, 1);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(not(jit), target_arch = "x86_64", target_os = "linux"))]
|
||||
|
@ -128,6 +128,25 @@ fn main() {
|
||||
0 => loop {},
|
||||
v => panic(v),
|
||||
};
|
||||
|
||||
if black_box(false) {
|
||||
// Based on https://github.com/rust-lang/rust/blob/2f320a224e827b400be25966755a621779f797cc/src/test/ui/debuginfo/debuginfo_with_uninhabitable_field_and_unsized.rs
|
||||
let _ = Foo::<dyn Send>::new();
|
||||
|
||||
#[allow(dead_code)]
|
||||
struct Foo<T: ?Sized> {
|
||||
base: Never,
|
||||
value: T,
|
||||
}
|
||||
|
||||
impl<T: ?Sized> Foo<T> {
|
||||
pub fn new() -> Box<Foo<T>> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
enum Never {}
|
||||
}
|
||||
}
|
||||
|
||||
fn panic(_: u128) {
|
||||
|
@ -1,3 +1,3 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2022-05-15"
|
||||
channel = "nightly-2022-07-25"
|
||||
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]
|
||||
|
@ -29,14 +29,15 @@ diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/ru
|
||||
index 8431aa7b818..a3ff7e68ce5 100644
|
||||
--- a/src/tools/compiletest/src/runtest.rs
|
||||
+++ b/src/tools/compiletest/src/runtest.rs
|
||||
@@ -3489,11 +3489,7 @@ fn normalize_output(&self, output: &str, custom_rules: &[(String, String)]) -> S
|
||||
.join("library");
|
||||
normalize_path(&src_dir, "$(echo '$SRC_DIR')");
|
||||
@@ -3489,12 +3489,7 @@ fn normalize_output(&self, output: &str, custom_rules: &[(String, String)]) -> S
|
||||
let compiler_src_dir = base_dir.join("compiler");
|
||||
normalize_path(&compiler_src_dir, "$(echo '$COMPILER_DIR')");
|
||||
|
||||
- if let Some(virtual_rust_source_base_dir) =
|
||||
- option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR").map(PathBuf::from)
|
||||
- {
|
||||
- normalize_path(&virtual_rust_source_base_dir.join("library"), "$(echo '$SRC_DIR')");
|
||||
- normalize_path(&virtual_rust_source_base_dir.join("compiler"), "$(echo '$COMPILER_DIR')");
|
||||
- }
|
||||
+ normalize_path(&Path::new("$(cd ../build_sysroot/sysroot_src/library; pwd)"), "$(echo '$SRC_DIR')");
|
||||
|
||||
@ -62,3 +63,6 @@ deny-warnings = false
|
||||
verbose-tests = false
|
||||
EOF
|
||||
popd
|
||||
|
||||
# FIXME remove once inline asm is fully supported
|
||||
export RUSTFLAGS="$RUSTFLAGS --cfg=rustix_use_libc"
|
||||
|
@ -33,6 +33,7 @@ rm src/test/ui/test-attrs/test-fn-signature-verification-for-explicit-return-typ
|
||||
rm src/test/ui/async-await/async-fn-size-moved-locals.rs # -Cpanic=abort shrinks some generator by one byte
|
||||
rm src/test/ui/async-await/async-fn-size-uninit-locals.rs # same
|
||||
rm src/test/ui/generator/size-moved-locals.rs # same
|
||||
rm -r src/test/ui/macros/rfc-2011-nicer-assert-messages/
|
||||
|
||||
# vendor intrinsics
|
||||
rm src/test/ui/sse2.rs # cpuid not supported, so sse2 not detected
|
||||
@ -65,11 +66,13 @@ rm src/test/ui/intrinsics/intrinsic-nearby.rs # unimplemented nearbyintf32 and n
|
||||
rm src/test/ui/target-feature/missing-plusminus.rs # error not implemented
|
||||
rm src/test/ui/fn/dyn-fn-alignment.rs # wants a 256 byte alignment
|
||||
rm -r src/test/run-make/emit-named-files # requires full --emit support
|
||||
rm src/test/ui/abi/stack-probes.rs # stack probes not yet implemented
|
||||
|
||||
# optimization tests
|
||||
# ==================
|
||||
rm src/test/ui/issues/issue-28950.rs # depends on stack size optimizations
|
||||
rm src/test/ui/codegen/issue-28950.rs # depends on stack size optimizations
|
||||
rm src/test/ui/codegen/init-large-type.rs # same
|
||||
rm src/test/ui/issues/issue-40883.rs # same
|
||||
rm -r src/test/run-make/fmt-write-bloat/ # tests an optimization
|
||||
|
||||
# backend specific tests
|
||||
@ -89,14 +92,13 @@ rm src/test/ui/consts/issue-33537.rs # same
|
||||
rm -r src/test/run-make/emit-shared-files # requires the rustdoc executable in build/bin/
|
||||
rm -r src/test/run-make/unstable-flag-required # same
|
||||
rm -r src/test/run-make/rustdoc-* # same
|
||||
rm -r src/test/run-make/issue-88756-default-output # same
|
||||
rm -r src/test/run-make/remap-path-prefix-dwarf # requires llvm-dwarfdump
|
||||
|
||||
# genuine bugs
|
||||
# ============
|
||||
rm src/test/ui/allocator/no_std-alloc-error-handler-default.rs # missing rust_oom definition
|
||||
|
||||
rm -r src/test/ui/polymorphization/ # polymorphization not yet supported
|
||||
rm src/test/codegen-units/polymorphization/unused_type_parameters.rs # same
|
||||
|
||||
rm src/test/incremental/spike-neg1.rs # errors out for some reason
|
||||
rm src/test/incremental/spike-neg2.rs # same
|
||||
rm src/test/ui/issues/issue-74564-if-expr-stack-overflow.rs # gives a stackoverflow before the backend runs
|
||||
@ -111,6 +113,8 @@ rm src/test/ui/backtrace.rs # TODO warning
|
||||
rm src/test/ui/empty_global_asm.rs # TODO add needs-asm-support
|
||||
rm src/test/ui/simple_global_asm.rs # TODO add needs-asm-support
|
||||
rm src/test/ui/test-attrs/test-type.rs # TODO panic message on stderr. correct stdout
|
||||
# not sure if this is actually a bug in the test suite, but the symbol list shows the function without leading _ for some reason
|
||||
rm -r src/test/run-make/native-link-modifier-bundle
|
||||
|
||||
echo "[TEST] rustc test suite"
|
||||
RUST_TEST_NOCAPTURE=1 COMPILETEST_FORCE_STAGE0=1 ./x.py test --stage 0 src/test/{codegen-units,run-make,run-pass-valgrind,ui,incremental}
|
||||
|
@ -4,6 +4,7 @@ mod comments;
|
||||
mod pass_mode;
|
||||
mod returning;
|
||||
|
||||
use cranelift_module::ModuleError;
|
||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||
use rustc_middle::ty::layout::FnAbiOf;
|
||||
use rustc_target::abi::call::{Conv, FnAbi};
|
||||
@ -69,7 +70,17 @@ pub(crate) fn import_function<'tcx>(
|
||||
) -> FuncId {
|
||||
let name = tcx.symbol_name(inst).name;
|
||||
let sig = get_function_sig(tcx, module.isa().triple(), inst);
|
||||
module.declare_function(name, Linkage::Import, &sig).unwrap()
|
||||
match module.declare_function(name, Linkage::Import, &sig) {
|
||||
Ok(func_id) => func_id,
|
||||
Err(ModuleError::IncompatibleDeclaration(_)) => tcx.sess.fatal(&format!(
|
||||
"attempt to declare `{name}` as function, but it was already declared as static"
|
||||
)),
|
||||
Err(ModuleError::IncompatibleSignature(_, prev_sig, new_sig)) => tcx.sess.fatal(&format!(
|
||||
"attempt to declare `{name}` with signature {new_sig:?}, \
|
||||
but it was already declared with signature {prev_sig:?}"
|
||||
)),
|
||||
Err(err) => Err::<_, _>(err).unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> FunctionCx<'_, '_, 'tcx> {
|
||||
@ -182,6 +193,15 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_
|
||||
}
|
||||
|
||||
let fn_abi = fx.fn_abi.take().unwrap();
|
||||
|
||||
// FIXME implement variadics in cranelift
|
||||
if fn_abi.c_variadic {
|
||||
fx.tcx.sess.span_fatal(
|
||||
fx.mir.span,
|
||||
"Defining variadic functions is not yet supported by Cranelift",
|
||||
);
|
||||
}
|
||||
|
||||
let mut arg_abis_iter = fn_abi.args.iter();
|
||||
|
||||
let func_params = fx
|
||||
@ -376,9 +396,15 @@ pub(crate) fn codegen_terminator_call<'tcx>(
|
||||
RevealAllLayoutCx(fx.tcx).fn_abi_of_fn_ptr(fn_ty.fn_sig(fx.tcx), extra_args)
|
||||
};
|
||||
|
||||
let is_cold = instance
|
||||
.map(|inst| fx.tcx.codegen_fn_attrs(inst.def_id()).flags.contains(CodegenFnAttrFlags::COLD))
|
||||
.unwrap_or(false);
|
||||
let is_cold = if fn_sig.abi == Abi::RustCold {
|
||||
true
|
||||
} else {
|
||||
instance
|
||||
.map(|inst| {
|
||||
fx.tcx.codegen_fn_attrs(inst.def_id()).flags.contains(CodegenFnAttrFlags::COLD)
|
||||
})
|
||||
.unwrap_or(false)
|
||||
};
|
||||
if is_cold {
|
||||
fx.bcx.set_cold_block(fx.bcx.current_block().unwrap());
|
||||
if let Some(destination_block) = target {
|
||||
|
@ -18,9 +18,9 @@ fn reg_to_abi_param(reg: Reg) -> AbiParam {
|
||||
let clif_ty = match (reg.kind, reg.size.bytes()) {
|
||||
(RegKind::Integer, 1) => types::I8,
|
||||
(RegKind::Integer, 2) => types::I16,
|
||||
(RegKind::Integer, 4) => types::I32,
|
||||
(RegKind::Integer, 8) => types::I64,
|
||||
(RegKind::Integer, 16) => types::I128,
|
||||
(RegKind::Integer, 3..=4) => types::I32,
|
||||
(RegKind::Integer, 5..=8) => types::I64,
|
||||
(RegKind::Integer, 9..=16) => types::I128,
|
||||
(RegKind::Float, 4) => types::F32,
|
||||
(RegKind::Float, 8) => types::F64,
|
||||
(RegKind::Vector, size) => types::I8.by(u16::try_from(size).unwrap()).unwrap(),
|
||||
@ -48,23 +48,9 @@ fn cast_target_to_abi_params(cast: CastTarget) -> SmallVec<[AbiParam; 2]> {
|
||||
)
|
||||
};
|
||||
|
||||
if cast.prefix.iter().all(|x| x.is_none()) {
|
||||
// Simplify to a single unit when there is no prefix and size <= unit size
|
||||
if cast.rest.total <= cast.rest.unit.size {
|
||||
let clif_ty = match (cast.rest.unit.kind, cast.rest.unit.size.bytes()) {
|
||||
(RegKind::Integer, 1) => types::I8,
|
||||
(RegKind::Integer, 2) => types::I16,
|
||||
(RegKind::Integer, 3..=4) => types::I32,
|
||||
(RegKind::Integer, 5..=8) => types::I64,
|
||||
(RegKind::Integer, 9..=16) => types::I128,
|
||||
(RegKind::Float, 4) => types::F32,
|
||||
(RegKind::Float, 8) => types::F64,
|
||||
(RegKind::Vector, size) => types::I8.by(u16::try_from(size).unwrap()).unwrap(),
|
||||
_ => unreachable!("{:?}", cast.rest.unit),
|
||||
};
|
||||
return smallvec![AbiParam::new(clif_ty)];
|
||||
}
|
||||
}
|
||||
// Note: Unlike the LLVM equivalent of this code we don't have separate branches for when there
|
||||
// is no prefix as a single unit, an array and a heterogeneous struct are not represented using
|
||||
// different types in Cranelift IR. Instead a single array of primitive types is used.
|
||||
|
||||
// Create list of fields in the main structure
|
||||
let mut args = cast
|
||||
@ -230,7 +216,7 @@ pub(super) fn adjust_arg_for_abi<'tcx>(
|
||||
arg_abi: &ArgAbi<'tcx, Ty<'tcx>>,
|
||||
is_owned: bool,
|
||||
) -> SmallVec<[Value; 2]> {
|
||||
assert_assignable(fx, arg.layout().ty, arg_abi.layout.ty);
|
||||
assert_assignable(fx, arg.layout().ty, arg_abi.layout.ty, 16);
|
||||
match arg_abi.mode {
|
||||
PassMode::Ignore => smallvec![],
|
||||
PassMode::Direct(_) => smallvec![arg.load_scalar(fx)],
|
||||
|
@ -86,7 +86,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
|
||||
|
||||
let mut entries = Vec::new();
|
||||
|
||||
for (entry_name, entry) in self.entries {
|
||||
for (mut entry_name, entry) in self.entries {
|
||||
// FIXME only read the symbol table of the object files to avoid having to keep all
|
||||
// object files in memory at once, or read them twice.
|
||||
let data = match entry {
|
||||
@ -109,6 +109,23 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
|
||||
};
|
||||
|
||||
if !self.no_builtin_ranlib {
|
||||
if symbol_table.contains_key(&entry_name) {
|
||||
// The ar crate can't handle creating a symbol table in case of multiple archive
|
||||
// members with the same name. Work around this by prepending a number until we
|
||||
// get a unique name.
|
||||
for i in 1.. {
|
||||
let new_name = format!("{}_", i)
|
||||
.into_bytes()
|
||||
.into_iter()
|
||||
.chain(entry_name.iter().copied())
|
||||
.collect::<Vec<_>>();
|
||||
if !symbol_table.contains_key(&new_name) {
|
||||
entry_name = new_name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match object::File::parse(&*data) {
|
||||
Ok(object) => {
|
||||
symbol_table.insert(
|
||||
|
@ -175,10 +175,37 @@ fn compile_fn<'tcx>(
|
||||
);
|
||||
});
|
||||
|
||||
#[cfg(any())] // This is never true
|
||||
let _clif_guard = {
|
||||
use std::fmt::Write;
|
||||
|
||||
let func_clone = context.func.clone();
|
||||
let clif_comments_clone = clif_comments.clone();
|
||||
let mut clif = String::new();
|
||||
for flag in module.isa().flags().iter() {
|
||||
writeln!(clif, "set {}", flag).unwrap();
|
||||
}
|
||||
write!(clif, "target {}", module.isa().triple().architecture.to_string()).unwrap();
|
||||
for isa_flag in module.isa().isa_flags().iter() {
|
||||
write!(clif, " {}", isa_flag).unwrap();
|
||||
}
|
||||
writeln!(clif, "\n").unwrap();
|
||||
crate::PrintOnPanic(move || {
|
||||
let mut clif = clif.clone();
|
||||
::cranelift_codegen::write::decorate_function(
|
||||
&mut &clif_comments_clone,
|
||||
&mut clif,
|
||||
&func_clone,
|
||||
)
|
||||
.unwrap();
|
||||
clif
|
||||
})
|
||||
};
|
||||
|
||||
// Define function
|
||||
tcx.sess.time("define function", || {
|
||||
context.want_disasm = crate::pretty_clif::should_write_ir(tcx);
|
||||
module.define_function(func_id, context).unwrap()
|
||||
module.define_function(func_id, context).unwrap();
|
||||
});
|
||||
|
||||
// Write optimized function to file for debugging
|
||||
@ -815,15 +842,7 @@ pub(crate) fn codegen_place<'tcx>(
|
||||
for elem in place.projection {
|
||||
match elem {
|
||||
PlaceElem::Deref => {
|
||||
if cplace.layout().ty.is_box() {
|
||||
cplace = cplace
|
||||
.place_field(fx, Field::new(0)) // Box<T> -> Unique<T>
|
||||
.place_field(fx, Field::new(0)) // Unique<T> -> NonNull<T>
|
||||
.place_field(fx, Field::new(0)) // NonNull<T> -> *mut T
|
||||
.place_deref(fx);
|
||||
} else {
|
||||
cplace = cplace.place_deref(fx);
|
||||
}
|
||||
cplace = cplace.place_deref(fx);
|
||||
}
|
||||
PlaceElem::Field(field, _ty) => {
|
||||
cplace = cplace.place_field(fx, field);
|
||||
|
@ -149,17 +149,8 @@ pub(crate) fn clif_int_or_float_cast(
|
||||
}
|
||||
|
||||
let is_not_nan = fx.bcx.ins().fcmp(FloatCC::Equal, from, from);
|
||||
if to_ty == types::I128 {
|
||||
// FIXME(bytecodealliance/wasmtime#3963): select.i128 on fcmp eq miscompiles
|
||||
let (lsb, msb) = fx.bcx.ins().isplit(val);
|
||||
let zero = fx.bcx.ins().iconst(types::I64, 0);
|
||||
let lsb = fx.bcx.ins().select(is_not_nan, lsb, zero);
|
||||
let msb = fx.bcx.ins().select(is_not_nan, msb, zero);
|
||||
fx.bcx.ins().iconcat(lsb, msb)
|
||||
} else {
|
||||
let zero = fx.bcx.ins().iconst(to_ty, 0);
|
||||
fx.bcx.ins().select(is_not_nan, val, zero)
|
||||
}
|
||||
let zero = fx.bcx.ins().iconst(to_ty, 0);
|
||||
fx.bcx.ins().select(is_not_nan, val, zero)
|
||||
} else if from_ty.is_float() && to_ty.is_float() {
|
||||
// float -> float
|
||||
match (from_ty, to_ty) {
|
||||
|
@ -328,14 +328,18 @@ fn data_id_for_static(
|
||||
|
||||
let attrs = tcx.codegen_fn_attrs(def_id);
|
||||
|
||||
let data_id = module
|
||||
.declare_data(
|
||||
&*symbol_name,
|
||||
linkage,
|
||||
is_mutable,
|
||||
attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL),
|
||||
)
|
||||
.unwrap();
|
||||
let data_id = match module.declare_data(
|
||||
&*symbol_name,
|
||||
linkage,
|
||||
is_mutable,
|
||||
attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL),
|
||||
) {
|
||||
Ok(data_id) => data_id,
|
||||
Err(ModuleError::IncompatibleDeclaration(_)) => tcx.sess.fatal(&format!(
|
||||
"attempt to declare `{symbol_name}` as static, but it was already declared as function"
|
||||
)),
|
||||
Err(err) => Err::<_, _>(err).unwrap(),
|
||||
};
|
||||
|
||||
if rlinkage.is_some() {
|
||||
// Comment copied from https://github.com/rust-lang/rust/blob/45060c2a66dfd667f88bd8b94261b28a58d85bd5/src/librustc_codegen_llvm/consts.rs#L141
|
||||
@ -441,7 +445,8 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
|
||||
let data_id = match reloc_target_alloc {
|
||||
GlobalAlloc::Function(instance) => {
|
||||
assert_eq!(addend, 0);
|
||||
let func_id = crate::abi::import_function(tcx, module, instance);
|
||||
let func_id =
|
||||
crate::abi::import_function(tcx, module, instance.polymorphize(tcx));
|
||||
let local_func_id = module.declare_func_in_data(func_id, &mut data_ctx);
|
||||
data_ctx.write_function_addr(offset.bytes() as u32, local_func_id);
|
||||
continue;
|
||||
|
@ -18,86 +18,96 @@ pub(crate) fn codegen_inline_asm<'tcx>(
|
||||
) {
|
||||
// FIXME add .eh_frame unwind info directives
|
||||
|
||||
if template[0] == InlineAsmTemplatePiece::String("int $$0x29".to_string()) {
|
||||
let true_ = fx.bcx.ins().iconst(types::I32, 1);
|
||||
fx.bcx.ins().trapnz(true_, TrapCode::User(1));
|
||||
return;
|
||||
} else if template[0] == InlineAsmTemplatePiece::String("movq %rbx, ".to_string())
|
||||
&& matches!(
|
||||
template[1],
|
||||
InlineAsmTemplatePiece::Placeholder { operand_idx: 0, modifier: Some('r'), span: _ }
|
||||
)
|
||||
&& template[2] == InlineAsmTemplatePiece::String("\n".to_string())
|
||||
&& template[3] == InlineAsmTemplatePiece::String("cpuid".to_string())
|
||||
&& template[4] == InlineAsmTemplatePiece::String("\n".to_string())
|
||||
&& template[5] == InlineAsmTemplatePiece::String("xchgq %rbx, ".to_string())
|
||||
&& matches!(
|
||||
template[6],
|
||||
InlineAsmTemplatePiece::Placeholder { operand_idx: 0, modifier: Some('r'), span: _ }
|
||||
)
|
||||
{
|
||||
assert_eq!(operands.len(), 4);
|
||||
let (leaf, eax_place) = match operands[1] {
|
||||
InlineAsmOperand::InOut { reg, late: true, ref in_value, out_place } => {
|
||||
assert_eq!(
|
||||
reg,
|
||||
InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::ax))
|
||||
);
|
||||
(
|
||||
crate::base::codegen_operand(fx, in_value).load_scalar(fx),
|
||||
crate::base::codegen_place(fx, out_place.unwrap()),
|
||||
)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let ebx_place = match operands[0] {
|
||||
InlineAsmOperand::Out { reg, late: true, place } => {
|
||||
assert_eq!(
|
||||
reg,
|
||||
InlineAsmRegOrRegClass::RegClass(InlineAsmRegClass::X86(
|
||||
X86InlineAsmRegClass::reg
|
||||
))
|
||||
);
|
||||
crate::base::codegen_place(fx, place.unwrap())
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let (sub_leaf, ecx_place) = match operands[2] {
|
||||
InlineAsmOperand::InOut { reg, late: true, ref in_value, out_place } => {
|
||||
assert_eq!(
|
||||
reg,
|
||||
InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::cx))
|
||||
);
|
||||
(
|
||||
crate::base::codegen_operand(fx, in_value).load_scalar(fx),
|
||||
crate::base::codegen_place(fx, out_place.unwrap()),
|
||||
)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let edx_place = match operands[3] {
|
||||
InlineAsmOperand::Out { reg, late: true, place } => {
|
||||
assert_eq!(
|
||||
reg,
|
||||
InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::dx))
|
||||
);
|
||||
crate::base::codegen_place(fx, place.unwrap())
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
if !template.is_empty() {
|
||||
if template[0] == InlineAsmTemplatePiece::String("int $$0x29".to_string()) {
|
||||
let true_ = fx.bcx.ins().iconst(types::I32, 1);
|
||||
fx.bcx.ins().trapnz(true_, TrapCode::User(1));
|
||||
return;
|
||||
} else if template[0] == InlineAsmTemplatePiece::String("movq %rbx, ".to_string())
|
||||
&& matches!(
|
||||
template[1],
|
||||
InlineAsmTemplatePiece::Placeholder {
|
||||
operand_idx: 0,
|
||||
modifier: Some('r'),
|
||||
span: _
|
||||
}
|
||||
)
|
||||
&& template[2] == InlineAsmTemplatePiece::String("\n".to_string())
|
||||
&& template[3] == InlineAsmTemplatePiece::String("cpuid".to_string())
|
||||
&& template[4] == InlineAsmTemplatePiece::String("\n".to_string())
|
||||
&& template[5] == InlineAsmTemplatePiece::String("xchgq %rbx, ".to_string())
|
||||
&& matches!(
|
||||
template[6],
|
||||
InlineAsmTemplatePiece::Placeholder {
|
||||
operand_idx: 0,
|
||||
modifier: Some('r'),
|
||||
span: _
|
||||
}
|
||||
)
|
||||
{
|
||||
assert_eq!(operands.len(), 4);
|
||||
let (leaf, eax_place) = match operands[1] {
|
||||
InlineAsmOperand::InOut { reg, late: true, ref in_value, out_place } => {
|
||||
assert_eq!(
|
||||
reg,
|
||||
InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::ax))
|
||||
);
|
||||
(
|
||||
crate::base::codegen_operand(fx, in_value).load_scalar(fx),
|
||||
crate::base::codegen_place(fx, out_place.unwrap()),
|
||||
)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let ebx_place = match operands[0] {
|
||||
InlineAsmOperand::Out { reg, late: true, place } => {
|
||||
assert_eq!(
|
||||
reg,
|
||||
InlineAsmRegOrRegClass::RegClass(InlineAsmRegClass::X86(
|
||||
X86InlineAsmRegClass::reg
|
||||
))
|
||||
);
|
||||
crate::base::codegen_place(fx, place.unwrap())
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let (sub_leaf, ecx_place) = match operands[2] {
|
||||
InlineAsmOperand::InOut { reg, late: true, ref in_value, out_place } => {
|
||||
assert_eq!(
|
||||
reg,
|
||||
InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::cx))
|
||||
);
|
||||
(
|
||||
crate::base::codegen_operand(fx, in_value).load_scalar(fx),
|
||||
crate::base::codegen_place(fx, out_place.unwrap()),
|
||||
)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let edx_place = match operands[3] {
|
||||
InlineAsmOperand::Out { reg, late: true, place } => {
|
||||
assert_eq!(
|
||||
reg,
|
||||
InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::dx))
|
||||
);
|
||||
crate::base::codegen_place(fx, place.unwrap())
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let (eax, ebx, ecx, edx) = crate::intrinsics::codegen_cpuid_call(fx, leaf, sub_leaf);
|
||||
let (eax, ebx, ecx, edx) = crate::intrinsics::codegen_cpuid_call(fx, leaf, sub_leaf);
|
||||
|
||||
eax_place.write_cvalue(fx, CValue::by_val(eax, fx.layout_of(fx.tcx.types.u32)));
|
||||
ebx_place.write_cvalue(fx, CValue::by_val(ebx, fx.layout_of(fx.tcx.types.u32)));
|
||||
ecx_place.write_cvalue(fx, CValue::by_val(ecx, fx.layout_of(fx.tcx.types.u32)));
|
||||
edx_place.write_cvalue(fx, CValue::by_val(edx, fx.layout_of(fx.tcx.types.u32)));
|
||||
return;
|
||||
} else if fx.tcx.symbol_name(fx.instance).name.starts_with("___chkstk") {
|
||||
// ___chkstk, ___chkstk_ms and __alloca are only used on Windows
|
||||
crate::trap::trap_unimplemented(fx, "Stack probes are not supported");
|
||||
} else if fx.tcx.symbol_name(fx.instance).name == "__alloca" {
|
||||
crate::trap::trap_unimplemented(fx, "Alloca is not supported");
|
||||
eax_place.write_cvalue(fx, CValue::by_val(eax, fx.layout_of(fx.tcx.types.u32)));
|
||||
ebx_place.write_cvalue(fx, CValue::by_val(ebx, fx.layout_of(fx.tcx.types.u32)));
|
||||
ecx_place.write_cvalue(fx, CValue::by_val(ecx, fx.layout_of(fx.tcx.types.u32)));
|
||||
edx_place.write_cvalue(fx, CValue::by_val(edx, fx.layout_of(fx.tcx.types.u32)));
|
||||
return;
|
||||
} else if fx.tcx.symbol_name(fx.instance).name.starts_with("___chkstk") {
|
||||
// ___chkstk, ___chkstk_ms and __alloca are only used on Windows
|
||||
crate::trap::trap_unimplemented(fx, "Stack probes are not supported");
|
||||
} else if fx.tcx.symbol_name(fx.instance).name == "__alloca" {
|
||||
crate::trap::trap_unimplemented(fx, "Alloca is not supported");
|
||||
}
|
||||
}
|
||||
|
||||
let mut inputs = Vec::new();
|
||||
|
@ -404,7 +404,9 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||
};
|
||||
size_of_val, (c ptr) {
|
||||
let layout = fx.layout_of(substs.type_at(0));
|
||||
let size = if layout.is_unsized() {
|
||||
// Note: Can't use is_unsized here as truly unsized types need to take the fixed size
|
||||
// branch
|
||||
let size = if let Abi::ScalarPair(_, _) = ptr.layout().abi {
|
||||
let (_ptr, info) = ptr.load_scalar_pair(fx);
|
||||
let (size, _align) = crate::unsize::size_and_align_of_dst(fx, layout, info);
|
||||
size
|
||||
@ -418,7 +420,9 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||
};
|
||||
min_align_of_val, (c ptr) {
|
||||
let layout = fx.layout_of(substs.type_at(0));
|
||||
let align = if layout.is_unsized() {
|
||||
// Note: Can't use is_unsized here as truly unsized types need to take the fixed size
|
||||
// branch
|
||||
let align = if let Abi::ScalarPair(_, _) = ptr.layout().abi {
|
||||
let (_ptr, info) = ptr.load_scalar_pair(fx);
|
||||
let (_size, align) = crate::unsize::size_and_align_of_dst(fx, layout, info);
|
||||
align
|
||||
@ -1145,6 +1149,20 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||
// FIXME implement black_box semantics
|
||||
ret.write_cvalue(fx, a);
|
||||
};
|
||||
|
||||
// FIXME implement variadics in cranelift
|
||||
va_copy, (o _dest, o _src) {
|
||||
fx.tcx.sess.span_fatal(
|
||||
source_info.span,
|
||||
"Defining variadic functions is not yet supported by Cranelift",
|
||||
);
|
||||
};
|
||||
va_arg | va_end, (o _valist) {
|
||||
fx.tcx.sess.span_fatal(
|
||||
source_info.span,
|
||||
"Defining variadic functions is not yet supported by Cranelift",
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
let ret_block = fx.get_block(destination.unwrap());
|
||||
|
@ -141,7 +141,11 @@ impl<'tcx> CodegenCx<'tcx> {
|
||||
|
||||
let unwind_context =
|
||||
UnwindContext::new(isa, matches!(backend_config.codegen_mode, CodegenMode::Aot));
|
||||
let debug_context = if debug_info { Some(DebugContext::new(tcx, isa)) } else { None };
|
||||
let debug_context = if debug_info && !tcx.sess.target.options.is_like_windows {
|
||||
Some(DebugContext::new(tcx, isa))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
CodegenCx {
|
||||
tcx,
|
||||
global_asm: String::new(),
|
||||
@ -243,6 +247,7 @@ fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Box<dyn isa::Tar
|
||||
flags_builder.set("enable_probestack", "false").unwrap(); // __cranelift_probestack is not provided
|
||||
let enable_verifier = if backend_config.enable_verifier { "true" } else { "false" };
|
||||
flags_builder.set("enable_verifier", enable_verifier).unwrap();
|
||||
flags_builder.set("regalloc_checker", enable_verifier).unwrap();
|
||||
|
||||
let tls_model = match target_triple.binary_format {
|
||||
BinaryFormat::Elf => "elf_gd",
|
||||
|
@ -109,7 +109,8 @@ pub(crate) fn maybe_create_entry_wrapper(
|
||||
tcx.mk_substs([GenericArg::from(main_ret_ty)].iter()),
|
||||
)
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
.unwrap()
|
||||
.polymorphize(tcx);
|
||||
|
||||
let report_name = tcx.symbol_name(report).name;
|
||||
let report_sig = get_function_sig(tcx, m.isa().triple(), report);
|
||||
|
@ -66,7 +66,7 @@ use rustc_session::config::OutputType;
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct CommentWriter {
|
||||
enabled: bool,
|
||||
global_comments: Vec<String>,
|
||||
@ -237,6 +237,7 @@ pub(crate) fn write_clif_file<'tcx>(
|
||||
func: &cranelift_codegen::ir::Function,
|
||||
mut clif_comments: &CommentWriter,
|
||||
) {
|
||||
// FIXME work around filename too long errors
|
||||
write_ir_file(
|
||||
tcx,
|
||||
|| format!("{}.{}.clif", tcx.symbol_name(instance).name, postfix),
|
||||
|
@ -153,11 +153,7 @@ pub(crate) fn size_and_align_of_dst<'tcx>(
|
||||
layout: TyAndLayout<'tcx>,
|
||||
info: Value,
|
||||
) -> (Value, Value) {
|
||||
if !layout.is_unsized() {
|
||||
let size = fx.bcx.ins().iconst(fx.pointer_type, layout.size.bytes() as i64);
|
||||
let align = fx.bcx.ins().iconst(fx.pointer_type, layout.align.abi.bytes() as i64);
|
||||
return (size, align);
|
||||
}
|
||||
assert!(layout.is_unsized() || layout.abi == Abi::Uninhabited);
|
||||
match layout.ty.kind() {
|
||||
ty::Dynamic(..) => {
|
||||
// load size/align from vtable
|
||||
|
@ -324,6 +324,12 @@ impl<'tcx> CPlace<'tcx> {
|
||||
};
|
||||
}
|
||||
|
||||
if layout.size.bytes() >= u64::from(u32::MAX - 16) {
|
||||
fx.tcx
|
||||
.sess
|
||||
.fatal(&format!("values of type {} are too big to store on the stack", layout.ty));
|
||||
}
|
||||
|
||||
let stack_slot = fx.bcx.create_stack_slot(StackSlotData {
|
||||
kind: StackSlotKind::ExplicitSlot,
|
||||
// FIXME Don't force the size to a multiple of 16 bytes once Cranelift gets a way to
|
||||
@ -420,7 +426,7 @@ impl<'tcx> CPlace<'tcx> {
|
||||
}
|
||||
|
||||
pub(crate) fn write_cvalue(self, fx: &mut FunctionCx<'_, '_, 'tcx>, from: CValue<'tcx>) {
|
||||
assert_assignable(fx, from.layout().ty, self.layout().ty);
|
||||
assert_assignable(fx, from.layout().ty, self.layout().ty, 16);
|
||||
|
||||
self.write_cvalue_maybe_transmute(fx, from, "write_cvalue");
|
||||
}
|
||||
@ -774,18 +780,25 @@ pub(crate) fn assert_assignable<'tcx>(
|
||||
fx: &FunctionCx<'_, '_, 'tcx>,
|
||||
from_ty: Ty<'tcx>,
|
||||
to_ty: Ty<'tcx>,
|
||||
limit: usize,
|
||||
) {
|
||||
if limit == 0 {
|
||||
// assert_assignable exists solely to catch bugs in cg_clif. it isn't necessary for
|
||||
// soundness. don't attempt to check deep types to avoid exponential behavior in certain
|
||||
// cases.
|
||||
return;
|
||||
}
|
||||
match (from_ty.kind(), to_ty.kind()) {
|
||||
(ty::Ref(_, a, _), ty::Ref(_, b, _))
|
||||
| (
|
||||
ty::RawPtr(TypeAndMut { ty: a, mutbl: _ }),
|
||||
ty::RawPtr(TypeAndMut { ty: b, mutbl: _ }),
|
||||
) => {
|
||||
assert_assignable(fx, *a, *b);
|
||||
assert_assignable(fx, *a, *b, limit - 1);
|
||||
}
|
||||
(ty::Ref(_, a, _), ty::RawPtr(TypeAndMut { ty: b, mutbl: _ }))
|
||||
| (ty::RawPtr(TypeAndMut { ty: a, mutbl: _ }), ty::Ref(_, b, _)) => {
|
||||
assert_assignable(fx, *a, *b);
|
||||
assert_assignable(fx, *a, *b, limit - 1);
|
||||
}
|
||||
(ty::FnPtr(_), ty::FnPtr(_)) => {
|
||||
let from_sig = fx.tcx.normalize_erasing_late_bound_regions(
|
||||
@ -815,6 +828,17 @@ pub(crate) fn assert_assignable<'tcx>(
|
||||
}
|
||||
// dyn for<'r> Trait<'r> -> dyn Trait<'_> is allowed
|
||||
}
|
||||
(&ty::Tuple(types_a), &ty::Tuple(types_b)) => {
|
||||
let mut types_a = types_a.iter();
|
||||
let mut types_b = types_b.iter();
|
||||
loop {
|
||||
match (types_a.next(), types_b.next()) {
|
||||
(Some(a), Some(b)) => assert_assignable(fx, a, b, limit - 1),
|
||||
(None, None) => return,
|
||||
(Some(_), None) | (None, Some(_)) => panic!("{:#?}/{:#?}", from_ty, to_ty),
|
||||
}
|
||||
}
|
||||
}
|
||||
(&ty::Adt(adt_def_a, substs_a), &ty::Adt(adt_def_b, substs_b))
|
||||
if adt_def_a.did() == adt_def_b.did() =>
|
||||
{
|
||||
@ -822,18 +846,37 @@ pub(crate) fn assert_assignable<'tcx>(
|
||||
let mut types_b = substs_b.types();
|
||||
loop {
|
||||
match (types_a.next(), types_b.next()) {
|
||||
(Some(a), Some(b)) => assert_assignable(fx, a, b),
|
||||
(Some(a), Some(b)) => assert_assignable(fx, a, b, limit - 1),
|
||||
(None, None) => return,
|
||||
(Some(_), None) | (None, Some(_)) => panic!("{:#?}/{:#?}", from_ty, to_ty),
|
||||
}
|
||||
}
|
||||
}
|
||||
(ty::Array(a, _), ty::Array(b, _)) => assert_assignable(fx, *a, *b),
|
||||
(ty::Array(a, _), ty::Array(b, _)) => assert_assignable(fx, *a, *b, limit - 1),
|
||||
(&ty::Closure(def_id_a, substs_a), &ty::Closure(def_id_b, substs_b))
|
||||
if def_id_a == def_id_b =>
|
||||
{
|
||||
let mut types_a = substs_a.types();
|
||||
let mut types_b = substs_b.types();
|
||||
loop {
|
||||
match (types_a.next(), types_b.next()) {
|
||||
(Some(a), Some(b)) => assert_assignable(fx, a, b, limit - 1),
|
||||
(None, None) => return,
|
||||
(Some(_), None) | (None, Some(_)) => panic!("{:#?}/{:#?}", from_ty, to_ty),
|
||||
}
|
||||
}
|
||||
}
|
||||
(ty::Param(_), _) | (_, ty::Param(_)) if fx.tcx.sess.opts.unstable_opts.polymorphize => {
|
||||
// No way to check if it is correct or not with polymorphization enabled
|
||||
}
|
||||
_ => {
|
||||
assert_eq!(
|
||||
from_ty, to_ty,
|
||||
from_ty,
|
||||
to_ty,
|
||||
"Can't write value with incompatible type {:?} to place with type {:?}\n\n{:#?}",
|
||||
from_ty, to_ty, fx,
|
||||
from_ty.kind(),
|
||||
to_ty.kind(),
|
||||
fx,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1883,7 +1883,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
exp_span, exp_found.expected, exp_found.found,
|
||||
);
|
||||
|
||||
if let ObligationCauseCode::CompareImplMethodObligation { .. } = cause.code() {
|
||||
if let ObligationCauseCode::CompareImplItemObligation { .. } = cause.code() {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2351,7 +2351,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
GenericKind::Projection(ref p) => format!("the associated type `{}`", p),
|
||||
};
|
||||
|
||||
if let Some(SubregionOrigin::CompareImplMethodObligation {
|
||||
if let Some(SubregionOrigin::CompareImplItemObligation {
|
||||
span,
|
||||
impl_item_def_id,
|
||||
trait_item_def_id,
|
||||
@ -2788,8 +2788,15 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
|
||||
use self::FailureCode::*;
|
||||
use crate::traits::ObligationCauseCode::*;
|
||||
match self.code() {
|
||||
CompareImplMethodObligation { .. } => Error0308("method not compatible with trait"),
|
||||
CompareImplTypeObligation { .. } => Error0308("type not compatible with trait"),
|
||||
CompareImplItemObligation { kind: ty::AssocKind::Fn, .. } => {
|
||||
Error0308("method not compatible with trait")
|
||||
}
|
||||
CompareImplItemObligation { kind: ty::AssocKind::Type, .. } => {
|
||||
Error0308("type not compatible with trait")
|
||||
}
|
||||
CompareImplItemObligation { kind: ty::AssocKind::Const, .. } => {
|
||||
Error0308("const not compatible with trait")
|
||||
}
|
||||
MatchExpressionArm(box MatchExpressionArmCause { source, .. }) => {
|
||||
Error0308(match source {
|
||||
hir::MatchSource::TryDesugar => "`?` operator has incompatible types",
|
||||
@ -2823,8 +2830,15 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
|
||||
fn as_requirement_str(&self) -> &'static str {
|
||||
use crate::traits::ObligationCauseCode::*;
|
||||
match self.code() {
|
||||
CompareImplMethodObligation { .. } => "method type is compatible with trait",
|
||||
CompareImplTypeObligation { .. } => "associated type is compatible with trait",
|
||||
CompareImplItemObligation { kind: ty::AssocKind::Fn, .. } => {
|
||||
"method type is compatible with trait"
|
||||
}
|
||||
CompareImplItemObligation { kind: ty::AssocKind::Type, .. } => {
|
||||
"associated type is compatible with trait"
|
||||
}
|
||||
CompareImplItemObligation { kind: ty::AssocKind::Const, .. } => {
|
||||
"const is compatible with trait"
|
||||
}
|
||||
ExprAssignable => "expression is assignable",
|
||||
IfExpression { .. } => "`if` and `else` have incompatible types",
|
||||
IfExpressionWithNoElse => "`if` missing an `else` returns `()`",
|
||||
|
@ -2,17 +2,17 @@
|
||||
|
||||
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
|
||||
use crate::infer::lexical_region_resolve::RegionResolutionError;
|
||||
use crate::infer::{SubregionOrigin, Subtype};
|
||||
use crate::traits::ObligationCauseCode::CompareImplMethodObligation;
|
||||
use crate::infer::Subtype;
|
||||
use crate::traits::ObligationCauseCode::CompareImplItemObligation;
|
||||
use rustc_errors::{ErrorGuaranteed, MultiSpan};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::intravisit::Visitor;
|
||||
use rustc_middle::hir::nested_filter;
|
||||
use rustc_middle::ty::print::RegionHighlightMode;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor};
|
||||
use rustc_span::{Span, Symbol};
|
||||
use rustc_span::Span;
|
||||
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
@ -22,38 +22,22 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||
let error = self.error.as_ref()?;
|
||||
debug!("try_report_impl_not_conforming_to_trait {:?}", error);
|
||||
if let RegionResolutionError::SubSupConflict(
|
||||
_, var_origin, sub_origin, _sub, sup_origin, _sup, _,
|
||||
_,
|
||||
var_origin,
|
||||
sub_origin,
|
||||
_sub,
|
||||
sup_origin,
|
||||
_sup,
|
||||
_,
|
||||
) = error.clone()
|
||||
&& let (&Subtype(ref sup_trace), &Subtype(ref sub_trace)) = (&sup_origin, &sub_origin)
|
||||
&& let (
|
||||
sub_expected_found @ Some((sub_expected, sub_found)),
|
||||
sup_expected_found @ Some(_),
|
||||
CompareImplMethodObligation { trait_item_def_id, .. },
|
||||
) = (sub_trace.values.ty(), sup_trace.values.ty(), sub_trace.cause.code())
|
||||
&& let (Subtype(sup_trace), Subtype(sub_trace)) = (&sup_origin, &sub_origin)
|
||||
&& let sub_expected_found @ Some((sub_expected, sub_found)) = sub_trace.values.ty()
|
||||
&& let sup_expected_found @ Some(_) = sup_trace.values.ty()
|
||||
&& let CompareImplItemObligation { trait_item_def_id, .. } = sub_trace.cause.code()
|
||||
&& sup_expected_found == sub_expected_found
|
||||
{
|
||||
let guar = self.emit_err(
|
||||
var_origin.span(),
|
||||
sub_expected,
|
||||
sub_found,
|
||||
*trait_item_def_id,
|
||||
);
|
||||
return Some(guar);
|
||||
}
|
||||
if let RegionResolutionError::ConcreteFailure(origin, _, _)
|
||||
| RegionResolutionError::GenericBoundFailure(origin, _, _) = error.clone()
|
||||
&& let SubregionOrigin::CompareImplTypeObligation {
|
||||
span,
|
||||
impl_item_def_id,
|
||||
trait_item_def_id,
|
||||
} = origin
|
||||
{
|
||||
let guar = self.emit_associated_type_err(
|
||||
span,
|
||||
self.infcx.tcx.item_name(impl_item_def_id.to_def_id()),
|
||||
impl_item_def_id,
|
||||
trait_item_def_id,
|
||||
);
|
||||
let guar =
|
||||
self.emit_err(var_origin.span(), sub_expected, sub_found, *trait_item_def_id);
|
||||
return Some(guar);
|
||||
}
|
||||
None
|
||||
@ -147,25 +131,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||
}
|
||||
err.emit()
|
||||
}
|
||||
|
||||
fn emit_associated_type_err(
|
||||
&self,
|
||||
span: Span,
|
||||
item_name: Symbol,
|
||||
impl_item_def_id: LocalDefId,
|
||||
trait_item_def_id: DefId,
|
||||
) -> ErrorGuaranteed {
|
||||
let impl_sp = self.tcx().def_span(impl_item_def_id);
|
||||
let trait_sp = self.tcx().def_span(trait_item_def_id);
|
||||
let mut err = self
|
||||
.tcx()
|
||||
.sess
|
||||
.struct_span_err(span, &format!("`impl` associated type signature for `{}` doesn't match `trait` associated type signature", item_name));
|
||||
err.span_label(impl_sp, "found");
|
||||
err.span_label(trait_sp, "expected");
|
||||
|
||||
err.emit()
|
||||
}
|
||||
}
|
||||
|
||||
struct TypeParamSpanVisitor<'tcx> {
|
||||
|
@ -86,13 +86,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
"...so that the declared lifetime parameter bounds are satisfied",
|
||||
);
|
||||
}
|
||||
infer::CompareImplMethodObligation { span, .. } => {
|
||||
label_or_note(
|
||||
span,
|
||||
"...so that the definition in impl matches the definition from the trait",
|
||||
);
|
||||
}
|
||||
infer::CompareImplTypeObligation { span, .. } => {
|
||||
infer::CompareImplItemObligation { span, .. } => {
|
||||
label_or_note(
|
||||
span,
|
||||
"...so that the definition in impl matches the definition from the trait",
|
||||
@ -329,15 +323,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
);
|
||||
err
|
||||
}
|
||||
infer::CompareImplMethodObligation { span, impl_item_def_id, trait_item_def_id } => {
|
||||
self.report_extra_impl_obligation(
|
||||
span,
|
||||
impl_item_def_id,
|
||||
trait_item_def_id,
|
||||
&format!("`{}: {}`", sup, sub),
|
||||
)
|
||||
}
|
||||
infer::CompareImplTypeObligation { span, impl_item_def_id, trait_item_def_id } => self
|
||||
infer::CompareImplItemObligation { span, impl_item_def_id, trait_item_def_id } => self
|
||||
.report_extra_impl_obligation(
|
||||
span,
|
||||
impl_item_def_id,
|
||||
|
@ -405,15 +405,7 @@ pub enum SubregionOrigin<'tcx> {
|
||||
|
||||
/// Comparing the signature and requirements of an impl method against
|
||||
/// the containing trait.
|
||||
CompareImplMethodObligation {
|
||||
span: Span,
|
||||
impl_item_def_id: LocalDefId,
|
||||
trait_item_def_id: DefId,
|
||||
},
|
||||
|
||||
/// Comparing the signature and requirements of an impl associated type
|
||||
/// against the containing trait
|
||||
CompareImplTypeObligation { span: Span, impl_item_def_id: LocalDefId, trait_item_def_id: DefId },
|
||||
CompareImplItemObligation { span: Span, impl_item_def_id: LocalDefId, trait_item_def_id: DefId },
|
||||
|
||||
/// Checking that the bounds of a trait's associated type hold for a given impl
|
||||
CheckAssociatedTypeBounds {
|
||||
@ -1945,8 +1937,7 @@ impl<'tcx> SubregionOrigin<'tcx> {
|
||||
ReborrowUpvar(a, _) => a,
|
||||
DataBorrowed(_, a) => a,
|
||||
ReferenceOutlivesReferent(_, a) => a,
|
||||
CompareImplMethodObligation { span, .. } => span,
|
||||
CompareImplTypeObligation { span, .. } => span,
|
||||
CompareImplItemObligation { span, .. } => span,
|
||||
CheckAssociatedTypeBounds { ref parent, .. } => parent.span(),
|
||||
}
|
||||
}
|
||||
@ -1960,19 +1951,11 @@ impl<'tcx> SubregionOrigin<'tcx> {
|
||||
SubregionOrigin::ReferenceOutlivesReferent(ref_type, cause.span)
|
||||
}
|
||||
|
||||
traits::ObligationCauseCode::CompareImplMethodObligation {
|
||||
traits::ObligationCauseCode::CompareImplItemObligation {
|
||||
impl_item_def_id,
|
||||
trait_item_def_id,
|
||||
} => SubregionOrigin::CompareImplMethodObligation {
|
||||
span: cause.span,
|
||||
impl_item_def_id,
|
||||
trait_item_def_id,
|
||||
},
|
||||
|
||||
traits::ObligationCauseCode::CompareImplTypeObligation {
|
||||
impl_item_def_id,
|
||||
trait_item_def_id,
|
||||
} => SubregionOrigin::CompareImplTypeObligation {
|
||||
kind: _,
|
||||
} => SubregionOrigin::CompareImplItemObligation {
|
||||
span: cause.span,
|
||||
impl_item_def_id,
|
||||
trait_item_def_id,
|
||||
|
@ -311,18 +311,10 @@ pub enum ObligationCauseCode<'tcx> {
|
||||
},
|
||||
|
||||
/// Error derived when matching traits/impls; see ObligationCause for more details
|
||||
CompareImplConstObligation,
|
||||
|
||||
/// Error derived when matching traits/impls; see ObligationCause for more details
|
||||
CompareImplMethodObligation {
|
||||
impl_item_def_id: LocalDefId,
|
||||
trait_item_def_id: DefId,
|
||||
},
|
||||
|
||||
/// Error derived when matching traits/impls; see ObligationCause for more details
|
||||
CompareImplTypeObligation {
|
||||
CompareImplItemObligation {
|
||||
impl_item_def_id: LocalDefId,
|
||||
trait_item_def_id: DefId,
|
||||
kind: ty::AssocKind,
|
||||
},
|
||||
|
||||
/// Checking that the bounds of a trait's associated type hold for a given impl
|
||||
|
@ -105,6 +105,16 @@ impl AssocKind {
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for AssocKind {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
AssocKind::Fn => write!(f, "method"),
|
||||
AssocKind::Const => write!(f, "associated const"),
|
||||
AssocKind::Type => write!(f, "associated type"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A list of `ty::AssocItem`s in definition order that allows for efficient lookup by name.
|
||||
///
|
||||
/// When doing lookup by name, we try to postpone hygienic comparison for as long as possible since
|
||||
|
@ -660,12 +660,8 @@ impl<T> Trait<T> for X {
|
||||
| hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(..), .. }),
|
||||
)
|
||||
);
|
||||
let impl_comparison = matches!(
|
||||
cause_code,
|
||||
ObligationCauseCode::CompareImplMethodObligation { .. }
|
||||
| ObligationCauseCode::CompareImplTypeObligation { .. }
|
||||
| ObligationCauseCode::CompareImplConstObligation
|
||||
);
|
||||
let impl_comparison =
|
||||
matches!(cause_code, ObligationCauseCode::CompareImplItemObligation { .. });
|
||||
let assoc = self.associated_item(proj_ty.item_def_id);
|
||||
if !callable_scope || impl_comparison {
|
||||
// We do not want to suggest calling functions when the reason of the
|
||||
|
@ -224,6 +224,7 @@ TrivialTypeTraversalAndLiftImpls! {
|
||||
// general `Region`.
|
||||
crate::ty::BoundRegionKind,
|
||||
crate::ty::AssocItem,
|
||||
crate::ty::AssocKind,
|
||||
crate::ty::Placeholder<crate::ty::BoundRegionKind>,
|
||||
crate::ty::ClosureKind,
|
||||
crate::ty::FreeRegion,
|
||||
|
@ -951,7 +951,7 @@ fn adt_defined_here<'p, 'tcx>(
|
||||
let mut span: MultiSpan =
|
||||
if spans.is_empty() { def_span.into() } else { spans.clone().into() };
|
||||
|
||||
span.push_span_label(def_span, String::new());
|
||||
span.push_span_label(def_span, "");
|
||||
for pat in spans {
|
||||
span.push_span_label(pat, "not covered");
|
||||
}
|
||||
|
@ -315,7 +315,7 @@ pub fn remove_dead_blocks<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
/// with `0` executions.
|
||||
///
|
||||
/// If there are no live `Counter` `Coverage` statements remaining, we remove
|
||||
/// dead `Coverage` statements along with the dead blocks. Since at least one
|
||||
/// `Coverage` statements along with the dead blocks. Since at least one
|
||||
/// counter per function is required by LLVM (and necessary, to add the
|
||||
/// `function_hash` to the counter's call to the LLVM intrinsic
|
||||
/// `instrprof.increment()`).
|
||||
@ -342,6 +342,16 @@ fn save_unreachable_coverage(
|
||||
}
|
||||
}
|
||||
|
||||
for block in &mut basic_blocks.raw[..first_dead_block] {
|
||||
for statement in &mut block.statements {
|
||||
let StatementKind::Coverage(_) = &statement.kind else { continue };
|
||||
let instance = statement.source_info.scope.inlined_instance(source_scopes);
|
||||
if !live.contains(&instance) {
|
||||
statement.make_nop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if live.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
@ -565,8 +565,7 @@ impl<'a> Resolver<'a> {
|
||||
} else if let Some(sp) = sm.generate_fn_name_span(span) {
|
||||
err.span_label(
|
||||
sp,
|
||||
"try adding a local generic parameter in this method instead"
|
||||
.to_string(),
|
||||
"try adding a local generic parameter in this method instead",
|
||||
);
|
||||
} else {
|
||||
err.help("try using a local generic parameter instead");
|
||||
|
@ -586,17 +586,6 @@ impl SourceMap {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns whether or not this span points into a file
|
||||
/// in the current crate. This may be `false` for spans
|
||||
/// produced by a macro expansion, or for spans associated
|
||||
/// with the definition of an item in a foreign crate
|
||||
pub fn is_local_span(&self, sp: Span) -> bool {
|
||||
let local_begin = self.lookup_byte_offset(sp.lo());
|
||||
let local_end = self.lookup_byte_offset(sp.hi());
|
||||
// This might be a weird span that covers multiple files
|
||||
local_begin.sf.src.is_some() && local_end.sf.src.is_some()
|
||||
}
|
||||
|
||||
pub fn is_span_accessible(&self, sp: Span) -> bool {
|
||||
self.span_to_source(sp, |src, start_index, end_index| {
|
||||
Ok(src.get(start_index..end_index).is_some())
|
||||
|
@ -301,13 +301,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
span = obligation.cause.span;
|
||||
}
|
||||
}
|
||||
if let ObligationCauseCode::CompareImplMethodObligation {
|
||||
impl_item_def_id,
|
||||
trait_item_def_id,
|
||||
}
|
||||
| ObligationCauseCode::CompareImplTypeObligation {
|
||||
if let ObligationCauseCode::CompareImplItemObligation {
|
||||
impl_item_def_id,
|
||||
trait_item_def_id,
|
||||
kind: _,
|
||||
} = *obligation.cause.code()
|
||||
{
|
||||
self.report_extra_impl_obligation(
|
||||
|
@ -2682,11 +2682,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
)
|
||||
});
|
||||
}
|
||||
ObligationCauseCode::CompareImplMethodObligation { trait_item_def_id, .. } => {
|
||||
ObligationCauseCode::CompareImplItemObligation { trait_item_def_id, kind, .. } => {
|
||||
let item_name = self.tcx.item_name(trait_item_def_id);
|
||||
let msg = format!(
|
||||
"the requirement `{}` appears on the impl method `{}` but not on the \
|
||||
corresponding trait method",
|
||||
"the requirement `{}` appears on the `impl`'s {kind} `{}` but not on the \
|
||||
corresponding trait's {kind}",
|
||||
predicate, item_name,
|
||||
);
|
||||
let sp = self
|
||||
@ -2697,7 +2697,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
let mut assoc_span: MultiSpan = sp.into();
|
||||
assoc_span.push_span_label(
|
||||
sp,
|
||||
format!("this trait method doesn't have the requirement `{}`", predicate),
|
||||
format!("this trait's {kind} doesn't have the requirement `{}`", predicate),
|
||||
);
|
||||
if let Some(ident) = self
|
||||
.tcx
|
||||
@ -2708,38 +2708,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
}
|
||||
err.span_note(assoc_span, &msg);
|
||||
}
|
||||
ObligationCauseCode::CompareImplTypeObligation { trait_item_def_id, .. } => {
|
||||
let item_name = self.tcx.item_name(trait_item_def_id);
|
||||
let msg = format!(
|
||||
"the requirement `{}` appears on the associated impl type `{}` but not on the \
|
||||
corresponding associated trait type",
|
||||
predicate, item_name,
|
||||
);
|
||||
let sp = self.tcx.def_span(trait_item_def_id);
|
||||
let mut assoc_span: MultiSpan = sp.into();
|
||||
assoc_span.push_span_label(
|
||||
sp,
|
||||
format!(
|
||||
"this trait associated type doesn't have the requirement `{}`",
|
||||
predicate,
|
||||
),
|
||||
);
|
||||
if let Some(ident) = self
|
||||
.tcx
|
||||
.opt_associated_item(trait_item_def_id)
|
||||
.and_then(|i| self.tcx.opt_item_ident(i.container.id()))
|
||||
{
|
||||
assoc_span.push_span_label(ident.span, "in this trait");
|
||||
}
|
||||
err.span_note(assoc_span, &msg);
|
||||
}
|
||||
ObligationCauseCode::CompareImplConstObligation => {
|
||||
err.note(&format!(
|
||||
"the requirement `{}` appears on the associated impl constant \
|
||||
but not on the corresponding associated trait constant",
|
||||
predicate
|
||||
));
|
||||
}
|
||||
ObligationCauseCode::TrivialBound => {
|
||||
err.help("see issue #48214");
|
||||
if tcx.sess.opts.unstable_features.is_nightly_build() {
|
||||
|
@ -8,7 +8,7 @@ use rustc_middle::ty;
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_span::lev_distance::find_best_match_for_name;
|
||||
use rustc_span::symbol::{sym, Ident};
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
use rustc_span::{Span, Symbol, DUMMY_SP};
|
||||
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
@ -17,7 +17,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
/// the type parameter's name as a placeholder.
|
||||
pub(crate) fn complain_about_missing_type_params(
|
||||
&self,
|
||||
missing_type_params: Vec<String>,
|
||||
missing_type_params: Vec<Symbol>,
|
||||
def_id: DefId,
|
||||
span: Span,
|
||||
empty_generic_args: bool,
|
||||
|
@ -382,7 +382,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
def_id: DefId,
|
||||
generic_args: &'a GenericArgs<'a>,
|
||||
span: Span,
|
||||
missing_type_params: Vec<String>,
|
||||
missing_type_params: Vec<Symbol>,
|
||||
inferred_params: Vec<Span>,
|
||||
infer_args: bool,
|
||||
is_object: bool,
|
||||
@ -514,7 +514,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
// defaults. This will lead to an ICE if we are not
|
||||
// careful!
|
||||
if self.default_needs_object_self(param) {
|
||||
self.missing_type_params.push(param.name.to_string());
|
||||
self.missing_type_params.push(param.name);
|
||||
tcx.ty_error().into()
|
||||
} else {
|
||||
// This is a default type parameter.
|
||||
@ -1150,17 +1150,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
.expect("missing associated type");
|
||||
|
||||
if !assoc_item.vis.is_accessible_from(def_scope, tcx) {
|
||||
let kind = match assoc_item.kind {
|
||||
ty::AssocKind::Type => "type",
|
||||
ty::AssocKind::Const => "const",
|
||||
_ => unreachable!(),
|
||||
};
|
||||
tcx.sess
|
||||
.struct_span_err(
|
||||
binding.span,
|
||||
&format!("associated {kind} `{}` is private", binding.item_name),
|
||||
&format!("{} `{}` is private", assoc_item.kind, binding.item_name),
|
||||
)
|
||||
.span_label(binding.span, &format!("private associated {kind}"))
|
||||
.span_label(binding.span, &format!("private {}", assoc_item.kind))
|
||||
.emit();
|
||||
}
|
||||
tcx.check_stability(assoc_item.def_id, Some(hir_ref_id), binding.span, None);
|
||||
|
@ -488,7 +488,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
ty::Binder::dummy(ty::PredicateKind::Trait(ty::TraitPredicate {
|
||||
trait_ref: ty::TraitRef {
|
||||
def_id: t.def_id(),
|
||||
substs: self.infcx.tcx.mk_substs_trait(outer_ty, &[]),
|
||||
substs: self.tcx.mk_substs_trait(outer_ty, &[]),
|
||||
},
|
||||
constness: t.constness,
|
||||
polarity: t.polarity,
|
||||
@ -496,9 +496,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let obl = Obligation::new(
|
||||
o.cause.clone(),
|
||||
self.param_env,
|
||||
pred.to_predicate(self.infcx.tcx),
|
||||
pred.to_predicate(self.tcx),
|
||||
);
|
||||
suggest_box &= self.infcx.predicate_must_hold_modulo_regions(&obl);
|
||||
suggest_box &= self.predicate_must_hold_modulo_regions(&obl);
|
||||
if !suggest_box {
|
||||
// We've encountered some obligation that didn't hold, so the
|
||||
// return expression can't just be boxed. We don't need to
|
||||
|
@ -376,7 +376,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
self.param_env,
|
||||
*predicate,
|
||||
);
|
||||
let result = self.infcx.evaluate_obligation(&obligation);
|
||||
let result = self.evaluate_obligation(&obligation);
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_err(
|
||||
|
@ -96,7 +96,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
self.tcx.typeck_root_def_id(expr_def_id.to_def_id()),
|
||||
);
|
||||
|
||||
let tupled_upvars_ty = self.infcx.next_ty_var(TypeVariableOrigin {
|
||||
let tupled_upvars_ty = self.next_ty_var(TypeVariableOrigin {
|
||||
kind: TypeVariableOriginKind::ClosureSynthetic,
|
||||
span: self.tcx.hir().span(expr.hir_id),
|
||||
});
|
||||
@ -141,7 +141,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
// Create a type variable (for now) to represent the closure kind.
|
||||
// It will be unified during the upvar inference phase (`upvar.rs`)
|
||||
None => self.infcx.next_ty_var(TypeVariableOrigin {
|
||||
None => self.next_ty_var(TypeVariableOrigin {
|
||||
// FIXME(eddyb) distinguish closure kind inference variables from the rest.
|
||||
kind: TypeVariableOriginKind::ClosureSynthetic,
|
||||
span: expr.span,
|
||||
@ -531,7 +531,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
//
|
||||
// [c1]: https://github.com/rust-lang/rust/pull/45072#issuecomment-341089706
|
||||
// [c2]: https://github.com/rust-lang/rust/pull/45072#issuecomment-341096796
|
||||
self.infcx.commit_if_ok(|_| {
|
||||
self.commit_if_ok(|_| {
|
||||
let mut all_obligations = vec![];
|
||||
|
||||
// The liberated version of this signature should be a subtype
|
||||
@ -544,7 +544,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
expected_sigs.liberated_sig.inputs(), // `liberated_sig` is E'.
|
||||
) {
|
||||
// Instantiate (this part of..) S to S', i.e., with fresh variables.
|
||||
let supplied_ty = self.infcx.replace_bound_vars_with_fresh_vars(
|
||||
let supplied_ty = self.replace_bound_vars_with_fresh_vars(
|
||||
hir_ty.span,
|
||||
LateBoundRegionConversionTime::FnCall,
|
||||
supplied_sig.inputs().rebind(supplied_ty),
|
||||
@ -557,7 +557,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
all_obligations.extend(obligations);
|
||||
}
|
||||
|
||||
let supplied_output_ty = self.infcx.replace_bound_vars_with_fresh_vars(
|
||||
let supplied_output_ty = self.replace_bound_vars_with_fresh_vars(
|
||||
decl.output.span(),
|
||||
LateBoundRegionConversionTime::FnCall,
|
||||
supplied_sig.output(),
|
||||
|
@ -241,13 +241,13 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
make_adjustments: impl FnOnce(Ty<'tcx>) -> Vec<Adjustment<'tcx>>,
|
||||
) -> CoerceResult<'tcx> {
|
||||
debug!("coerce_from_inference_variable(a={:?}, b={:?})", a, b);
|
||||
assert!(a.is_ty_var() && self.infcx.shallow_resolve(a) == a);
|
||||
assert!(self.infcx.shallow_resolve(b) == b);
|
||||
assert!(a.is_ty_var() && self.shallow_resolve(a) == a);
|
||||
assert!(self.shallow_resolve(b) == b);
|
||||
|
||||
if b.is_ty_var() {
|
||||
// Two unresolved type variables: create a `Coerce` predicate.
|
||||
let target_ty = if self.use_lub {
|
||||
self.infcx.next_ty_var(TypeVariableOrigin {
|
||||
self.next_ty_var(TypeVariableOrigin {
|
||||
kind: TypeVariableOriginKind::LatticeVariable,
|
||||
span: self.cause.span,
|
||||
})
|
||||
@ -991,7 +991,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
self.autoderef(rustc_span::DUMMY_SP, expr_ty).nth(1).and_then(|(deref_ty, _)| {
|
||||
self.infcx
|
||||
.type_implements_trait(
|
||||
self.infcx.tcx.lang_items().deref_mut_trait()?,
|
||||
self.tcx.lang_items().deref_mut_trait()?,
|
||||
expr_ty,
|
||||
ty::List::empty(),
|
||||
self.param_env,
|
||||
|
@ -90,9 +90,10 @@ fn compare_predicate_entailment<'tcx>(
|
||||
let mut cause = ObligationCause::new(
|
||||
impl_m_span,
|
||||
impl_m_hir_id,
|
||||
ObligationCauseCode::CompareImplMethodObligation {
|
||||
ObligationCauseCode::CompareImplItemObligation {
|
||||
impl_item_def_id: impl_m.def_id.expect_local(),
|
||||
trait_item_def_id: trait_m.def_id,
|
||||
kind: impl_m.kind,
|
||||
},
|
||||
);
|
||||
|
||||
@ -223,9 +224,10 @@ fn compare_predicate_entailment<'tcx>(
|
||||
let cause = ObligationCause::new(
|
||||
span,
|
||||
impl_m_hir_id,
|
||||
ObligationCauseCode::CompareImplMethodObligation {
|
||||
ObligationCauseCode::CompareImplItemObligation {
|
||||
impl_item_def_id: impl_m.def_id.expect_local(),
|
||||
trait_item_def_id: trait_m.def_id,
|
||||
kind: impl_m.kind,
|
||||
},
|
||||
);
|
||||
ocx.register_obligation(traits::Obligation::new(cause, param_env, predicate));
|
||||
@ -1079,7 +1081,11 @@ pub(crate) fn compare_const_impl<'tcx>(
|
||||
let mut cause = ObligationCause::new(
|
||||
impl_c_span,
|
||||
impl_c_hir_id,
|
||||
ObligationCauseCode::CompareImplConstObligation,
|
||||
ObligationCauseCode::CompareImplItemObligation {
|
||||
impl_item_def_id: impl_c.def_id.expect_local(),
|
||||
trait_item_def_id: trait_c.def_id,
|
||||
kind: impl_c.kind,
|
||||
},
|
||||
);
|
||||
|
||||
// There is no "body" here, so just pass dummy id.
|
||||
@ -1212,15 +1218,6 @@ fn compare_type_predicate_entailment<'tcx>(
|
||||
// `ObligationCause` (and the `FnCtxt`). This is what
|
||||
// `regionck_item` expects.
|
||||
let impl_ty_hir_id = tcx.hir().local_def_id_to_hir_id(impl_ty.def_id.expect_local());
|
||||
let cause = ObligationCause::new(
|
||||
impl_ty_span,
|
||||
impl_ty_hir_id,
|
||||
ObligationCauseCode::CompareImplTypeObligation {
|
||||
impl_item_def_id: impl_ty.def_id.expect_local(),
|
||||
trait_item_def_id: trait_ty.def_id,
|
||||
},
|
||||
);
|
||||
|
||||
debug!("compare_type_predicate_entailment: trait_to_impl_substs={:?}", trait_to_impl_substs);
|
||||
|
||||
// The predicates declared by the impl definition, the trait and the
|
||||
@ -1239,7 +1236,7 @@ fn compare_type_predicate_entailment<'tcx>(
|
||||
Reveal::UserFacing,
|
||||
hir::Constness::NotConst,
|
||||
);
|
||||
let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause.clone());
|
||||
let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause);
|
||||
tcx.infer_ctxt().enter(|infcx| {
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
|
||||
@ -1247,12 +1244,25 @@ fn compare_type_predicate_entailment<'tcx>(
|
||||
|
||||
let mut selcx = traits::SelectionContext::new(&infcx);
|
||||
|
||||
for predicate in impl_ty_own_bounds.predicates {
|
||||
assert_eq!(impl_ty_own_bounds.predicates.len(), impl_ty_own_bounds.spans.len());
|
||||
for (span, predicate) in
|
||||
std::iter::zip(impl_ty_own_bounds.spans, impl_ty_own_bounds.predicates)
|
||||
{
|
||||
let cause = ObligationCause::misc(span, impl_ty_hir_id);
|
||||
let traits::Normalized { value: predicate, obligations } =
|
||||
traits::normalize(&mut selcx, param_env, normalize_cause.clone(), predicate);
|
||||
traits::normalize(&mut selcx, param_env, cause, predicate);
|
||||
|
||||
let cause = ObligationCause::new(
|
||||
span,
|
||||
impl_ty_hir_id,
|
||||
ObligationCauseCode::CompareImplItemObligation {
|
||||
impl_item_def_id: impl_ty.def_id.expect_local(),
|
||||
trait_item_def_id: trait_ty.def_id,
|
||||
kind: impl_ty.kind,
|
||||
},
|
||||
);
|
||||
ocx.register_obligations(obligations);
|
||||
ocx.register_obligation(traits::Obligation::new(cause.clone(), param_env, predicate));
|
||||
ocx.register_obligation(traits::Obligation::new(cause, param_env, predicate));
|
||||
}
|
||||
|
||||
// Check that all obligations are satisfied by the implementation's
|
||||
|
@ -287,6 +287,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
expr_ty: Ty<'tcx>,
|
||||
) {
|
||||
if let ty::Adt(expected_adt, substs) = expected.kind() {
|
||||
if let hir::ExprKind::Field(base, ident) = expr.kind {
|
||||
let base_ty = self.typeck_results.borrow().expr_ty(base);
|
||||
if self.can_eq(self.param_env, base_ty, expected).is_ok()
|
||||
&& let Some(base_span) = base.span.find_ancestor_inside(expr.span)
|
||||
{
|
||||
err.span_suggestion_verbose(
|
||||
expr.span.with_lo(base_span.hi()),
|
||||
format!("consider removing the tuple struct field `{ident}`"),
|
||||
"",
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// If the expression is of type () and it's the return expression of a block,
|
||||
// we suggest adding a separate return expression instead.
|
||||
// (To avoid things like suggesting `Ok(while .. { .. })`.)
|
||||
@ -815,7 +830,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
hir::ExprKind::AddrOf(hir::BorrowKind::Ref, _, ref expr),
|
||||
_,
|
||||
&ty::Ref(_, checked, _),
|
||||
) if self.infcx.can_sub(self.param_env, checked, expected).is_ok() => {
|
||||
) if self.can_sub(self.param_env, checked, expected).is_ok() => {
|
||||
// We have `&T`, check if what was expected was `T`. If so,
|
||||
// we may want to suggest removing a `&`.
|
||||
if sm.is_imported(expr.span) {
|
||||
@ -959,7 +974,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
// For this suggestion to make sense, the type would need to be `Copy`,
|
||||
// or we have to be moving out of a `Box<T>`
|
||||
if self.infcx.type_is_copy_modulo_regions(self.param_env, expected, sp)
|
||||
if self.type_is_copy_modulo_regions(self.param_env, expected, sp)
|
||||
// FIXME(compiler-errors): We can actually do this if the checked_ty is
|
||||
// `steps` layers of boxes, not just one, but this is easier and most likely.
|
||||
|| (checked_ty.is_box() && steps == 1)
|
||||
|
@ -2235,7 +2235,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
base: &'tcx hir::Expr<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) {
|
||||
let output_ty = match self.infcx.get_impl_future_output_ty(ty) {
|
||||
let output_ty = match self.get_impl_future_output_ty(ty) {
|
||||
Some(output_ty) => self.resolve_vars_if_possible(output_ty),
|
||||
_ => return,
|
||||
};
|
||||
|
@ -218,9 +218,9 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
|
||||
.diverging_type_vars
|
||||
.borrow()
|
||||
.iter()
|
||||
.map(|&ty| self.infcx.shallow_resolve(ty))
|
||||
.map(|&ty| self.shallow_resolve(ty))
|
||||
.filter_map(|ty| ty.ty_vid())
|
||||
.map(|vid| self.infcx.root_var(vid))
|
||||
.map(|vid| self.root_var(vid))
|
||||
.collect();
|
||||
debug!(
|
||||
"calculate_diverging_fallback: diverging_type_vars={:?}",
|
||||
@ -236,7 +236,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
|
||||
let mut diverging_vids = vec![];
|
||||
let mut non_diverging_vids = vec![];
|
||||
for unsolved_vid in unsolved_vids {
|
||||
let root_vid = self.infcx.root_var(unsolved_vid);
|
||||
let root_vid = self.root_var(unsolved_vid);
|
||||
debug!(
|
||||
"calculate_diverging_fallback: unsolved_vid={:?} root_vid={:?} diverges={:?}",
|
||||
unsolved_vid,
|
||||
@ -271,7 +271,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
|
||||
// variables. (Note that this set consists of "root variables".)
|
||||
let mut roots_reachable_from_non_diverging = DepthFirstSearch::new(&coercion_graph);
|
||||
for &non_diverging_vid in &non_diverging_vids {
|
||||
let root_vid = self.infcx.root_var(non_diverging_vid);
|
||||
let root_vid = self.root_var(non_diverging_vid);
|
||||
if roots_reachable_from_diverging.visited(root_vid) {
|
||||
continue;
|
||||
}
|
||||
@ -294,7 +294,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
|
||||
diverging_fallback.reserve(diverging_vids.len());
|
||||
for &diverging_vid in &diverging_vids {
|
||||
let diverging_ty = self.tcx.mk_ty_var(diverging_vid);
|
||||
let root_vid = self.infcx.root_var(diverging_vid);
|
||||
let root_vid = self.root_var(diverging_vid);
|
||||
let can_reach_non_diverging = coercion_graph
|
||||
.depth_first_search(root_vid)
|
||||
.any(|n| roots_reachable_from_non_diverging.visited(n));
|
||||
@ -302,7 +302,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
|
||||
let mut relationship = ty::FoundRelationships { self_in_trait: false, output: false };
|
||||
|
||||
for (vid, rel) in relationships.iter() {
|
||||
if self.infcx.root_var(*vid) == root_vid {
|
||||
if self.root_var(*vid) == root_vid {
|
||||
relationship.self_in_trait |= rel.self_in_trait;
|
||||
relationship.output |= rel.output;
|
||||
}
|
||||
@ -387,12 +387,12 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
|
||||
})
|
||||
.collect();
|
||||
debug!("create_coercion_graph: coercion_edges={:?}", coercion_edges);
|
||||
let num_ty_vars = self.infcx.num_ty_vars();
|
||||
let num_ty_vars = self.num_ty_vars();
|
||||
VecGraph::new(num_ty_vars, coercion_edges)
|
||||
}
|
||||
|
||||
/// If `ty` is an unresolved type variable, returns its root vid.
|
||||
fn root_vid(&self, ty: Ty<'tcx>) -> Option<ty::TyVid> {
|
||||
Some(self.infcx.root_var(self.infcx.shallow_resolve(ty).ty_vid()?))
|
||||
Some(self.root_var(self.shallow_resolve(ty).ty_vid()?))
|
||||
}
|
||||
}
|
||||
|
@ -185,12 +185,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
if !method.substs.is_empty() {
|
||||
let method_generics = self.tcx.generics_of(method.def_id);
|
||||
if !method_generics.params.is_empty() {
|
||||
let user_type_annotation = self.infcx.probe(|_| {
|
||||
let user_type_annotation = self.probe(|_| {
|
||||
let user_substs = UserSubsts {
|
||||
substs: InternalSubsts::for_item(self.tcx, method.def_id, |param, _| {
|
||||
let i = param.index as usize;
|
||||
if i < method_generics.parent_count {
|
||||
self.infcx.var_for_def(DUMMY_SP, param)
|
||||
self.var_for_def(DUMMY_SP, param)
|
||||
} else {
|
||||
method.substs[i]
|
||||
}
|
||||
@ -198,7 +198,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
user_self_ty: None, // not relevant here
|
||||
};
|
||||
|
||||
self.infcx.canonicalize_user_type_annotation(UserType::TypeOf(
|
||||
self.canonicalize_user_type_annotation(UserType::TypeOf(
|
||||
method.def_id,
|
||||
user_substs,
|
||||
))
|
||||
@ -236,7 +236,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
debug!("fcx {}", self.tag());
|
||||
|
||||
if Self::can_contain_user_lifetime_bounds((substs, user_self_ty)) {
|
||||
let canonicalized = self.infcx.canonicalize_user_type_annotation(UserType::TypeOf(
|
||||
let canonicalized = self.canonicalize_user_type_annotation(UserType::TypeOf(
|
||||
def_id,
|
||||
UserSubsts { substs, user_self_ty },
|
||||
));
|
||||
@ -480,7 +480,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
debug!("to_ty_saving_user_provided_ty: ty={:?}", ty);
|
||||
|
||||
if Self::can_contain_user_lifetime_bounds(ty) {
|
||||
let c_ty = self.infcx.canonicalize_response(UserType::Ty(ty));
|
||||
let c_ty = self.canonicalize_response(UserType::Ty(ty));
|
||||
debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty);
|
||||
self.typeck_results.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty);
|
||||
}
|
||||
@ -764,7 +764,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
if let ty::subst::GenericArgKind::Type(ty) = ty.unpack()
|
||||
&& let ty::Opaque(def_id, _) = *ty.kind()
|
||||
&& let Some(def_id) = def_id.as_local()
|
||||
&& self.infcx.opaque_type_origin(def_id, DUMMY_SP).is_some() {
|
||||
&& self.opaque_type_origin(def_id, DUMMY_SP).is_some() {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
@ -826,7 +826,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
} else {
|
||||
self.tcx.bound_type_of(def_id)
|
||||
};
|
||||
let substs = self.infcx.fresh_substs_for_item(span, def_id);
|
||||
let substs = self.fresh_substs_for_item(span, def_id);
|
||||
let ty = item_ty.subst(self.tcx, substs);
|
||||
|
||||
self.write_resolution(hir_id, Ok((def_kind, def_id)));
|
||||
|
@ -1520,21 +1520,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
/// ```
|
||||
fn get_expr_coercion_span(&self, expr: &hir::Expr<'_>) -> rustc_span::Span {
|
||||
let check_in_progress = |elem: &hir::Expr<'_>| {
|
||||
self.in_progress_typeck_results
|
||||
.and_then(|typeck_results| typeck_results.borrow().node_type_opt(elem.hir_id))
|
||||
.and_then(|ty| {
|
||||
if ty.is_never() {
|
||||
None
|
||||
} else {
|
||||
Some(match elem.kind {
|
||||
// Point at the tail expression when possible.
|
||||
hir::ExprKind::Block(block, _) => {
|
||||
block.expr.map_or(block.span, |e| e.span)
|
||||
}
|
||||
_ => elem.span,
|
||||
})
|
||||
}
|
||||
})
|
||||
self.typeck_results.borrow().node_type_opt(elem.hir_id).filter(|ty| !ty.is_never()).map(
|
||||
|_| match elem.kind {
|
||||
// Point at the tail expression when possible.
|
||||
hir::ExprKind::Block(block, _) => block.expr.map_or(block.span, |e| e.span),
|
||||
_ => elem.span,
|
||||
},
|
||||
)
|
||||
};
|
||||
|
||||
if let hir::ExprKind::If(_, _, Some(el)) = expr.kind {
|
||||
|
@ -343,7 +343,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
OP: FnOnce(ProbeContext<'a, 'tcx>) -> Result<R, MethodError<'tcx>>,
|
||||
{
|
||||
let mut orig_values = OriginalQueryValues::default();
|
||||
let param_env_and_self_ty = self.infcx.canonicalize_query(
|
||||
let param_env_and_self_ty = self.canonicalize_query(
|
||||
ParamEnvAnd { param_env: self.param_env, value: self_ty },
|
||||
&mut orig_values,
|
||||
);
|
||||
@ -351,7 +351,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let steps = if mode == Mode::MethodCall {
|
||||
self.tcx.method_autoderef_steps(param_env_and_self_ty)
|
||||
} else {
|
||||
self.infcx.probe(|_| {
|
||||
self.probe(|_| {
|
||||
// Mode::Path - the deref steps is "trivial". This turns
|
||||
// our CanonicalQuery into a "trivial" QueryResponse. This
|
||||
// is a bit inefficient, but I don't think that writing
|
||||
|
@ -865,27 +865,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
.join("\n");
|
||||
let actual_prefix = actual.prefix_string(self.tcx);
|
||||
info!("unimplemented_traits.len() == {}", unimplemented_traits.len());
|
||||
let (primary_message, label) = if unimplemented_traits.len() == 1
|
||||
&& unimplemented_traits_only
|
||||
{
|
||||
unimplemented_traits
|
||||
.into_iter()
|
||||
.next()
|
||||
.map(|(_, (trait_ref, obligation))| {
|
||||
if trait_ref.self_ty().references_error()
|
||||
|| actual.references_error()
|
||||
{
|
||||
// Avoid crashing.
|
||||
return (None, None);
|
||||
}
|
||||
let OnUnimplementedNote { message, label, .. } =
|
||||
self.infcx.on_unimplemented_note(trait_ref, &obligation);
|
||||
(message, label)
|
||||
})
|
||||
.unwrap_or((None, None))
|
||||
} else {
|
||||
(None, None)
|
||||
};
|
||||
let (primary_message, label) =
|
||||
if unimplemented_traits.len() == 1 && unimplemented_traits_only {
|
||||
unimplemented_traits
|
||||
.into_iter()
|
||||
.next()
|
||||
.map(|(_, (trait_ref, obligation))| {
|
||||
if trait_ref.self_ty().references_error()
|
||||
|| actual.references_error()
|
||||
{
|
||||
// Avoid crashing.
|
||||
return (None, None);
|
||||
}
|
||||
let OnUnimplementedNote { message, label, .. } =
|
||||
self.on_unimplemented_note(trait_ref, &obligation);
|
||||
(message, label)
|
||||
})
|
||||
.unwrap_or((None, None))
|
||||
} else {
|
||||
(None, None)
|
||||
};
|
||||
let primary_message = primary_message.unwrap_or_else(|| format!(
|
||||
"the {item_kind} `{item_name}` exists for {actual_prefix} `{ty_str}`, but its trait bounds were not satisfied"
|
||||
));
|
||||
@ -1648,7 +1647,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
call: &hir::Expr<'_>,
|
||||
span: Span,
|
||||
) {
|
||||
let output_ty = match self.infcx.get_impl_future_output_ty(ty) {
|
||||
let output_ty = match self.get_impl_future_output_ty(ty) {
|
||||
Some(output_ty) => self.resolve_vars_if_possible(output_ty).skip_binder(),
|
||||
_ => return,
|
||||
};
|
||||
|
@ -475,7 +475,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
suggest_deref_binop(lhs_deref_ty);
|
||||
} else if is_assign == IsAssign::No
|
||||
&& let Ref(_, lhs_deref_ty, _) = lhs_ty.kind() {
|
||||
if self.infcx.type_is_copy_modulo_regions(self.param_env, *lhs_deref_ty, lhs_expr.span) {
|
||||
if self.type_is_copy_modulo_regions(self.param_env, *lhs_deref_ty, lhs_expr.span) {
|
||||
suggest_deref_binop(*lhs_deref_ty);
|
||||
}
|
||||
}
|
||||
@ -523,7 +523,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
_ => None,
|
||||
};
|
||||
|
||||
self.infcx.suggest_restricting_param_bound(
|
||||
self.suggest_restricting_param_bound(
|
||||
&mut err,
|
||||
trait_pred,
|
||||
proj_pred,
|
||||
@ -740,7 +740,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
error.obligation.predicate.to_opt_poly_trait_pred()
|
||||
});
|
||||
for pred in predicates {
|
||||
self.infcx.suggest_restricting_param_bound(
|
||||
self.suggest_restricting_param_bound(
|
||||
&mut err,
|
||||
pred,
|
||||
None,
|
||||
|
@ -948,7 +948,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
let root_var_min_capture_list = min_captures.and_then(|m| m.get(&var_hir_id))?;
|
||||
|
||||
let ty = self.infcx.resolve_vars_if_possible(self.node_ty(var_hir_id));
|
||||
let ty = self.resolve_vars_if_possible(self.node_ty(var_hir_id));
|
||||
|
||||
let ty = match closure_clause {
|
||||
hir::CaptureBy::Value => ty, // For move closure the capture kind should be by value
|
||||
@ -1064,7 +1064,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
closure_clause: hir::CaptureBy,
|
||||
var_hir_id: hir::HirId,
|
||||
) -> Option<FxHashSet<UpvarMigrationInfo>> {
|
||||
let ty = self.infcx.resolve_vars_if_possible(self.node_ty(var_hir_id));
|
||||
let ty = self.resolve_vars_if_possible(self.node_ty(var_hir_id));
|
||||
|
||||
if !ty.has_significant_drop(self.tcx, self.tcx.param_env(closure_def_id.expect_local())) {
|
||||
debug!("does not have significant drop");
|
||||
|
@ -748,7 +748,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> {
|
||||
// (e.g. keep `for<'a>` named `for<'a>`).
|
||||
// This allows NLL to generate error messages that
|
||||
// refer to the higher-ranked lifetime names written by the user.
|
||||
EraseEarlyRegions { tcx: self.infcx.tcx }.fold_ty(t)
|
||||
EraseEarlyRegions { tcx: self.tcx }.fold_ty(t)
|
||||
}
|
||||
Err(_) => {
|
||||
debug!("Resolver::fold_ty: input type `{:?}` not fully resolvable", t);
|
||||
@ -766,7 +766,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> {
|
||||
|
||||
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
|
||||
match self.infcx.fully_resolve(ct) {
|
||||
Ok(ct) => self.infcx.tcx.erase_regions(ct),
|
||||
Ok(ct) => self.tcx.erase_regions(ct),
|
||||
Err(_) => {
|
||||
debug!("Resolver::fold_const: input const `{:?}` not fully resolvable", ct);
|
||||
self.report_const_error(ct);
|
||||
|
@ -244,7 +244,7 @@ pub struct UnconstrainedOpaqueType {
|
||||
pub struct MissingTypeParams {
|
||||
pub span: Span,
|
||||
pub def_span: Span,
|
||||
pub missing_type_params: Vec<String>,
|
||||
pub missing_type_params: Vec<Symbol>,
|
||||
pub empty_generic_args: bool,
|
||||
}
|
||||
|
||||
@ -285,7 +285,15 @@ impl<'a> SessionDiagnostic<'a> for MissingTypeParams {
|
||||
err.span_suggestion(
|
||||
self.span,
|
||||
rustc_errors::fluent::typeck::suggestion,
|
||||
format!("{}<{}>", snippet, self.missing_type_params.join(", ")),
|
||||
format!(
|
||||
"{}<{}>",
|
||||
snippet,
|
||||
self.missing_type_params
|
||||
.iter()
|
||||
.map(|n| n.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
),
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
suggested = true;
|
||||
|
@ -1126,6 +1126,19 @@ impl fmt::Debug for File {
|
||||
Some(PathBuf::from(OsString::from_vec(buf)))
|
||||
}
|
||||
|
||||
#[cfg(all(target_os = "freebsd", target_arch = "x86_64"))]
|
||||
fn get_path(fd: c_int) -> Option<PathBuf> {
|
||||
let info = Box::<libc::kinfo_file>::new_zeroed();
|
||||
let mut info = unsafe { info.assume_init() };
|
||||
info.kf_structsize = mem::size_of::<libc::kinfo_file>() as libc::c_int;
|
||||
let n = unsafe { libc::fcntl(fd, libc::F_KINFO, &mut *info) };
|
||||
if n == -1 {
|
||||
return None;
|
||||
}
|
||||
let buf = unsafe { CStr::from_ptr(info.kf_path.as_mut_ptr()).to_bytes().to_vec() };
|
||||
Some(PathBuf::from(OsString::from_vec(buf)))
|
||||
}
|
||||
|
||||
#[cfg(target_os = "vxworks")]
|
||||
fn get_path(fd: c_int) -> Option<PathBuf> {
|
||||
let mut buf = vec![0; libc::PATH_MAX as usize];
|
||||
@ -1142,6 +1155,7 @@ impl fmt::Debug for File {
|
||||
target_os = "linux",
|
||||
target_os = "macos",
|
||||
target_os = "vxworks",
|
||||
all(target_os = "freebsd", target_arch = "x86_64"),
|
||||
target_os = "netbsd"
|
||||
)))]
|
||||
fn get_path(_fd: c_int) -> Option<PathBuf> {
|
||||
|
@ -1,21 +1,28 @@
|
||||
1| |// Regression test for issue #98833.
|
||||
2| |// compile-flags: -Zinline-mir
|
||||
2| |// compile-flags: -Zinline-mir -Cdebug-assertions=off
|
||||
3| |
|
||||
4| 1|fn main() {
|
||||
5| 1| println!("{}", live::<false>());
|
||||
6| 1|}
|
||||
7| |
|
||||
8| |#[inline]
|
||||
9| 1|fn live<const B: bool>() -> u32 {
|
||||
10| 1| if B {
|
||||
11| 0| dead()
|
||||
12| | } else {
|
||||
13| 1| 0
|
||||
14| | }
|
||||
15| 1|}
|
||||
16| |
|
||||
17| |#[inline]
|
||||
18| 0|fn dead() -> u32 {
|
||||
19| 0| 42
|
||||
20| 0|}
|
||||
6| 1|
|
||||
7| 1| let f = |x: bool| {
|
||||
8| | debug_assert!(
|
||||
9| | x
|
||||
10| | );
|
||||
11| 1| };
|
||||
12| 1| f(false);
|
||||
13| 1|}
|
||||
14| |
|
||||
15| |#[inline]
|
||||
16| 1|fn live<const B: bool>() -> u32 {
|
||||
17| 1| if B {
|
||||
18| 0| dead()
|
||||
19| | } else {
|
||||
20| 1| 0
|
||||
21| | }
|
||||
22| 1|}
|
||||
23| |
|
||||
24| |#[inline]
|
||||
25| 0|fn dead() -> u32 {
|
||||
26| 0| 42
|
||||
27| 0|}
|
||||
|
||||
|
@ -1,8 +1,15 @@
|
||||
// Regression test for issue #98833.
|
||||
// compile-flags: -Zinline-mir
|
||||
// compile-flags: -Zinline-mir -Cdebug-assertions=off
|
||||
|
||||
fn main() {
|
||||
println!("{}", live::<false>());
|
||||
|
||||
let f = |x: bool| {
|
||||
debug_assert!(
|
||||
x
|
||||
);
|
||||
};
|
||||
f(false);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -5,7 +5,7 @@ trait Foo {
|
||||
|
||||
impl<'a> Foo for &'a () {
|
||||
const NAME: &'a str = "unit";
|
||||
//~^ ERROR mismatched types [E0308]
|
||||
//~^ ERROR const not compatible with trait
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,4 +1,4 @@
|
||||
error[E0308]: mismatched types
|
||||
error[E0308]: const not compatible with trait
|
||||
--> $DIR/associated-const-impl-wrong-lifetime.rs:7:5
|
||||
|
|
||||
LL | const NAME: &'a str = "unit";
|
||||
|
@ -11,13 +11,13 @@ LL | type Assoc2<T: std::fmt::Display> = Vec<T>;
|
||||
| +++++++++++++++++++
|
||||
|
||||
error[E0276]: impl has stricter requirements than trait
|
||||
--> $DIR/generic-associated-types-where.rs:22:5
|
||||
--> $DIR/generic-associated-types-where.rs:22:38
|
||||
|
|
||||
LL | type Assoc3<T>;
|
||||
| -------------- definition of `Assoc3` from trait
|
||||
...
|
||||
LL | type Assoc3<T> = Vec<T> where T: Iterator;
|
||||
| ^^^^^^^^^^^^^^ impl has extra requirement `T: Iterator`
|
||||
| ^^^^^^^^ impl has extra requirement `T: Iterator`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -13,9 +13,9 @@ struct Fooy<T>(T);
|
||||
|
||||
impl<T> Foo for Fooy<T> {
|
||||
type A<'a> = (&'a ()) where Self: 'static;
|
||||
//~^ ERROR `impl` associated type
|
||||
//~^ ERROR impl has stricter requirements than trait
|
||||
type B<'a, 'b> = (&'a(), &'b ()) where 'b: 'a;
|
||||
//~^ ERROR `impl` associated type
|
||||
//~^ ERROR impl has stricter requirements than trait
|
||||
//~| ERROR lifetime bound not satisfied
|
||||
type C = String where Self: Copy;
|
||||
//~^ ERROR the trait bound `T: Copy` is not satisfied
|
||||
|
@ -1,20 +1,20 @@
|
||||
error: `impl` associated type signature for `A` doesn't match `trait` associated type signature
|
||||
--> $DIR/impl_bounds.rs:15:5
|
||||
error[E0276]: impl has stricter requirements than trait
|
||||
--> $DIR/impl_bounds.rs:15:39
|
||||
|
|
||||
LL | type A<'a> where Self: 'a;
|
||||
| ---------- expected
|
||||
| ---------- definition of `A` from trait
|
||||
...
|
||||
LL | type A<'a> = (&'a ()) where Self: 'static;
|
||||
| ^^^^^^^^^^ found
|
||||
| ^^^^^^^ impl has extra requirement `T: 'static`
|
||||
|
||||
error: `impl` associated type signature for `B` doesn't match `trait` associated type signature
|
||||
--> $DIR/impl_bounds.rs:17:5
|
||||
error[E0276]: impl has stricter requirements than trait
|
||||
--> $DIR/impl_bounds.rs:17:48
|
||||
|
|
||||
LL | type B<'a, 'b> where 'a: 'b;
|
||||
| -------------- expected
|
||||
| -------------- definition of `B` from trait
|
||||
...
|
||||
LL | type B<'a, 'b> = (&'a(), &'b ()) where 'b: 'a;
|
||||
| ^^^^^^^^^^^^^^ found
|
||||
| ^^ impl has extra requirement `'b: 'a`
|
||||
|
||||
error[E0478]: lifetime bound not satisfied
|
||||
--> $DIR/impl_bounds.rs:17:22
|
||||
@ -37,24 +37,24 @@ LL | type B<'a, 'b> = (&'a(), &'b ()) where 'b: 'a;
|
||||
| ^^
|
||||
|
||||
error[E0277]: the trait bound `T: Copy` is not satisfied
|
||||
--> $DIR/impl_bounds.rs:20:5
|
||||
--> $DIR/impl_bounds.rs:20:33
|
||||
|
|
||||
LL | type C = String where Self: Copy;
|
||||
| ^^^^^^ the trait `Copy` is not implemented for `T`
|
||||
| ^^^^ the trait `Copy` is not implemented for `T`
|
||||
|
|
||||
note: required because of the requirements on the impl of `Copy` for `Fooy<T>`
|
||||
--> $DIR/impl_bounds.rs:11:10
|
||||
|
|
||||
LL | #[derive(Copy, Clone)]
|
||||
| ^^^^
|
||||
note: the requirement `Fooy<T>: Copy` appears on the associated impl type `C` but not on the corresponding associated trait type
|
||||
--> $DIR/impl_bounds.rs:7:5
|
||||
note: the requirement `Fooy<T>: Copy` appears on the `impl`'s associated type `C` but not on the corresponding trait's associated type
|
||||
--> $DIR/impl_bounds.rs:7:10
|
||||
|
|
||||
LL | trait Foo {
|
||||
| --- in this trait
|
||||
...
|
||||
LL | type C where Self: Clone;
|
||||
| ^^^^^^ this trait associated type doesn't have the requirement `Fooy<T>: Copy`
|
||||
| ^ this trait's associated type doesn't have the requirement `Fooy<T>: Copy`
|
||||
= note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider restricting type parameter `T`
|
||||
|
|
||||
@ -72,14 +72,14 @@ note: required because of the requirements on the impl of `Copy` for `Fooy<T>`
|
||||
|
|
||||
LL | #[derive(Copy, Clone)]
|
||||
| ^^^^
|
||||
note: the requirement `Fooy<T>: Copy` appears on the impl method `d` but not on the corresponding trait method
|
||||
note: the requirement `Fooy<T>: Copy` appears on the `impl`'s method `d` but not on the corresponding trait's method
|
||||
--> $DIR/impl_bounds.rs:8:8
|
||||
|
|
||||
LL | trait Foo {
|
||||
| --- in this trait
|
||||
...
|
||||
LL | fn d() where Self: Clone;
|
||||
| ^ this trait method doesn't have the requirement `Fooy<T>: Copy`
|
||||
| ^ this trait's method doesn't have the requirement `Fooy<T>: Copy`
|
||||
= note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider restricting type parameter `T`
|
||||
|
|
||||
@ -88,5 +88,5 @@ LL | impl<T: std::marker::Copy> Foo for Fooy<T> {
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0277, E0478.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
||||
Some errors have detailed explanations: E0276, E0277, E0478.
|
||||
For more information about an error, try `rustc --explain E0276`.
|
||||
|
@ -1,11 +1,11 @@
|
||||
error[E0276]: impl has stricter requirements than trait
|
||||
--> $DIR/issue-47206-where-clause.rs:12:5
|
||||
--> $DIR/issue-47206-where-clause.rs:12:38
|
||||
|
|
||||
LL | type Assoc3<T>;
|
||||
| -------------- definition of `Assoc3` from trait
|
||||
...
|
||||
LL | type Assoc3<T> = Vec<T> where T: Iterator;
|
||||
| ^^^^^^^^^^^^^^ impl has extra requirement `T: Iterator`
|
||||
| ^^^^^^^^ impl has extra requirement `T: Iterator`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -7,7 +7,7 @@ trait Foo {
|
||||
}
|
||||
impl Foo for () {
|
||||
type Assoc<'a, 'b> = () where 'a: 'b;
|
||||
//~^ `impl` associated type
|
||||
//~^ impl has stricter requirements than trait
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,11 +1,12 @@
|
||||
error: `impl` associated type signature for `Assoc` doesn't match `trait` associated type signature
|
||||
--> $DIR/missing-where-clause-on-trait.rs:9:5
|
||||
error[E0276]: impl has stricter requirements than trait
|
||||
--> $DIR/missing-where-clause-on-trait.rs:9:39
|
||||
|
|
||||
LL | type Assoc<'a, 'b>;
|
||||
| ------------------ expected
|
||||
| ------------------ definition of `Assoc` from trait
|
||||
...
|
||||
LL | type Assoc<'a, 'b> = () where 'a: 'b;
|
||||
| ^^^^^^^^^^^^^^^^^^ found
|
||||
| ^^ impl has extra requirement `'a: 'b`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0276`.
|
||||
|
@ -0,0 +1,17 @@
|
||||
// run-rustfix
|
||||
|
||||
macro_rules! my_wrapper {
|
||||
($expr:expr) => { MyWrapper($expr) }
|
||||
}
|
||||
|
||||
pub struct MyWrapper(u32);
|
||||
|
||||
fn main() {
|
||||
let value = MyWrapper(123);
|
||||
some_fn(value); //~ ERROR mismatched types
|
||||
some_fn(my_wrapper!(123)); //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn some_fn(wrapped: MyWrapper) {
|
||||
drop(wrapped);
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
// run-rustfix
|
||||
|
||||
macro_rules! my_wrapper {
|
||||
($expr:expr) => { MyWrapper($expr) }
|
||||
}
|
||||
|
||||
pub struct MyWrapper(u32);
|
||||
|
||||
fn main() {
|
||||
let value = MyWrapper(123);
|
||||
some_fn(value.0); //~ ERROR mismatched types
|
||||
some_fn(my_wrapper!(123).0); //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn some_fn(wrapped: MyWrapper) {
|
||||
drop(wrapped);
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/suggest-removing-tulpe-struct-field.rs:11:13
|
||||
|
|
||||
LL | some_fn(value.0);
|
||||
| ------- ^^^^^^^ expected struct `MyWrapper`, found `u32`
|
||||
| |
|
||||
| arguments to this function are incorrect
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/suggest-removing-tulpe-struct-field.rs:15:4
|
||||
|
|
||||
LL | fn some_fn(wrapped: MyWrapper) {
|
||||
| ^^^^^^^ ------------------
|
||||
help: consider removing the tuple struct field `0`
|
||||
|
|
||||
LL - some_fn(value.0);
|
||||
LL + some_fn(value);
|
||||
|
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/suggest-removing-tulpe-struct-field.rs:12:13
|
||||
|
|
||||
LL | some_fn(my_wrapper!(123).0);
|
||||
| ------- ^^^^^^^^^^^^^^^^^^ expected struct `MyWrapper`, found `u32`
|
||||
| |
|
||||
| arguments to this function are incorrect
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/suggest-removing-tulpe-struct-field.rs:15:4
|
||||
|
|
||||
LL | fn some_fn(wrapped: MyWrapper) {
|
||||
| ^^^^^^^ ------------------
|
||||
help: consider removing the tuple struct field `0`
|
||||
|
|
||||
LL - some_fn(my_wrapper!(123).0);
|
||||
LL + some_fn(my_wrapper!(123));
|
||||
|
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
@ -19,7 +19,7 @@ struct FailStruct { }
|
||||
|
||||
impl<'a: 'b, 'b, 'c> Anything<'a, 'b> for FailStruct {
|
||||
const AC: Option<&'c str> = None;
|
||||
//~^ ERROR: mismatched types
|
||||
//~^ ERROR: const not compatible with trait
|
||||
}
|
||||
|
||||
struct OKStruct2 { }
|
||||
|
@ -1,4 +1,4 @@
|
||||
error[E0308]: mismatched types
|
||||
error[E0308]: const not compatible with trait
|
||||
--> $DIR/trait-associated-constant.rs:21:5
|
||||
|
|
||||
LL | const AC: Option<&'c str> = None;
|
||||
|
@ -55,12 +55,13 @@ const EXCEPTIONS_CRANELIFT: &[(&str, &str)] = &[
|
||||
("cranelift-codegen-shared", "Apache-2.0 WITH LLVM-exception"),
|
||||
("cranelift-entity", "Apache-2.0 WITH LLVM-exception"),
|
||||
("cranelift-frontend", "Apache-2.0 WITH LLVM-exception"),
|
||||
("cranelift-isle", "Apache-2.0 WITH LLVM-exception"),
|
||||
("cranelift-jit", "Apache-2.0 WITH LLVM-exception"),
|
||||
("cranelift-module", "Apache-2.0 WITH LLVM-exception"),
|
||||
("cranelift-native", "Apache-2.0 WITH LLVM-exception"),
|
||||
("cranelift-object", "Apache-2.0 WITH LLVM-exception"),
|
||||
("mach", "BSD-2-Clause"),
|
||||
("regalloc", "Apache-2.0 WITH LLVM-exception"),
|
||||
("regalloc2", "Apache-2.0 WITH LLVM-exception"),
|
||||
("target-lexicon", "Apache-2.0 WITH LLVM-exception"),
|
||||
];
|
||||
|
||||
@ -258,10 +259,12 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[
|
||||
];
|
||||
|
||||
const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[
|
||||
"ahash",
|
||||
"anyhow",
|
||||
"ar",
|
||||
"autocfg",
|
||||
"bitflags",
|
||||
"byteorder",
|
||||
"cfg-if",
|
||||
"cranelift-bforest",
|
||||
"cranelift-codegen",
|
||||
@ -269,11 +272,14 @@ const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[
|
||||
"cranelift-codegen-shared",
|
||||
"cranelift-entity",
|
||||
"cranelift-frontend",
|
||||
"cranelift-isle",
|
||||
"cranelift-jit",
|
||||
"cranelift-module",
|
||||
"cranelift-native",
|
||||
"cranelift-object",
|
||||
"crc32fast",
|
||||
"fxhash",
|
||||
"getrandom",
|
||||
"gimli",
|
||||
"hashbrown",
|
||||
"indexmap",
|
||||
@ -284,11 +290,13 @@ const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[
|
||||
"memchr",
|
||||
"object",
|
||||
"once_cell",
|
||||
"regalloc",
|
||||
"regalloc2",
|
||||
"region",
|
||||
"rustc-hash",
|
||||
"slice-group-by",
|
||||
"smallvec",
|
||||
"target-lexicon",
|
||||
"version_check",
|
||||
"wasi",
|
||||
"winapi",
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
|
Loading…
x
Reference in New Issue
Block a user