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
74 changed files with 843 additions and 550 deletions
|
@ -850,13 +850,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
debug!("trait spans found: {:?}", traits);
|
debug!("trait spans found: {:?}", traits);
|
||||||
for span in &traits {
|
for span in &traits {
|
||||||
let mut multi_span: MultiSpan = vec![*span].into();
|
let mut multi_span: MultiSpan = vec![*span].into();
|
||||||
multi_span.push_span_label(
|
multi_span
|
||||||
*span,
|
.push_span_label(*span, "this has an implicit `'static` lifetime requirement");
|
||||||
"this has an implicit `'static` lifetime requirement".to_string(),
|
|
||||||
);
|
|
||||||
multi_span.push_span_label(
|
multi_span.push_span_label(
|
||||||
ident.span,
|
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_note(multi_span, "the used `impl` has a `'static` requirement");
|
||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
{
|
{
|
||||||
// source for rustc_* is not included in the rust-src component; disable the errors about this
|
// 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.diagnostics.disabled": ["unresolved-extern-crate", "unresolved-macro-call"],
|
||||||
"rust-analyzer.assist.importGranularity": "module",
|
"rust-analyzer.imports.granularity.enforce": true,
|
||||||
"rust-analyzer.assist.importEnforceGranularity": true,
|
"rust-analyzer.imports.granularity.group": "module",
|
||||||
"rust-analyzer.assist.importPrefix": "crate",
|
"rust-analyzer.imports.prefix": "crate",
|
||||||
"rust-analyzer.cargo.runBuildScripts": true,
|
|
||||||
"rust-analyzer.cargo.features": ["unstable-features"],
|
"rust-analyzer.cargo.features": ["unstable-features"],
|
||||||
"rust-analyzer.linkedProjects": [
|
"rust-analyzer.linkedProjects": [
|
||||||
"./Cargo.toml",
|
"./Cargo.toml",
|
||||||
|
|
|
@ -2,6 +2,17 @@
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
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]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.56"
|
version = "1.0.56"
|
||||||
|
@ -25,6 +36,12 @@ version = "1.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder"
|
||||||
|
version = "1.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
|
@ -33,56 +50,57 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-bforest"
|
name = "cranelift-bforest"
|
||||||
version = "0.83.0"
|
version = "0.85.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ed44413e7e2fe3260d0ed73e6956ab188b69c10ee92b892e401e0f4f6808c68b"
|
checksum = "749d0d6022c9038dccf480bdde2a38d435937335bf2bb0f14e815d94517cdce8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cranelift-entity",
|
"cranelift-entity",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-codegen"
|
name = "cranelift-codegen"
|
||||||
version = "0.83.0"
|
version = "0.85.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0b5d83f0f26bf213f971f45589d17e5b65e4861f9ed22392b0cbb6eaa5bd329c"
|
checksum = "e94370cc7b37bf652ccd8bb8f09bd900997f7ccf97520edfc75554bb5c4abbea"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cranelift-bforest",
|
"cranelift-bforest",
|
||||||
"cranelift-codegen-meta",
|
"cranelift-codegen-meta",
|
||||||
"cranelift-codegen-shared",
|
"cranelift-codegen-shared",
|
||||||
"cranelift-entity",
|
"cranelift-entity",
|
||||||
|
"cranelift-isle",
|
||||||
"gimli",
|
"gimli",
|
||||||
"log",
|
"log",
|
||||||
"regalloc",
|
"regalloc2",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"target-lexicon",
|
"target-lexicon",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-codegen-meta"
|
name = "cranelift-codegen-meta"
|
||||||
version = "0.83.0"
|
version = "0.85.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6800dc386177df6ecc5a32680607ed8ba1fa0d31a2a59c8c61fbf44826b8191d"
|
checksum = "e0a3cea8fdab90e44018c5b9a1dfd460d8ee265ac354337150222a354628bdb6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cranelift-codegen-shared",
|
"cranelift-codegen-shared",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-codegen-shared"
|
name = "cranelift-codegen-shared"
|
||||||
version = "0.83.0"
|
version = "0.85.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c961f85070985ebc8fcdb81b838a5cf842294d1e6ed4852446161c7e246fd455"
|
checksum = "5ac72f76f2698598951ab26d8c96eaa854810e693e7dd52523958b5909fde6b2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-entity"
|
name = "cranelift-entity"
|
||||||
version = "0.83.0"
|
version = "0.85.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2347b2b8d1d5429213668f2a8e36c85ee3c73984a2f6a79007e365d3e575e7ed"
|
checksum = "09eaeacfcd2356fe0e66b295e8f9d59fdd1ac3ace53ba50de14d628ec902f72d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-frontend"
|
name = "cranelift-frontend"
|
||||||
version = "0.83.0"
|
version = "0.85.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4cbcdbf7bed29e363568b778649b69dabc3d727256d5d25236096ef693757654"
|
checksum = "dba69c9980d5ffd62c18a2bde927855fcd7c8dc92f29feaf8636052662cbd99c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cranelift-codegen",
|
"cranelift-codegen",
|
||||||
"log",
|
"log",
|
||||||
|
@ -91,10 +109,16 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-jit"
|
name = "cranelift-isle"
|
||||||
version = "0.83.0"
|
version = "0.85.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
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 = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"cranelift-codegen",
|
"cranelift-codegen",
|
||||||
|
@ -110,9 +134,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-module"
|
name = "cranelift-module"
|
||||||
version = "0.83.0"
|
version = "0.85.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0ab57d399a2401074bb0cc40b3031e420f3d66d46ec0cf21eeae53ac04bd73e2"
|
checksum = "eee6784303bf9af235237a4885f7417e09a35df896d38ea969a0081064b3ede4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"cranelift-codegen",
|
"cranelift-codegen",
|
||||||
|
@ -120,9 +144,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-native"
|
name = "cranelift-native"
|
||||||
version = "0.83.0"
|
version = "0.85.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8f4cdf93552e5ceb2e3c042829ebb4de4378492705f769eadc6a7c6c5251624c"
|
checksum = "f04dfa45f9b2a6f587c564d6b63388e00cd6589d2df6ea2758cf79e1a13285e6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cranelift-codegen",
|
"cranelift-codegen",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -131,9 +155,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-object"
|
name = "cranelift-object"
|
||||||
version = "0.83.0"
|
version = "0.85.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf8e65f4839c26e6237fc0744911d79b0a2ac5e76b4e4eebd14db2b8d849fd31"
|
checksum = "0bf38b2c505db749276793116c0cb30bd096206c7810e471677a453134881881"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"cranelift-codegen",
|
"cranelift-codegen",
|
||||||
|
@ -152,6 +176,26 @@ dependencies = [
|
||||||
"cfg-if",
|
"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]]
|
[[package]]
|
||||||
name = "gimli"
|
name = "gimli"
|
||||||
version = "0.26.1"
|
version = "0.26.1"
|
||||||
|
@ -161,6 +205,15 @@ dependencies = [
|
||||||
"indexmap",
|
"indexmap",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.11.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
|
||||||
|
dependencies = [
|
||||||
|
"ahash",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.12.3"
|
version = "0.12.3"
|
||||||
|
@ -174,14 +227,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
|
checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"hashbrown",
|
"hashbrown 0.12.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.119"
|
version = "0.2.126"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4"
|
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libloading"
|
name = "libloading"
|
||||||
|
@ -219,11 +272,12 @@ checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "object"
|
name = "object"
|
||||||
version = "0.27.1"
|
version = "0.28.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "67ac1d3f9a1d3616fd9a60c8d74296f22406a238b6a72f5cc1e6f314df4ffbf9"
|
checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crc32fast",
|
"crc32fast",
|
||||||
|
"hashbrown 0.11.2",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
@ -235,13 +289,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
|
checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regalloc"
|
name = "regalloc2"
|
||||||
version = "0.0.34"
|
version = "0.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "62446b1d3ebf980bdc68837700af1d77b37bc430e524bf95319c6eada2a4cc02"
|
checksum = "4a8d23b35d7177df3b9d31ed8a9ab4bf625c668be77a319d4f5efd4a5257701c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"fxhash",
|
||||||
"log",
|
"log",
|
||||||
"rustc-hash",
|
"slice-group-by",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -257,12 +312,6 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustc-hash"
|
|
||||||
version = "1.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc_codegen_cranelift"
|
name = "rustc_codegen_cranelift"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -283,6 +332,12 @@ dependencies = [
|
||||||
"target-lexicon",
|
"target-lexicon",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "slice-group-by"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "03b634d87b960ab1a38c4fe143b508576f075e7c978bfad18217645ebfdfa2ec"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
version = "1.8.1"
|
version = "1.8.1"
|
||||||
|
@ -295,6 +350,18 @@ version = "0.12.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d7fa7e55043acb85fca6b3c01485a2eeb6b69c5d21002e273c79e465f43b7ac1"
|
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]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
|
|
|
@ -8,15 +8,15 @@ crate-type = ["dylib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# These have to be in sync with each other
|
# These have to be in sync with each other
|
||||||
cranelift-codegen = { version = "0.83.0", features = ["unwind", "all-arch"] }
|
cranelift-codegen = { version = "0.85.3", features = ["unwind", "all-arch"] }
|
||||||
cranelift-frontend = "0.83.0"
|
cranelift-frontend = "0.85.3"
|
||||||
cranelift-module = "0.83.0"
|
cranelift-module = "0.85.3"
|
||||||
cranelift-native = "0.83.0"
|
cranelift-native = "0.85.3"
|
||||||
cranelift-jit = { version = "0.83.0", optional = true }
|
cranelift-jit = { version = "0.85.3", optional = true }
|
||||||
cranelift-object = "0.83.0"
|
cranelift-object = "0.85.3"
|
||||||
target-lexicon = "0.12.0"
|
target-lexicon = "0.12.0"
|
||||||
gimli = { version = "0.26.0", default-features = false, features = ["write"]}
|
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" }
|
ar = { git = "https://github.com/bjorn3/rust-ar.git", branch = "do_not_remove_cg_clif_ranlib" }
|
||||||
indexmap = "1.9.1"
|
indexmap = "1.9.1"
|
||||||
|
|
|
@ -56,9 +56,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "compiler_builtins"
|
name = "compiler_builtins"
|
||||||
version = "0.1.72"
|
version = "0.1.75"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "afdbb35d279238cf77f0c9e8d90ad50d6c7bff476ab342baafa29440f0f10bff"
|
checksum = "c6e3183e88f659a862835db8f4b67dbeed3d93e44dd4927eef78edb1c149d784"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustc-std-workspace-core",
|
"rustc-std-workspace-core",
|
||||||
]
|
]
|
||||||
|
@ -112,9 +112,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.12.1"
|
version = "0.12.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3"
|
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"compiler_builtins",
|
"compiler_builtins",
|
||||||
"rustc-std-workspace-alloc",
|
"rustc-std-workspace-alloc",
|
||||||
|
@ -123,20 +123,21 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
version = "0.2.0"
|
version = "0.2.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1ab7905ea95c6d9af62940f9d7dd9596d54c334ae2c15300c482051292d5637f"
|
checksum = "7668753748e445859e4e373c3d41117235d9feed578392f5a3a73efdc751ca4a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"compiler_builtins",
|
"compiler_builtins",
|
||||||
"libc",
|
"libc",
|
||||||
|
"rustc-std-workspace-alloc",
|
||||||
"rustc-std-workspace-core",
|
"rustc-std-workspace-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.125"
|
version = "0.2.126"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b"
|
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustc-std-workspace-core",
|
"rustc-std-workspace-core",
|
||||||
]
|
]
|
||||||
|
|
|
@ -205,7 +205,7 @@ fn build_clif_sysroot_for_triple(
|
||||||
{
|
{
|
||||||
let entry = entry.unwrap();
|
let entry = entry.unwrap();
|
||||||
if let Some(ext) = entry.path().extension() {
|
if let Some(ext) = entry.path().extension() {
|
||||||
if ext == "rmeta" || ext == "d" || ext == "dSYM" {
|
if ext == "rmeta" || ext == "d" || ext == "dSYM" || ext == "clif" {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -458,7 +458,7 @@ pub trait FnMut<Args>: FnOnce<Args> {
|
||||||
|
|
||||||
#[lang = "panic"]
|
#[lang = "panic"]
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn panic(_msg: &str) -> ! {
|
pub fn panic(_msg: &'static str) -> ! {
|
||||||
unsafe {
|
unsafe {
|
||||||
libc::puts("Panicking\n\0" as *const str as *const i8);
|
libc::puts("Panicking\n\0" as *const str as *const i8);
|
||||||
intrinsics::abort();
|
intrinsics::abort();
|
||||||
|
@ -497,7 +497,7 @@ pub trait Deref {
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
#[rustc_layout_scalar_valid_range_start(1)]
|
#[rustc_layout_scalar_valid_range_start(1)]
|
||||||
#[rustc_nonnull_optimization_guaranteed]
|
#[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> 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> {}
|
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;
|
type Target = T;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
|
|
|
@ -124,6 +124,23 @@ fn call_return_u128_pair() {
|
||||||
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
|
#[allow(unreachable_code)] // FIXME false positive
|
||||||
fn main() {
|
fn main() {
|
||||||
take_unique(Unique {
|
take_unique(Unique {
|
||||||
|
@ -134,6 +151,20 @@ fn main() {
|
||||||
|
|
||||||
call_return_u128_pair();
|
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 = &[0, 1] as &[i32];
|
||||||
let slice_ptr = slice as *const [i32] as *const i32;
|
let slice_ptr = slice as *const [i32] as *const i32;
|
||||||
|
|
||||||
|
@ -299,6 +330,17 @@ fn main() {
|
||||||
static REF1: &u8 = &42;
|
static REF1: &u8 = &42;
|
||||||
static REF2: &u8 = REF1;
|
static REF2: &u8 = REF1;
|
||||||
assert_eq!(*REF1, *REF2);
|
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"))]
|
#[cfg(all(not(jit), target_arch = "x86_64", target_os = "linux"))]
|
||||||
|
|
|
@ -128,6 +128,25 @@ fn main() {
|
||||||
0 => loop {},
|
0 => loop {},
|
||||||
v => panic(v),
|
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) {
|
fn panic(_: u128) {
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
[toolchain]
|
[toolchain]
|
||||||
channel = "nightly-2022-05-15"
|
channel = "nightly-2022-07-25"
|
||||||
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]
|
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
|
index 8431aa7b818..a3ff7e68ce5 100644
|
||||||
--- a/src/tools/compiletest/src/runtest.rs
|
--- a/src/tools/compiletest/src/runtest.rs
|
||||||
+++ b/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
|
@@ -3489,12 +3489,7 @@ fn normalize_output(&self, output: &str, custom_rules: &[(String, String)]) -> S
|
||||||
.join("library");
|
let compiler_src_dir = base_dir.join("compiler");
|
||||||
normalize_path(&src_dir, "$(echo '$SRC_DIR')");
|
normalize_path(&compiler_src_dir, "$(echo '$COMPILER_DIR')");
|
||||||
|
|
||||||
- if let Some(virtual_rust_source_base_dir) =
|
- if let Some(virtual_rust_source_base_dir) =
|
||||||
- option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR").map(PathBuf::from)
|
- 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("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')");
|
+ normalize_path(&Path::new("$(cd ../build_sysroot/sysroot_src/library; pwd)"), "$(echo '$SRC_DIR')");
|
||||||
|
|
||||||
|
@ -62,3 +63,6 @@ deny-warnings = false
|
||||||
verbose-tests = false
|
verbose-tests = false
|
||||||
EOF
|
EOF
|
||||||
popd
|
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-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/async-await/async-fn-size-uninit-locals.rs # same
|
||||||
rm src/test/ui/generator/size-moved-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
|
# vendor intrinsics
|
||||||
rm src/test/ui/sse2.rs # cpuid not supported, so sse2 not detected
|
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/target-feature/missing-plusminus.rs # error not implemented
|
||||||
rm src/test/ui/fn/dyn-fn-alignment.rs # wants a 256 byte alignment
|
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 -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
|
# 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/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
|
rm -r src/test/run-make/fmt-write-bloat/ # tests an optimization
|
||||||
|
|
||||||
# backend specific tests
|
# 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/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/unstable-flag-required # same
|
||||||
rm -r src/test/run-make/rustdoc-* # 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
|
# genuine bugs
|
||||||
# ============
|
# ============
|
||||||
rm src/test/ui/allocator/no_std-alloc-error-handler-default.rs # missing rust_oom definition
|
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-neg1.rs # errors out for some reason
|
||||||
rm src/test/incremental/spike-neg2.rs # same
|
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
|
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/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/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
|
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"
|
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}
|
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 pass_mode;
|
||||||
mod returning;
|
mod returning;
|
||||||
|
|
||||||
|
use cranelift_module::ModuleError;
|
||||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||||
use rustc_middle::ty::layout::FnAbiOf;
|
use rustc_middle::ty::layout::FnAbiOf;
|
||||||
use rustc_target::abi::call::{Conv, FnAbi};
|
use rustc_target::abi::call::{Conv, FnAbi};
|
||||||
|
@ -69,7 +70,17 @@ pub(crate) fn import_function<'tcx>(
|
||||||
) -> FuncId {
|
) -> FuncId {
|
||||||
let name = tcx.symbol_name(inst).name;
|
let name = tcx.symbol_name(inst).name;
|
||||||
let sig = get_function_sig(tcx, module.isa().triple(), inst);
|
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> {
|
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();
|
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 mut arg_abis_iter = fn_abi.args.iter();
|
||||||
|
|
||||||
let func_params = fx
|
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)
|
RevealAllLayoutCx(fx.tcx).fn_abi_of_fn_ptr(fn_ty.fn_sig(fx.tcx), extra_args)
|
||||||
};
|
};
|
||||||
|
|
||||||
let is_cold = instance
|
let is_cold = if fn_sig.abi == Abi::RustCold {
|
||||||
.map(|inst| fx.tcx.codegen_fn_attrs(inst.def_id()).flags.contains(CodegenFnAttrFlags::COLD))
|
true
|
||||||
.unwrap_or(false);
|
} else {
|
||||||
|
instance
|
||||||
|
.map(|inst| {
|
||||||
|
fx.tcx.codegen_fn_attrs(inst.def_id()).flags.contains(CodegenFnAttrFlags::COLD)
|
||||||
|
})
|
||||||
|
.unwrap_or(false)
|
||||||
|
};
|
||||||
if is_cold {
|
if is_cold {
|
||||||
fx.bcx.set_cold_block(fx.bcx.current_block().unwrap());
|
fx.bcx.set_cold_block(fx.bcx.current_block().unwrap());
|
||||||
if let Some(destination_block) = target {
|
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()) {
|
let clif_ty = match (reg.kind, reg.size.bytes()) {
|
||||||
(RegKind::Integer, 1) => types::I8,
|
(RegKind::Integer, 1) => types::I8,
|
||||||
(RegKind::Integer, 2) => types::I16,
|
(RegKind::Integer, 2) => types::I16,
|
||||||
(RegKind::Integer, 4) => types::I32,
|
(RegKind::Integer, 3..=4) => types::I32,
|
||||||
(RegKind::Integer, 8) => types::I64,
|
(RegKind::Integer, 5..=8) => types::I64,
|
||||||
(RegKind::Integer, 16) => types::I128,
|
(RegKind::Integer, 9..=16) => types::I128,
|
||||||
(RegKind::Float, 4) => types::F32,
|
(RegKind::Float, 4) => types::F32,
|
||||||
(RegKind::Float, 8) => types::F64,
|
(RegKind::Float, 8) => types::F64,
|
||||||
(RegKind::Vector, size) => types::I8.by(u16::try_from(size).unwrap()).unwrap(),
|
(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()) {
|
// Note: Unlike the LLVM equivalent of this code we don't have separate branches for when there
|
||||||
// Simplify to a single unit when there is no prefix and size <= unit size
|
// is no prefix as a single unit, an array and a heterogeneous struct are not represented using
|
||||||
if cast.rest.total <= cast.rest.unit.size {
|
// different types in Cranelift IR. Instead a single array of primitive types is used.
|
||||||
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)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create list of fields in the main structure
|
// Create list of fields in the main structure
|
||||||
let mut args = cast
|
let mut args = cast
|
||||||
|
@ -230,7 +216,7 @@ pub(super) fn adjust_arg_for_abi<'tcx>(
|
||||||
arg_abi: &ArgAbi<'tcx, Ty<'tcx>>,
|
arg_abi: &ArgAbi<'tcx, Ty<'tcx>>,
|
||||||
is_owned: bool,
|
is_owned: bool,
|
||||||
) -> SmallVec<[Value; 2]> {
|
) -> 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 {
|
match arg_abi.mode {
|
||||||
PassMode::Ignore => smallvec![],
|
PassMode::Ignore => smallvec![],
|
||||||
PassMode::Direct(_) => smallvec![arg.load_scalar(fx)],
|
PassMode::Direct(_) => smallvec![arg.load_scalar(fx)],
|
||||||
|
|
|
@ -86,7 +86,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
|
||||||
|
|
||||||
let mut entries = Vec::new();
|
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
|
// 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.
|
// object files in memory at once, or read them twice.
|
||||||
let data = match entry {
|
let data = match entry {
|
||||||
|
@ -109,6 +109,23 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
if !self.no_builtin_ranlib {
|
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) {
|
match object::File::parse(&*data) {
|
||||||
Ok(object) => {
|
Ok(object) => {
|
||||||
symbol_table.insert(
|
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
|
// Define function
|
||||||
tcx.sess.time("define function", || {
|
tcx.sess.time("define function", || {
|
||||||
context.want_disasm = crate::pretty_clif::should_write_ir(tcx);
|
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
|
// Write optimized function to file for debugging
|
||||||
|
@ -815,16 +842,8 @@ pub(crate) fn codegen_place<'tcx>(
|
||||||
for elem in place.projection {
|
for elem in place.projection {
|
||||||
match elem {
|
match elem {
|
||||||
PlaceElem::Deref => {
|
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) => {
|
PlaceElem::Field(field, _ty) => {
|
||||||
cplace = cplace.place_field(fx, field);
|
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);
|
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);
|
let zero = fx.bcx.ins().iconst(to_ty, 0);
|
||||||
fx.bcx.ins().select(is_not_nan, val, zero)
|
fx.bcx.ins().select(is_not_nan, val, zero)
|
||||||
}
|
|
||||||
} else if from_ty.is_float() && to_ty.is_float() {
|
} else if from_ty.is_float() && to_ty.is_float() {
|
||||||
// float -> float
|
// float -> float
|
||||||
match (from_ty, to_ty) {
|
match (from_ty, to_ty) {
|
||||||
|
|
|
@ -328,14 +328,18 @@ fn data_id_for_static(
|
||||||
|
|
||||||
let attrs = tcx.codegen_fn_attrs(def_id);
|
let attrs = tcx.codegen_fn_attrs(def_id);
|
||||||
|
|
||||||
let data_id = module
|
let data_id = match module.declare_data(
|
||||||
.declare_data(
|
|
||||||
&*symbol_name,
|
&*symbol_name,
|
||||||
linkage,
|
linkage,
|
||||||
is_mutable,
|
is_mutable,
|
||||||
attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL),
|
attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL),
|
||||||
)
|
) {
|
||||||
.unwrap();
|
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() {
|
if rlinkage.is_some() {
|
||||||
// Comment copied from https://github.com/rust-lang/rust/blob/45060c2a66dfd667f88bd8b94261b28a58d85bd5/src/librustc_codegen_llvm/consts.rs#L141
|
// 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 {
|
let data_id = match reloc_target_alloc {
|
||||||
GlobalAlloc::Function(instance) => {
|
GlobalAlloc::Function(instance) => {
|
||||||
assert_eq!(addend, 0);
|
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);
|
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);
|
data_ctx.write_function_addr(offset.bytes() as u32, local_func_id);
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -18,6 +18,7 @@ pub(crate) fn codegen_inline_asm<'tcx>(
|
||||||
) {
|
) {
|
||||||
// FIXME add .eh_frame unwind info directives
|
// FIXME add .eh_frame unwind info directives
|
||||||
|
|
||||||
|
if !template.is_empty() {
|
||||||
if template[0] == InlineAsmTemplatePiece::String("int $$0x29".to_string()) {
|
if template[0] == InlineAsmTemplatePiece::String("int $$0x29".to_string()) {
|
||||||
let true_ = fx.bcx.ins().iconst(types::I32, 1);
|
let true_ = fx.bcx.ins().iconst(types::I32, 1);
|
||||||
fx.bcx.ins().trapnz(true_, TrapCode::User(1));
|
fx.bcx.ins().trapnz(true_, TrapCode::User(1));
|
||||||
|
@ -25,7 +26,11 @@ pub(crate) fn codegen_inline_asm<'tcx>(
|
||||||
} else if template[0] == InlineAsmTemplatePiece::String("movq %rbx, ".to_string())
|
} else if template[0] == InlineAsmTemplatePiece::String("movq %rbx, ".to_string())
|
||||||
&& matches!(
|
&& matches!(
|
||||||
template[1],
|
template[1],
|
||||||
InlineAsmTemplatePiece::Placeholder { operand_idx: 0, modifier: Some('r'), span: _ }
|
InlineAsmTemplatePiece::Placeholder {
|
||||||
|
operand_idx: 0,
|
||||||
|
modifier: Some('r'),
|
||||||
|
span: _
|
||||||
|
}
|
||||||
)
|
)
|
||||||
&& template[2] == InlineAsmTemplatePiece::String("\n".to_string())
|
&& template[2] == InlineAsmTemplatePiece::String("\n".to_string())
|
||||||
&& template[3] == InlineAsmTemplatePiece::String("cpuid".to_string())
|
&& template[3] == InlineAsmTemplatePiece::String("cpuid".to_string())
|
||||||
|
@ -33,7 +38,11 @@ pub(crate) fn codegen_inline_asm<'tcx>(
|
||||||
&& template[5] == InlineAsmTemplatePiece::String("xchgq %rbx, ".to_string())
|
&& template[5] == InlineAsmTemplatePiece::String("xchgq %rbx, ".to_string())
|
||||||
&& matches!(
|
&& matches!(
|
||||||
template[6],
|
template[6],
|
||||||
InlineAsmTemplatePiece::Placeholder { operand_idx: 0, modifier: Some('r'), span: _ }
|
InlineAsmTemplatePiece::Placeholder {
|
||||||
|
operand_idx: 0,
|
||||||
|
modifier: Some('r'),
|
||||||
|
span: _
|
||||||
|
}
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
assert_eq!(operands.len(), 4);
|
assert_eq!(operands.len(), 4);
|
||||||
|
@ -99,6 +108,7 @@ pub(crate) fn codegen_inline_asm<'tcx>(
|
||||||
} else if fx.tcx.symbol_name(fx.instance).name == "__alloca" {
|
} else if fx.tcx.symbol_name(fx.instance).name == "__alloca" {
|
||||||
crate::trap::trap_unimplemented(fx, "Alloca is not supported");
|
crate::trap::trap_unimplemented(fx, "Alloca is not supported");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let mut inputs = Vec::new();
|
let mut inputs = Vec::new();
|
||||||
let mut outputs = Vec::new();
|
let mut outputs = Vec::new();
|
||||||
|
|
|
@ -404,7 +404,9 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||||
};
|
};
|
||||||
size_of_val, (c ptr) {
|
size_of_val, (c ptr) {
|
||||||
let layout = fx.layout_of(substs.type_at(0));
|
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 (_ptr, info) = ptr.load_scalar_pair(fx);
|
||||||
let (size, _align) = crate::unsize::size_and_align_of_dst(fx, layout, info);
|
let (size, _align) = crate::unsize::size_and_align_of_dst(fx, layout, info);
|
||||||
size
|
size
|
||||||
|
@ -418,7 +420,9 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||||
};
|
};
|
||||||
min_align_of_val, (c ptr) {
|
min_align_of_val, (c ptr) {
|
||||||
let layout = fx.layout_of(substs.type_at(0));
|
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 (_ptr, info) = ptr.load_scalar_pair(fx);
|
||||||
let (_size, align) = crate::unsize::size_and_align_of_dst(fx, layout, info);
|
let (_size, align) = crate::unsize::size_and_align_of_dst(fx, layout, info);
|
||||||
align
|
align
|
||||||
|
@ -1145,6 +1149,20 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||||
// FIXME implement black_box semantics
|
// FIXME implement black_box semantics
|
||||||
ret.write_cvalue(fx, a);
|
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());
|
let ret_block = fx.get_block(destination.unwrap());
|
||||||
|
|
|
@ -141,7 +141,11 @@ impl<'tcx> CodegenCx<'tcx> {
|
||||||
|
|
||||||
let unwind_context =
|
let unwind_context =
|
||||||
UnwindContext::new(isa, matches!(backend_config.codegen_mode, CodegenMode::Aot));
|
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 {
|
CodegenCx {
|
||||||
tcx,
|
tcx,
|
||||||
global_asm: String::new(),
|
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
|
flags_builder.set("enable_probestack", "false").unwrap(); // __cranelift_probestack is not provided
|
||||||
let enable_verifier = if backend_config.enable_verifier { "true" } else { "false" };
|
let enable_verifier = if backend_config.enable_verifier { "true" } else { "false" };
|
||||||
flags_builder.set("enable_verifier", enable_verifier).unwrap();
|
flags_builder.set("enable_verifier", enable_verifier).unwrap();
|
||||||
|
flags_builder.set("regalloc_checker", enable_verifier).unwrap();
|
||||||
|
|
||||||
let tls_model = match target_triple.binary_format {
|
let tls_model = match target_triple.binary_format {
|
||||||
BinaryFormat::Elf => "elf_gd",
|
BinaryFormat::Elf => "elf_gd",
|
||||||
|
|
|
@ -109,7 +109,8 @@ pub(crate) fn maybe_create_entry_wrapper(
|
||||||
tcx.mk_substs([GenericArg::from(main_ret_ty)].iter()),
|
tcx.mk_substs([GenericArg::from(main_ret_ty)].iter()),
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.unwrap();
|
.unwrap()
|
||||||
|
.polymorphize(tcx);
|
||||||
|
|
||||||
let report_name = tcx.symbol_name(report).name;
|
let report_name = tcx.symbol_name(report).name;
|
||||||
let report_sig = get_function_sig(tcx, m.isa().triple(), report);
|
let report_sig = get_function_sig(tcx, m.isa().triple(), report);
|
||||||
|
|
|
@ -66,7 +66,7 @@ use rustc_session::config::OutputType;
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub(crate) struct CommentWriter {
|
pub(crate) struct CommentWriter {
|
||||||
enabled: bool,
|
enabled: bool,
|
||||||
global_comments: Vec<String>,
|
global_comments: Vec<String>,
|
||||||
|
@ -237,6 +237,7 @@ pub(crate) fn write_clif_file<'tcx>(
|
||||||
func: &cranelift_codegen::ir::Function,
|
func: &cranelift_codegen::ir::Function,
|
||||||
mut clif_comments: &CommentWriter,
|
mut clif_comments: &CommentWriter,
|
||||||
) {
|
) {
|
||||||
|
// FIXME work around filename too long errors
|
||||||
write_ir_file(
|
write_ir_file(
|
||||||
tcx,
|
tcx,
|
||||||
|| format!("{}.{}.clif", tcx.symbol_name(instance).name, postfix),
|
|| format!("{}.{}.clif", tcx.symbol_name(instance).name, postfix),
|
||||||
|
|
|
@ -153,11 +153,7 @@ pub(crate) fn size_and_align_of_dst<'tcx>(
|
||||||
layout: TyAndLayout<'tcx>,
|
layout: TyAndLayout<'tcx>,
|
||||||
info: Value,
|
info: Value,
|
||||||
) -> (Value, Value) {
|
) -> (Value, Value) {
|
||||||
if !layout.is_unsized() {
|
assert!(layout.is_unsized() || layout.abi == Abi::Uninhabited);
|
||||||
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);
|
|
||||||
}
|
|
||||||
match layout.ty.kind() {
|
match layout.ty.kind() {
|
||||||
ty::Dynamic(..) => {
|
ty::Dynamic(..) => {
|
||||||
// load size/align from vtable
|
// 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 {
|
let stack_slot = fx.bcx.create_stack_slot(StackSlotData {
|
||||||
kind: StackSlotKind::ExplicitSlot,
|
kind: StackSlotKind::ExplicitSlot,
|
||||||
// FIXME Don't force the size to a multiple of 16 bytes once Cranelift gets a way to
|
// 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>) {
|
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");
|
self.write_cvalue_maybe_transmute(fx, from, "write_cvalue");
|
||||||
}
|
}
|
||||||
|
@ -774,18 +780,25 @@ pub(crate) fn assert_assignable<'tcx>(
|
||||||
fx: &FunctionCx<'_, '_, 'tcx>,
|
fx: &FunctionCx<'_, '_, 'tcx>,
|
||||||
from_ty: Ty<'tcx>,
|
from_ty: Ty<'tcx>,
|
||||||
to_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()) {
|
match (from_ty.kind(), to_ty.kind()) {
|
||||||
(ty::Ref(_, a, _), ty::Ref(_, b, _))
|
(ty::Ref(_, a, _), ty::Ref(_, b, _))
|
||||||
| (
|
| (
|
||||||
ty::RawPtr(TypeAndMut { ty: a, mutbl: _ }),
|
ty::RawPtr(TypeAndMut { ty: a, mutbl: _ }),
|
||||||
ty::RawPtr(TypeAndMut { ty: b, 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::Ref(_, a, _), ty::RawPtr(TypeAndMut { ty: b, mutbl: _ }))
|
||||||
| (ty::RawPtr(TypeAndMut { ty: a, mutbl: _ }), ty::Ref(_, b, _)) => {
|
| (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(_)) => {
|
(ty::FnPtr(_), ty::FnPtr(_)) => {
|
||||||
let from_sig = fx.tcx.normalize_erasing_late_bound_regions(
|
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
|
// 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))
|
(&ty::Adt(adt_def_a, substs_a), &ty::Adt(adt_def_b, substs_b))
|
||||||
if adt_def_a.did() == adt_def_b.did() =>
|
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();
|
let mut types_b = substs_b.types();
|
||||||
loop {
|
loop {
|
||||||
match (types_a.next(), types_b.next()) {
|
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,
|
(None, None) => return,
|
||||||
(Some(_), None) | (None, Some(_)) => panic!("{:#?}/{:#?}", from_ty, to_ty),
|
(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!(
|
assert_eq!(
|
||||||
from_ty, to_ty,
|
from_ty,
|
||||||
|
to_ty,
|
||||||
"Can't write value with incompatible type {:?} to place with type {:?}\n\n{:#?}",
|
"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,
|
exp_span, exp_found.expected, exp_found.found,
|
||||||
);
|
);
|
||||||
|
|
||||||
if let ObligationCauseCode::CompareImplMethodObligation { .. } = cause.code() {
|
if let ObligationCauseCode::CompareImplItemObligation { .. } = cause.code() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2351,7 +2351,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
GenericKind::Projection(ref p) => format!("the associated type `{}`", p),
|
GenericKind::Projection(ref p) => format!("the associated type `{}`", p),
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(SubregionOrigin::CompareImplMethodObligation {
|
if let Some(SubregionOrigin::CompareImplItemObligation {
|
||||||
span,
|
span,
|
||||||
impl_item_def_id,
|
impl_item_def_id,
|
||||||
trait_item_def_id,
|
trait_item_def_id,
|
||||||
|
@ -2788,8 +2788,15 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
|
||||||
use self::FailureCode::*;
|
use self::FailureCode::*;
|
||||||
use crate::traits::ObligationCauseCode::*;
|
use crate::traits::ObligationCauseCode::*;
|
||||||
match self.code() {
|
match self.code() {
|
||||||
CompareImplMethodObligation { .. } => Error0308("method not compatible with trait"),
|
CompareImplItemObligation { kind: ty::AssocKind::Fn, .. } => {
|
||||||
CompareImplTypeObligation { .. } => Error0308("type not compatible with trait"),
|
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, .. }) => {
|
MatchExpressionArm(box MatchExpressionArmCause { source, .. }) => {
|
||||||
Error0308(match source {
|
Error0308(match source {
|
||||||
hir::MatchSource::TryDesugar => "`?` operator has incompatible types",
|
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 {
|
fn as_requirement_str(&self) -> &'static str {
|
||||||
use crate::traits::ObligationCauseCode::*;
|
use crate::traits::ObligationCauseCode::*;
|
||||||
match self.code() {
|
match self.code() {
|
||||||
CompareImplMethodObligation { .. } => "method type is compatible with trait",
|
CompareImplItemObligation { kind: ty::AssocKind::Fn, .. } => {
|
||||||
CompareImplTypeObligation { .. } => "associated type is compatible with trait",
|
"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",
|
ExprAssignable => "expression is assignable",
|
||||||
IfExpression { .. } => "`if` and `else` have incompatible types",
|
IfExpression { .. } => "`if` and `else` have incompatible types",
|
||||||
IfExpressionWithNoElse => "`if` missing an `else` returns `()`",
|
IfExpressionWithNoElse => "`if` missing an `else` returns `()`",
|
||||||
|
|
|
@ -2,17 +2,17 @@
|
||||||
|
|
||||||
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
|
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
|
||||||
use crate::infer::lexical_region_resolve::RegionResolutionError;
|
use crate::infer::lexical_region_resolve::RegionResolutionError;
|
||||||
use crate::infer::{SubregionOrigin, Subtype};
|
use crate::infer::Subtype;
|
||||||
use crate::traits::ObligationCauseCode::CompareImplMethodObligation;
|
use crate::traits::ObligationCauseCode::CompareImplItemObligation;
|
||||||
use rustc_errors::{ErrorGuaranteed, MultiSpan};
|
use rustc_errors::{ErrorGuaranteed, MultiSpan};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::Res;
|
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_hir::intravisit::Visitor;
|
||||||
use rustc_middle::hir::nested_filter;
|
use rustc_middle::hir::nested_filter;
|
||||||
use rustc_middle::ty::print::RegionHighlightMode;
|
use rustc_middle::ty::print::RegionHighlightMode;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor};
|
use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor};
|
||||||
use rustc_span::{Span, Symbol};
|
use rustc_span::Span;
|
||||||
|
|
||||||
use std::ops::ControlFlow;
|
use std::ops::ControlFlow;
|
||||||
|
|
||||||
|
@ -22,38 +22,22 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||||
let error = self.error.as_ref()?;
|
let error = self.error.as_ref()?;
|
||||||
debug!("try_report_impl_not_conforming_to_trait {:?}", error);
|
debug!("try_report_impl_not_conforming_to_trait {:?}", error);
|
||||||
if let RegionResolutionError::SubSupConflict(
|
if let RegionResolutionError::SubSupConflict(
|
||||||
_, var_origin, sub_origin, _sub, sup_origin, _sup, _,
|
_,
|
||||||
|
var_origin,
|
||||||
|
sub_origin,
|
||||||
|
_sub,
|
||||||
|
sup_origin,
|
||||||
|
_sup,
|
||||||
|
_,
|
||||||
) = error.clone()
|
) = error.clone()
|
||||||
&& let (&Subtype(ref sup_trace), &Subtype(ref sub_trace)) = (&sup_origin, &sub_origin)
|
&& let (Subtype(sup_trace), Subtype(sub_trace)) = (&sup_origin, &sub_origin)
|
||||||
&& let (
|
&& let sub_expected_found @ Some((sub_expected, sub_found)) = sub_trace.values.ty()
|
||||||
sub_expected_found @ Some((sub_expected, sub_found)),
|
&& let sup_expected_found @ Some(_) = sup_trace.values.ty()
|
||||||
sup_expected_found @ Some(_),
|
&& let CompareImplItemObligation { trait_item_def_id, .. } = sub_trace.cause.code()
|
||||||
CompareImplMethodObligation { trait_item_def_id, .. },
|
|
||||||
) = (sub_trace.values.ty(), sup_trace.values.ty(), sub_trace.cause.code())
|
|
||||||
&& sup_expected_found == sub_expected_found
|
&& sup_expected_found == sub_expected_found
|
||||||
{
|
{
|
||||||
let guar = self.emit_err(
|
let guar =
|
||||||
var_origin.span(),
|
self.emit_err(var_origin.span(), sub_expected, sub_found, *trait_item_def_id);
|
||||||
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,
|
|
||||||
);
|
|
||||||
return Some(guar);
|
return Some(guar);
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
|
@ -147,25 +131,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
err.emit()
|
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> {
|
struct TypeParamSpanVisitor<'tcx> {
|
||||||
|
|
|
@ -86,13 +86,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
"...so that the declared lifetime parameter bounds are satisfied",
|
"...so that the declared lifetime parameter bounds are satisfied",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
infer::CompareImplMethodObligation { span, .. } => {
|
infer::CompareImplItemObligation { span, .. } => {
|
||||||
label_or_note(
|
|
||||||
span,
|
|
||||||
"...so that the definition in impl matches the definition from the trait",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
infer::CompareImplTypeObligation { span, .. } => {
|
|
||||||
label_or_note(
|
label_or_note(
|
||||||
span,
|
span,
|
||||||
"...so that the definition in impl matches the definition from the trait",
|
"...so that the definition in impl matches the definition from the trait",
|
||||||
|
@ -329,15 +323,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
);
|
);
|
||||||
err
|
err
|
||||||
}
|
}
|
||||||
infer::CompareImplMethodObligation { span, impl_item_def_id, trait_item_def_id } => {
|
infer::CompareImplItemObligation { span, impl_item_def_id, trait_item_def_id } => self
|
||||||
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
|
|
||||||
.report_extra_impl_obligation(
|
.report_extra_impl_obligation(
|
||||||
span,
|
span,
|
||||||
impl_item_def_id,
|
impl_item_def_id,
|
||||||
|
|
|
@ -405,15 +405,7 @@ pub enum SubregionOrigin<'tcx> {
|
||||||
|
|
||||||
/// Comparing the signature and requirements of an impl method against
|
/// Comparing the signature and requirements of an impl method against
|
||||||
/// the containing trait.
|
/// the containing trait.
|
||||||
CompareImplMethodObligation {
|
CompareImplItemObligation { span: Span, impl_item_def_id: LocalDefId, trait_item_def_id: DefId },
|
||||||
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 },
|
|
||||||
|
|
||||||
/// Checking that the bounds of a trait's associated type hold for a given impl
|
/// Checking that the bounds of a trait's associated type hold for a given impl
|
||||||
CheckAssociatedTypeBounds {
|
CheckAssociatedTypeBounds {
|
||||||
|
@ -1945,8 +1937,7 @@ impl<'tcx> SubregionOrigin<'tcx> {
|
||||||
ReborrowUpvar(a, _) => a,
|
ReborrowUpvar(a, _) => a,
|
||||||
DataBorrowed(_, a) => a,
|
DataBorrowed(_, a) => a,
|
||||||
ReferenceOutlivesReferent(_, a) => a,
|
ReferenceOutlivesReferent(_, a) => a,
|
||||||
CompareImplMethodObligation { span, .. } => span,
|
CompareImplItemObligation { span, .. } => span,
|
||||||
CompareImplTypeObligation { span, .. } => span,
|
|
||||||
CheckAssociatedTypeBounds { ref parent, .. } => parent.span(),
|
CheckAssociatedTypeBounds { ref parent, .. } => parent.span(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1960,19 +1951,11 @@ impl<'tcx> SubregionOrigin<'tcx> {
|
||||||
SubregionOrigin::ReferenceOutlivesReferent(ref_type, cause.span)
|
SubregionOrigin::ReferenceOutlivesReferent(ref_type, cause.span)
|
||||||
}
|
}
|
||||||
|
|
||||||
traits::ObligationCauseCode::CompareImplMethodObligation {
|
traits::ObligationCauseCode::CompareImplItemObligation {
|
||||||
impl_item_def_id,
|
impl_item_def_id,
|
||||||
trait_item_def_id,
|
trait_item_def_id,
|
||||||
} => SubregionOrigin::CompareImplMethodObligation {
|
kind: _,
|
||||||
span: cause.span,
|
} => SubregionOrigin::CompareImplItemObligation {
|
||||||
impl_item_def_id,
|
|
||||||
trait_item_def_id,
|
|
||||||
},
|
|
||||||
|
|
||||||
traits::ObligationCauseCode::CompareImplTypeObligation {
|
|
||||||
impl_item_def_id,
|
|
||||||
trait_item_def_id,
|
|
||||||
} => SubregionOrigin::CompareImplTypeObligation {
|
|
||||||
span: cause.span,
|
span: cause.span,
|
||||||
impl_item_def_id,
|
impl_item_def_id,
|
||||||
trait_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
|
/// Error derived when matching traits/impls; see ObligationCause for more details
|
||||||
CompareImplConstObligation,
|
CompareImplItemObligation {
|
||||||
|
|
||||||
/// 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 {
|
|
||||||
impl_item_def_id: LocalDefId,
|
impl_item_def_id: LocalDefId,
|
||||||
trait_item_def_id: DefId,
|
trait_item_def_id: DefId,
|
||||||
|
kind: ty::AssocKind,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Checking that the bounds of a trait's associated type hold for a given impl
|
/// 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.
|
/// 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
|
/// 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(..), .. }),
|
| hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(..), .. }),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
let impl_comparison = matches!(
|
let impl_comparison =
|
||||||
cause_code,
|
matches!(cause_code, ObligationCauseCode::CompareImplItemObligation { .. });
|
||||||
ObligationCauseCode::CompareImplMethodObligation { .. }
|
|
||||||
| ObligationCauseCode::CompareImplTypeObligation { .. }
|
|
||||||
| ObligationCauseCode::CompareImplConstObligation
|
|
||||||
);
|
|
||||||
let assoc = self.associated_item(proj_ty.item_def_id);
|
let assoc = self.associated_item(proj_ty.item_def_id);
|
||||||
if !callable_scope || impl_comparison {
|
if !callable_scope || impl_comparison {
|
||||||
// We do not want to suggest calling functions when the reason of the
|
// We do not want to suggest calling functions when the reason of the
|
||||||
|
|
|
@ -224,6 +224,7 @@ TrivialTypeTraversalAndLiftImpls! {
|
||||||
// general `Region`.
|
// general `Region`.
|
||||||
crate::ty::BoundRegionKind,
|
crate::ty::BoundRegionKind,
|
||||||
crate::ty::AssocItem,
|
crate::ty::AssocItem,
|
||||||
|
crate::ty::AssocKind,
|
||||||
crate::ty::Placeholder<crate::ty::BoundRegionKind>,
|
crate::ty::Placeholder<crate::ty::BoundRegionKind>,
|
||||||
crate::ty::ClosureKind,
|
crate::ty::ClosureKind,
|
||||||
crate::ty::FreeRegion,
|
crate::ty::FreeRegion,
|
||||||
|
|
|
@ -951,7 +951,7 @@ fn adt_defined_here<'p, 'tcx>(
|
||||||
let mut span: MultiSpan =
|
let mut span: MultiSpan =
|
||||||
if spans.is_empty() { def_span.into() } else { spans.clone().into() };
|
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 {
|
for pat in spans {
|
||||||
span.push_span_label(pat, "not covered");
|
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.
|
/// with `0` executions.
|
||||||
///
|
///
|
||||||
/// If there are no live `Counter` `Coverage` statements remaining, we remove
|
/// 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
|
/// counter per function is required by LLVM (and necessary, to add the
|
||||||
/// `function_hash` to the counter's call to the LLVM intrinsic
|
/// `function_hash` to the counter's call to the LLVM intrinsic
|
||||||
/// `instrprof.increment()`).
|
/// `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() {
|
if live.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -565,8 +565,7 @@ impl<'a> Resolver<'a> {
|
||||||
} else if let Some(sp) = sm.generate_fn_name_span(span) {
|
} else if let Some(sp) = sm.generate_fn_name_span(span) {
|
||||||
err.span_label(
|
err.span_label(
|
||||||
sp,
|
sp,
|
||||||
"try adding a local generic parameter in this method instead"
|
"try adding a local generic parameter in this method instead",
|
||||||
.to_string(),
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
err.help("try using a local generic parameter instead");
|
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 {
|
pub fn is_span_accessible(&self, sp: Span) -> bool {
|
||||||
self.span_to_source(sp, |src, start_index, end_index| {
|
self.span_to_source(sp, |src, start_index, end_index| {
|
||||||
Ok(src.get(start_index..end_index).is_some())
|
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;
|
span = obligation.cause.span;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let ObligationCauseCode::CompareImplMethodObligation {
|
if let ObligationCauseCode::CompareImplItemObligation {
|
||||||
impl_item_def_id,
|
|
||||||
trait_item_def_id,
|
|
||||||
}
|
|
||||||
| ObligationCauseCode::CompareImplTypeObligation {
|
|
||||||
impl_item_def_id,
|
impl_item_def_id,
|
||||||
trait_item_def_id,
|
trait_item_def_id,
|
||||||
|
kind: _,
|
||||||
} = *obligation.cause.code()
|
} = *obligation.cause.code()
|
||||||
{
|
{
|
||||||
self.report_extra_impl_obligation(
|
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 item_name = self.tcx.item_name(trait_item_def_id);
|
||||||
let msg = format!(
|
let msg = format!(
|
||||||
"the requirement `{}` appears on the impl method `{}` but not on the \
|
"the requirement `{}` appears on the `impl`'s {kind} `{}` but not on the \
|
||||||
corresponding trait method",
|
corresponding trait's {kind}",
|
||||||
predicate, item_name,
|
predicate, item_name,
|
||||||
);
|
);
|
||||||
let sp = self
|
let sp = self
|
||||||
|
@ -2697,7 +2697,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
let mut assoc_span: MultiSpan = sp.into();
|
let mut assoc_span: MultiSpan = sp.into();
|
||||||
assoc_span.push_span_label(
|
assoc_span.push_span_label(
|
||||||
sp,
|
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
|
if let Some(ident) = self
|
||||||
.tcx
|
.tcx
|
||||||
|
@ -2708,38 +2708,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
err.span_note(assoc_span, &msg);
|
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 => {
|
ObligationCauseCode::TrivialBound => {
|
||||||
err.help("see issue #48214");
|
err.help("see issue #48214");
|
||||||
if tcx.sess.opts.unstable_features.is_nightly_build() {
|
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_session::parse::feature_err;
|
||||||
use rustc_span::lev_distance::find_best_match_for_name;
|
use rustc_span::lev_distance::find_best_match_for_name;
|
||||||
use rustc_span::symbol::{sym, Ident};
|
use rustc_span::symbol::{sym, Ident};
|
||||||
use rustc_span::{Span, DUMMY_SP};
|
use rustc_span::{Span, Symbol, DUMMY_SP};
|
||||||
|
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
/// the type parameter's name as a placeholder.
|
/// the type parameter's name as a placeholder.
|
||||||
pub(crate) fn complain_about_missing_type_params(
|
pub(crate) fn complain_about_missing_type_params(
|
||||||
&self,
|
&self,
|
||||||
missing_type_params: Vec<String>,
|
missing_type_params: Vec<Symbol>,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
span: Span,
|
span: Span,
|
||||||
empty_generic_args: bool,
|
empty_generic_args: bool,
|
||||||
|
|
|
@ -382,7 +382,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
generic_args: &'a GenericArgs<'a>,
|
generic_args: &'a GenericArgs<'a>,
|
||||||
span: Span,
|
span: Span,
|
||||||
missing_type_params: Vec<String>,
|
missing_type_params: Vec<Symbol>,
|
||||||
inferred_params: Vec<Span>,
|
inferred_params: Vec<Span>,
|
||||||
infer_args: bool,
|
infer_args: bool,
|
||||||
is_object: 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
|
// defaults. This will lead to an ICE if we are not
|
||||||
// careful!
|
// careful!
|
||||||
if self.default_needs_object_self(param) {
|
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()
|
tcx.ty_error().into()
|
||||||
} else {
|
} else {
|
||||||
// This is a default type parameter.
|
// This is a default type parameter.
|
||||||
|
@ -1150,17 +1150,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
.expect("missing associated type");
|
.expect("missing associated type");
|
||||||
|
|
||||||
if !assoc_item.vis.is_accessible_from(def_scope, tcx) {
|
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
|
tcx.sess
|
||||||
.struct_span_err(
|
.struct_span_err(
|
||||||
binding.span,
|
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();
|
.emit();
|
||||||
}
|
}
|
||||||
tcx.check_stability(assoc_item.def_id, Some(hir_ref_id), binding.span, None);
|
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 {
|
ty::Binder::dummy(ty::PredicateKind::Trait(ty::TraitPredicate {
|
||||||
trait_ref: ty::TraitRef {
|
trait_ref: ty::TraitRef {
|
||||||
def_id: t.def_id(),
|
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,
|
constness: t.constness,
|
||||||
polarity: t.polarity,
|
polarity: t.polarity,
|
||||||
|
@ -496,9 +496,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let obl = Obligation::new(
|
let obl = Obligation::new(
|
||||||
o.cause.clone(),
|
o.cause.clone(),
|
||||||
self.param_env,
|
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 {
|
if !suggest_box {
|
||||||
// We've encountered some obligation that didn't hold, so the
|
// We've encountered some obligation that didn't hold, so the
|
||||||
// return expression can't just be boxed. We don't need to
|
// 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,
|
self.param_env,
|
||||||
*predicate,
|
*predicate,
|
||||||
);
|
);
|
||||||
let result = self.infcx.evaluate_obligation(&obligation);
|
let result = self.evaluate_obligation(&obligation);
|
||||||
self.tcx
|
self.tcx
|
||||||
.sess
|
.sess
|
||||||
.struct_span_err(
|
.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()),
|
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,
|
kind: TypeVariableOriginKind::ClosureSynthetic,
|
||||||
span: self.tcx.hir().span(expr.hir_id),
|
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.
|
// Create a type variable (for now) to represent the closure kind.
|
||||||
// It will be unified during the upvar inference phase (`upvar.rs`)
|
// 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.
|
// FIXME(eddyb) distinguish closure kind inference variables from the rest.
|
||||||
kind: TypeVariableOriginKind::ClosureSynthetic,
|
kind: TypeVariableOriginKind::ClosureSynthetic,
|
||||||
span: expr.span,
|
span: expr.span,
|
||||||
|
@ -531,7 +531,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
//
|
//
|
||||||
// [c1]: https://github.com/rust-lang/rust/pull/45072#issuecomment-341089706
|
// [c1]: https://github.com/rust-lang/rust/pull/45072#issuecomment-341089706
|
||||||
// [c2]: https://github.com/rust-lang/rust/pull/45072#issuecomment-341096796
|
// [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![];
|
let mut all_obligations = vec![];
|
||||||
|
|
||||||
// The liberated version of this signature should be a subtype
|
// 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'.
|
expected_sigs.liberated_sig.inputs(), // `liberated_sig` is E'.
|
||||||
) {
|
) {
|
||||||
// Instantiate (this part of..) S to S', i.e., with fresh variables.
|
// 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,
|
hir_ty.span,
|
||||||
LateBoundRegionConversionTime::FnCall,
|
LateBoundRegionConversionTime::FnCall,
|
||||||
supplied_sig.inputs().rebind(supplied_ty),
|
supplied_sig.inputs().rebind(supplied_ty),
|
||||||
|
@ -557,7 +557,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
all_obligations.extend(obligations);
|
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(),
|
decl.output.span(),
|
||||||
LateBoundRegionConversionTime::FnCall,
|
LateBoundRegionConversionTime::FnCall,
|
||||||
supplied_sig.output(),
|
supplied_sig.output(),
|
||||||
|
|
|
@ -241,13 +241,13 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||||
make_adjustments: impl FnOnce(Ty<'tcx>) -> Vec<Adjustment<'tcx>>,
|
make_adjustments: impl FnOnce(Ty<'tcx>) -> Vec<Adjustment<'tcx>>,
|
||||||
) -> CoerceResult<'tcx> {
|
) -> CoerceResult<'tcx> {
|
||||||
debug!("coerce_from_inference_variable(a={:?}, b={:?})", a, b);
|
debug!("coerce_from_inference_variable(a={:?}, b={:?})", a, b);
|
||||||
assert!(a.is_ty_var() && self.infcx.shallow_resolve(a) == a);
|
assert!(a.is_ty_var() && self.shallow_resolve(a) == a);
|
||||||
assert!(self.infcx.shallow_resolve(b) == b);
|
assert!(self.shallow_resolve(b) == b);
|
||||||
|
|
||||||
if b.is_ty_var() {
|
if b.is_ty_var() {
|
||||||
// Two unresolved type variables: create a `Coerce` predicate.
|
// Two unresolved type variables: create a `Coerce` predicate.
|
||||||
let target_ty = if self.use_lub {
|
let target_ty = if self.use_lub {
|
||||||
self.infcx.next_ty_var(TypeVariableOrigin {
|
self.next_ty_var(TypeVariableOrigin {
|
||||||
kind: TypeVariableOriginKind::LatticeVariable,
|
kind: TypeVariableOriginKind::LatticeVariable,
|
||||||
span: self.cause.span,
|
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.autoderef(rustc_span::DUMMY_SP, expr_ty).nth(1).and_then(|(deref_ty, _)| {
|
||||||
self.infcx
|
self.infcx
|
||||||
.type_implements_trait(
|
.type_implements_trait(
|
||||||
self.infcx.tcx.lang_items().deref_mut_trait()?,
|
self.tcx.lang_items().deref_mut_trait()?,
|
||||||
expr_ty,
|
expr_ty,
|
||||||
ty::List::empty(),
|
ty::List::empty(),
|
||||||
self.param_env,
|
self.param_env,
|
||||||
|
|
|
@ -90,9 +90,10 @@ fn compare_predicate_entailment<'tcx>(
|
||||||
let mut cause = ObligationCause::new(
|
let mut cause = ObligationCause::new(
|
||||||
impl_m_span,
|
impl_m_span,
|
||||||
impl_m_hir_id,
|
impl_m_hir_id,
|
||||||
ObligationCauseCode::CompareImplMethodObligation {
|
ObligationCauseCode::CompareImplItemObligation {
|
||||||
impl_item_def_id: impl_m.def_id.expect_local(),
|
impl_item_def_id: impl_m.def_id.expect_local(),
|
||||||
trait_item_def_id: trait_m.def_id,
|
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(
|
let cause = ObligationCause::new(
|
||||||
span,
|
span,
|
||||||
impl_m_hir_id,
|
impl_m_hir_id,
|
||||||
ObligationCauseCode::CompareImplMethodObligation {
|
ObligationCauseCode::CompareImplItemObligation {
|
||||||
impl_item_def_id: impl_m.def_id.expect_local(),
|
impl_item_def_id: impl_m.def_id.expect_local(),
|
||||||
trait_item_def_id: trait_m.def_id,
|
trait_item_def_id: trait_m.def_id,
|
||||||
|
kind: impl_m.kind,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
ocx.register_obligation(traits::Obligation::new(cause, param_env, predicate));
|
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(
|
let mut cause = ObligationCause::new(
|
||||||
impl_c_span,
|
impl_c_span,
|
||||||
impl_c_hir_id,
|
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.
|
// 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
|
// `ObligationCause` (and the `FnCtxt`). This is what
|
||||||
// `regionck_item` expects.
|
// `regionck_item` expects.
|
||||||
let impl_ty_hir_id = tcx.hir().local_def_id_to_hir_id(impl_ty.def_id.expect_local());
|
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);
|
debug!("compare_type_predicate_entailment: trait_to_impl_substs={:?}", trait_to_impl_substs);
|
||||||
|
|
||||||
// The predicates declared by the impl definition, the trait and the
|
// The predicates declared by the impl definition, the trait and the
|
||||||
|
@ -1239,7 +1236,7 @@ fn compare_type_predicate_entailment<'tcx>(
|
||||||
Reveal::UserFacing,
|
Reveal::UserFacing,
|
||||||
hir::Constness::NotConst,
|
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| {
|
tcx.infer_ctxt().enter(|infcx| {
|
||||||
let ocx = ObligationCtxt::new(&infcx);
|
let ocx = ObligationCtxt::new(&infcx);
|
||||||
|
|
||||||
|
@ -1247,12 +1244,25 @@ fn compare_type_predicate_entailment<'tcx>(
|
||||||
|
|
||||||
let mut selcx = traits::SelectionContext::new(&infcx);
|
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 } =
|
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_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
|
// Check that all obligations are satisfied by the implementation's
|
||||||
|
|
|
@ -287,6 +287,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
expr_ty: Ty<'tcx>,
|
expr_ty: Ty<'tcx>,
|
||||||
) {
|
) {
|
||||||
if let ty::Adt(expected_adt, substs) = expected.kind() {
|
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,
|
// If the expression is of type () and it's the return expression of a block,
|
||||||
// we suggest adding a separate return expression instead.
|
// we suggest adding a separate return expression instead.
|
||||||
// (To avoid things like suggesting `Ok(while .. { .. })`.)
|
// (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),
|
hir::ExprKind::AddrOf(hir::BorrowKind::Ref, _, ref expr),
|
||||||
_,
|
_,
|
||||||
&ty::Ref(_, checked, _),
|
&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 have `&T`, check if what was expected was `T`. If so,
|
||||||
// we may want to suggest removing a `&`.
|
// we may want to suggest removing a `&`.
|
||||||
if sm.is_imported(expr.span) {
|
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`,
|
// For this suggestion to make sense, the type would need to be `Copy`,
|
||||||
// or we have to be moving out of a `Box<T>`
|
// 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
|
// 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.
|
// `steps` layers of boxes, not just one, but this is easier and most likely.
|
||||||
|| (checked_ty.is_box() && steps == 1)
|
|| (checked_ty.is_box() && steps == 1)
|
||||||
|
|
|
@ -2235,7 +2235,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
base: &'tcx hir::Expr<'tcx>,
|
base: &'tcx hir::Expr<'tcx>,
|
||||||
ty: Ty<'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),
|
Some(output_ty) => self.resolve_vars_if_possible(output_ty),
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
|
|
|
@ -218,9 +218,9 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
|
||||||
.diverging_type_vars
|
.diverging_type_vars
|
||||||
.borrow()
|
.borrow()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&ty| self.infcx.shallow_resolve(ty))
|
.map(|&ty| self.shallow_resolve(ty))
|
||||||
.filter_map(|ty| ty.ty_vid())
|
.filter_map(|ty| ty.ty_vid())
|
||||||
.map(|vid| self.infcx.root_var(vid))
|
.map(|vid| self.root_var(vid))
|
||||||
.collect();
|
.collect();
|
||||||
debug!(
|
debug!(
|
||||||
"calculate_diverging_fallback: diverging_type_vars={:?}",
|
"calculate_diverging_fallback: diverging_type_vars={:?}",
|
||||||
|
@ -236,7 +236,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
|
||||||
let mut diverging_vids = vec![];
|
let mut diverging_vids = vec![];
|
||||||
let mut non_diverging_vids = vec![];
|
let mut non_diverging_vids = vec![];
|
||||||
for unsolved_vid in unsolved_vids {
|
for unsolved_vid in unsolved_vids {
|
||||||
let root_vid = self.infcx.root_var(unsolved_vid);
|
let root_vid = self.root_var(unsolved_vid);
|
||||||
debug!(
|
debug!(
|
||||||
"calculate_diverging_fallback: unsolved_vid={:?} root_vid={:?} diverges={:?}",
|
"calculate_diverging_fallback: unsolved_vid={:?} root_vid={:?} diverges={:?}",
|
||||||
unsolved_vid,
|
unsolved_vid,
|
||||||
|
@ -271,7 +271,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
|
||||||
// variables. (Note that this set consists of "root variables".)
|
// variables. (Note that this set consists of "root variables".)
|
||||||
let mut roots_reachable_from_non_diverging = DepthFirstSearch::new(&coercion_graph);
|
let mut roots_reachable_from_non_diverging = DepthFirstSearch::new(&coercion_graph);
|
||||||
for &non_diverging_vid in &non_diverging_vids {
|
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) {
|
if roots_reachable_from_diverging.visited(root_vid) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -294,7 +294,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
|
||||||
diverging_fallback.reserve(diverging_vids.len());
|
diverging_fallback.reserve(diverging_vids.len());
|
||||||
for &diverging_vid in &diverging_vids {
|
for &diverging_vid in &diverging_vids {
|
||||||
let diverging_ty = self.tcx.mk_ty_var(diverging_vid);
|
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
|
let can_reach_non_diverging = coercion_graph
|
||||||
.depth_first_search(root_vid)
|
.depth_first_search(root_vid)
|
||||||
.any(|n| roots_reachable_from_non_diverging.visited(n));
|
.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 };
|
let mut relationship = ty::FoundRelationships { self_in_trait: false, output: false };
|
||||||
|
|
||||||
for (vid, rel) in relationships.iter() {
|
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.self_in_trait |= rel.self_in_trait;
|
||||||
relationship.output |= rel.output;
|
relationship.output |= rel.output;
|
||||||
}
|
}
|
||||||
|
@ -387,12 +387,12 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
debug!("create_coercion_graph: coercion_edges={:?}", coercion_edges);
|
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)
|
VecGraph::new(num_ty_vars, coercion_edges)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If `ty` is an unresolved type variable, returns its root vid.
|
/// If `ty` is an unresolved type variable, returns its root vid.
|
||||||
fn root_vid(&self, ty: Ty<'tcx>) -> Option<ty::TyVid> {
|
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() {
|
if !method.substs.is_empty() {
|
||||||
let method_generics = self.tcx.generics_of(method.def_id);
|
let method_generics = self.tcx.generics_of(method.def_id);
|
||||||
if !method_generics.params.is_empty() {
|
if !method_generics.params.is_empty() {
|
||||||
let user_type_annotation = self.infcx.probe(|_| {
|
let user_type_annotation = self.probe(|_| {
|
||||||
let user_substs = UserSubsts {
|
let user_substs = UserSubsts {
|
||||||
substs: InternalSubsts::for_item(self.tcx, method.def_id, |param, _| {
|
substs: InternalSubsts::for_item(self.tcx, method.def_id, |param, _| {
|
||||||
let i = param.index as usize;
|
let i = param.index as usize;
|
||||||
if i < method_generics.parent_count {
|
if i < method_generics.parent_count {
|
||||||
self.infcx.var_for_def(DUMMY_SP, param)
|
self.var_for_def(DUMMY_SP, param)
|
||||||
} else {
|
} else {
|
||||||
method.substs[i]
|
method.substs[i]
|
||||||
}
|
}
|
||||||
|
@ -198,7 +198,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
user_self_ty: None, // not relevant here
|
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,
|
method.def_id,
|
||||||
user_substs,
|
user_substs,
|
||||||
))
|
))
|
||||||
|
@ -236,7 +236,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
debug!("fcx {}", self.tag());
|
debug!("fcx {}", self.tag());
|
||||||
|
|
||||||
if Self::can_contain_user_lifetime_bounds((substs, user_self_ty)) {
|
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,
|
def_id,
|
||||||
UserSubsts { substs, user_self_ty },
|
UserSubsts { substs, user_self_ty },
|
||||||
));
|
));
|
||||||
|
@ -480,7 +480,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
debug!("to_ty_saving_user_provided_ty: ty={:?}", ty);
|
debug!("to_ty_saving_user_provided_ty: ty={:?}", ty);
|
||||||
|
|
||||||
if Self::can_contain_user_lifetime_bounds(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);
|
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);
|
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()
|
if let ty::subst::GenericArgKind::Type(ty) = ty.unpack()
|
||||||
&& let ty::Opaque(def_id, _) = *ty.kind()
|
&& let ty::Opaque(def_id, _) = *ty.kind()
|
||||||
&& let Some(def_id) = def_id.as_local()
|
&& 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;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -826,7 +826,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
} else {
|
} else {
|
||||||
self.tcx.bound_type_of(def_id)
|
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);
|
let ty = item_ty.subst(self.tcx, substs);
|
||||||
|
|
||||||
self.write_resolution(hir_id, Ok((def_kind, def_id)));
|
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 {
|
fn get_expr_coercion_span(&self, expr: &hir::Expr<'_>) -> rustc_span::Span {
|
||||||
let check_in_progress = |elem: &hir::Expr<'_>| {
|
let check_in_progress = |elem: &hir::Expr<'_>| {
|
||||||
self.in_progress_typeck_results
|
self.typeck_results.borrow().node_type_opt(elem.hir_id).filter(|ty| !ty.is_never()).map(
|
||||||
.and_then(|typeck_results| typeck_results.borrow().node_type_opt(elem.hir_id))
|
|_| match elem.kind {
|
||||||
.and_then(|ty| {
|
|
||||||
if ty.is_never() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(match elem.kind {
|
|
||||||
// Point at the tail expression when possible.
|
// Point at the tail expression when possible.
|
||||||
hir::ExprKind::Block(block, _) => {
|
hir::ExprKind::Block(block, _) => block.expr.map_or(block.span, |e| e.span),
|
||||||
block.expr.map_or(block.span, |e| e.span)
|
|
||||||
}
|
|
||||||
_ => elem.span,
|
_ => elem.span,
|
||||||
})
|
},
|
||||||
}
|
)
|
||||||
})
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if let hir::ExprKind::If(_, _, Some(el)) = expr.kind {
|
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>>,
|
OP: FnOnce(ProbeContext<'a, 'tcx>) -> Result<R, MethodError<'tcx>>,
|
||||||
{
|
{
|
||||||
let mut orig_values = OriginalQueryValues::default();
|
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 },
|
ParamEnvAnd { param_env: self.param_env, value: self_ty },
|
||||||
&mut orig_values,
|
&mut orig_values,
|
||||||
);
|
);
|
||||||
|
@ -351,7 +351,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let steps = if mode == Mode::MethodCall {
|
let steps = if mode == Mode::MethodCall {
|
||||||
self.tcx.method_autoderef_steps(param_env_and_self_ty)
|
self.tcx.method_autoderef_steps(param_env_and_self_ty)
|
||||||
} else {
|
} else {
|
||||||
self.infcx.probe(|_| {
|
self.probe(|_| {
|
||||||
// Mode::Path - the deref steps is "trivial". This turns
|
// Mode::Path - the deref steps is "trivial". This turns
|
||||||
// our CanonicalQuery into a "trivial" QueryResponse. This
|
// our CanonicalQuery into a "trivial" QueryResponse. This
|
||||||
// is a bit inefficient, but I don't think that writing
|
// is a bit inefficient, but I don't think that writing
|
||||||
|
|
|
@ -865,9 +865,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
.join("\n");
|
.join("\n");
|
||||||
let actual_prefix = actual.prefix_string(self.tcx);
|
let actual_prefix = actual.prefix_string(self.tcx);
|
||||||
info!("unimplemented_traits.len() == {}", unimplemented_traits.len());
|
info!("unimplemented_traits.len() == {}", unimplemented_traits.len());
|
||||||
let (primary_message, label) = if unimplemented_traits.len() == 1
|
let (primary_message, label) =
|
||||||
&& unimplemented_traits_only
|
if unimplemented_traits.len() == 1 && unimplemented_traits_only {
|
||||||
{
|
|
||||||
unimplemented_traits
|
unimplemented_traits
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.next()
|
.next()
|
||||||
|
@ -879,7 +878,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
return (None, None);
|
return (None, None);
|
||||||
}
|
}
|
||||||
let OnUnimplementedNote { message, label, .. } =
|
let OnUnimplementedNote { message, label, .. } =
|
||||||
self.infcx.on_unimplemented_note(trait_ref, &obligation);
|
self.on_unimplemented_note(trait_ref, &obligation);
|
||||||
(message, label)
|
(message, label)
|
||||||
})
|
})
|
||||||
.unwrap_or((None, None))
|
.unwrap_or((None, None))
|
||||||
|
@ -1648,7 +1647,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
call: &hir::Expr<'_>,
|
call: &hir::Expr<'_>,
|
||||||
span: Span,
|
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(),
|
Some(output_ty) => self.resolve_vars_if_possible(output_ty).skip_binder(),
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
|
|
|
@ -475,7 +475,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
suggest_deref_binop(lhs_deref_ty);
|
suggest_deref_binop(lhs_deref_ty);
|
||||||
} else if is_assign == IsAssign::No
|
} else if is_assign == IsAssign::No
|
||||||
&& let Ref(_, lhs_deref_ty, _) = lhs_ty.kind() {
|
&& 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);
|
suggest_deref_binop(*lhs_deref_ty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -523,7 +523,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.infcx.suggest_restricting_param_bound(
|
self.suggest_restricting_param_bound(
|
||||||
&mut err,
|
&mut err,
|
||||||
trait_pred,
|
trait_pred,
|
||||||
proj_pred,
|
proj_pred,
|
||||||
|
@ -740,7 +740,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
error.obligation.predicate.to_opt_poly_trait_pred()
|
error.obligation.predicate.to_opt_poly_trait_pred()
|
||||||
});
|
});
|
||||||
for pred in predicates {
|
for pred in predicates {
|
||||||
self.infcx.suggest_restricting_param_bound(
|
self.suggest_restricting_param_bound(
|
||||||
&mut err,
|
&mut err,
|
||||||
pred,
|
pred,
|
||||||
None,
|
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 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 {
|
let ty = match closure_clause {
|
||||||
hir::CaptureBy::Value => ty, // For move closure the capture kind should be by value
|
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,
|
closure_clause: hir::CaptureBy,
|
||||||
var_hir_id: hir::HirId,
|
var_hir_id: hir::HirId,
|
||||||
) -> Option<FxHashSet<UpvarMigrationInfo>> {
|
) -> 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())) {
|
if !ty.has_significant_drop(self.tcx, self.tcx.param_env(closure_def_id.expect_local())) {
|
||||||
debug!("does not have significant drop");
|
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>`).
|
// (e.g. keep `for<'a>` named `for<'a>`).
|
||||||
// This allows NLL to generate error messages that
|
// This allows NLL to generate error messages that
|
||||||
// refer to the higher-ranked lifetime names written by the user.
|
// 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(_) => {
|
Err(_) => {
|
||||||
debug!("Resolver::fold_ty: input type `{:?}` not fully resolvable", t);
|
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> {
|
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
|
||||||
match self.infcx.fully_resolve(ct) {
|
match self.infcx.fully_resolve(ct) {
|
||||||
Ok(ct) => self.infcx.tcx.erase_regions(ct),
|
Ok(ct) => self.tcx.erase_regions(ct),
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
debug!("Resolver::fold_const: input const `{:?}` not fully resolvable", ct);
|
debug!("Resolver::fold_const: input const `{:?}` not fully resolvable", ct);
|
||||||
self.report_const_error(ct);
|
self.report_const_error(ct);
|
||||||
|
|
|
@ -244,7 +244,7 @@ pub struct UnconstrainedOpaqueType {
|
||||||
pub struct MissingTypeParams {
|
pub struct MissingTypeParams {
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub def_span: Span,
|
pub def_span: Span,
|
||||||
pub missing_type_params: Vec<String>,
|
pub missing_type_params: Vec<Symbol>,
|
||||||
pub empty_generic_args: bool,
|
pub empty_generic_args: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,7 +285,15 @@ impl<'a> SessionDiagnostic<'a> for MissingTypeParams {
|
||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
self.span,
|
self.span,
|
||||||
rustc_errors::fluent::typeck::suggestion,
|
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,
|
Applicability::HasPlaceholders,
|
||||||
);
|
);
|
||||||
suggested = true;
|
suggested = true;
|
||||||
|
|
|
@ -1126,6 +1126,19 @@ impl fmt::Debug for File {
|
||||||
Some(PathBuf::from(OsString::from_vec(buf)))
|
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")]
|
#[cfg(target_os = "vxworks")]
|
||||||
fn get_path(fd: c_int) -> Option<PathBuf> {
|
fn get_path(fd: c_int) -> Option<PathBuf> {
|
||||||
let mut buf = vec![0; libc::PATH_MAX as usize];
|
let mut buf = vec![0; libc::PATH_MAX as usize];
|
||||||
|
@ -1142,6 +1155,7 @@ impl fmt::Debug for File {
|
||||||
target_os = "linux",
|
target_os = "linux",
|
||||||
target_os = "macos",
|
target_os = "macos",
|
||||||
target_os = "vxworks",
|
target_os = "vxworks",
|
||||||
|
all(target_os = "freebsd", target_arch = "x86_64"),
|
||||||
target_os = "netbsd"
|
target_os = "netbsd"
|
||||||
)))]
|
)))]
|
||||||
fn get_path(_fd: c_int) -> Option<PathBuf> {
|
fn get_path(_fd: c_int) -> Option<PathBuf> {
|
||||||
|
|
|
@ -1,21 +1,28 @@
|
||||||
1| |// Regression test for issue #98833.
|
1| |// Regression test for issue #98833.
|
||||||
2| |// compile-flags: -Zinline-mir
|
2| |// compile-flags: -Zinline-mir -Cdebug-assertions=off
|
||||||
3| |
|
3| |
|
||||||
4| 1|fn main() {
|
4| 1|fn main() {
|
||||||
5| 1| println!("{}", live::<false>());
|
5| 1| println!("{}", live::<false>());
|
||||||
6| 1|}
|
6| 1|
|
||||||
7| |
|
7| 1| let f = |x: bool| {
|
||||||
8| |#[inline]
|
8| | debug_assert!(
|
||||||
9| 1|fn live<const B: bool>() -> u32 {
|
9| | x
|
||||||
10| 1| if B {
|
10| | );
|
||||||
11| 0| dead()
|
11| 1| };
|
||||||
12| | } else {
|
12| 1| f(false);
|
||||||
13| 1| 0
|
13| 1|}
|
||||||
14| | }
|
14| |
|
||||||
15| 1|}
|
15| |#[inline]
|
||||||
16| |
|
16| 1|fn live<const B: bool>() -> u32 {
|
||||||
17| |#[inline]
|
17| 1| if B {
|
||||||
18| 0|fn dead() -> u32 {
|
18| 0| dead()
|
||||||
19| 0| 42
|
19| | } else {
|
||||||
20| 0|}
|
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.
|
// Regression test for issue #98833.
|
||||||
// compile-flags: -Zinline-mir
|
// compile-flags: -Zinline-mir -Cdebug-assertions=off
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("{}", live::<false>());
|
println!("{}", live::<false>());
|
||||||
|
|
||||||
|
let f = |x: bool| {
|
||||||
|
debug_assert!(
|
||||||
|
x
|
||||||
|
);
|
||||||
|
};
|
||||||
|
f(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -5,7 +5,7 @@ trait Foo {
|
||||||
|
|
||||||
impl<'a> Foo for &'a () {
|
impl<'a> Foo for &'a () {
|
||||||
const NAME: &'a str = "unit";
|
const NAME: &'a str = "unit";
|
||||||
//~^ ERROR mismatched types [E0308]
|
//~^ ERROR const not compatible with trait
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
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
|
--> $DIR/associated-const-impl-wrong-lifetime.rs:7:5
|
||||||
|
|
|
|
||||||
LL | const NAME: &'a str = "unit";
|
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
|
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>;
|
LL | type Assoc3<T>;
|
||||||
| -------------- definition of `Assoc3` from trait
|
| -------------- definition of `Assoc3` from trait
|
||||||
...
|
...
|
||||||
LL | type Assoc3<T> = Vec<T> where T: Iterator;
|
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
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -13,9 +13,9 @@ struct Fooy<T>(T);
|
||||||
|
|
||||||
impl<T> Foo for Fooy<T> {
|
impl<T> Foo for Fooy<T> {
|
||||||
type A<'a> = (&'a ()) where Self: 'static;
|
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;
|
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
|
//~| ERROR lifetime bound not satisfied
|
||||||
type C = String where Self: Copy;
|
type C = String where Self: Copy;
|
||||||
//~^ ERROR the trait bound `T: Copy` is not satisfied
|
//~^ 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
|
error[E0276]: impl has stricter requirements than trait
|
||||||
--> $DIR/impl_bounds.rs:15:5
|
--> $DIR/impl_bounds.rs:15:39
|
||||||
|
|
|
|
||||||
LL | type A<'a> where Self: 'a;
|
LL | type A<'a> where Self: 'a;
|
||||||
| ---------- expected
|
| ---------- definition of `A` from trait
|
||||||
...
|
...
|
||||||
LL | type A<'a> = (&'a ()) where Self: 'static;
|
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
|
error[E0276]: impl has stricter requirements than trait
|
||||||
--> $DIR/impl_bounds.rs:17:5
|
--> $DIR/impl_bounds.rs:17:48
|
||||||
|
|
|
|
||||||
LL | type B<'a, 'b> where 'a: 'b;
|
LL | type B<'a, 'b> where 'a: 'b;
|
||||||
| -------------- expected
|
| -------------- definition of `B` from trait
|
||||||
...
|
...
|
||||||
LL | type B<'a, 'b> = (&'a(), &'b ()) where 'b: 'a;
|
LL | type B<'a, 'b> = (&'a(), &'b ()) where 'b: 'a;
|
||||||
| ^^^^^^^^^^^^^^ found
|
| ^^ impl has extra requirement `'b: 'a`
|
||||||
|
|
||||||
error[E0478]: lifetime bound not satisfied
|
error[E0478]: lifetime bound not satisfied
|
||||||
--> $DIR/impl_bounds.rs:17:22
|
--> $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
|
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;
|
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>`
|
note: required because of the requirements on the impl of `Copy` for `Fooy<T>`
|
||||||
--> $DIR/impl_bounds.rs:11:10
|
--> $DIR/impl_bounds.rs:11:10
|
||||||
|
|
|
|
||||||
LL | #[derive(Copy, Clone)]
|
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
|
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:5
|
--> $DIR/impl_bounds.rs:7:10
|
||||||
|
|
|
|
||||||
LL | trait Foo {
|
LL | trait Foo {
|
||||||
| --- in this trait
|
| --- in this trait
|
||||||
...
|
...
|
||||||
LL | type C where Self: Clone;
|
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)
|
= 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`
|
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)]
|
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
|
--> $DIR/impl_bounds.rs:8:8
|
||||||
|
|
|
|
||||||
LL | trait Foo {
|
LL | trait Foo {
|
||||||
| --- in this trait
|
| --- in this trait
|
||||||
...
|
...
|
||||||
LL | fn d() where Self: Clone;
|
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)
|
= 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`
|
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
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0277, E0478.
|
Some errors have detailed explanations: E0276, E0277, E0478.
|
||||||
For more information about an error, try `rustc --explain E0277`.
|
For more information about an error, try `rustc --explain E0276`.
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
error[E0276]: impl has stricter requirements than trait
|
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>;
|
LL | type Assoc3<T>;
|
||||||
| -------------- definition of `Assoc3` from trait
|
| -------------- definition of `Assoc3` from trait
|
||||||
...
|
...
|
||||||
LL | type Assoc3<T> = Vec<T> where T: Iterator;
|
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
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ trait Foo {
|
||||||
}
|
}
|
||||||
impl Foo for () {
|
impl Foo for () {
|
||||||
type Assoc<'a, 'b> = () where 'a: 'b;
|
type Assoc<'a, 'b> = () where 'a: 'b;
|
||||||
//~^ `impl` associated type
|
//~^ impl has stricter requirements than trait
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
error: `impl` associated type signature for `Assoc` doesn't match `trait` associated type signature
|
error[E0276]: impl has stricter requirements than trait
|
||||||
--> $DIR/missing-where-clause-on-trait.rs:9:5
|
--> $DIR/missing-where-clause-on-trait.rs:9:39
|
||||||
|
|
|
|
||||||
LL | type Assoc<'a, 'b>;
|
LL | type Assoc<'a, 'b>;
|
||||||
| ------------------ expected
|
| ------------------ definition of `Assoc` from trait
|
||||||
...
|
...
|
||||||
LL | type Assoc<'a, 'b> = () where 'a: 'b;
|
LL | type Assoc<'a, 'b> = () where 'a: 'b;
|
||||||
| ^^^^^^^^^^^^^^^^^^ found
|
| ^^ impl has extra requirement `'a: 'b`
|
||||||
|
|
||||||
error: aborting due to previous error
|
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 {
|
impl<'a: 'b, 'b, 'c> Anything<'a, 'b> for FailStruct {
|
||||||
const AC: Option<&'c str> = None;
|
const AC: Option<&'c str> = None;
|
||||||
//~^ ERROR: mismatched types
|
//~^ ERROR: const not compatible with trait
|
||||||
}
|
}
|
||||||
|
|
||||||
struct OKStruct2 { }
|
struct OKStruct2 { }
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error[E0308]: mismatched types
|
error[E0308]: const not compatible with trait
|
||||||
--> $DIR/trait-associated-constant.rs:21:5
|
--> $DIR/trait-associated-constant.rs:21:5
|
||||||
|
|
|
|
||||||
LL | const AC: Option<&'c str> = None;
|
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-codegen-shared", "Apache-2.0 WITH LLVM-exception"),
|
||||||
("cranelift-entity", "Apache-2.0 WITH LLVM-exception"),
|
("cranelift-entity", "Apache-2.0 WITH LLVM-exception"),
|
||||||
("cranelift-frontend", "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-jit", "Apache-2.0 WITH LLVM-exception"),
|
||||||
("cranelift-module", "Apache-2.0 WITH LLVM-exception"),
|
("cranelift-module", "Apache-2.0 WITH LLVM-exception"),
|
||||||
("cranelift-native", "Apache-2.0 WITH LLVM-exception"),
|
("cranelift-native", "Apache-2.0 WITH LLVM-exception"),
|
||||||
("cranelift-object", "Apache-2.0 WITH LLVM-exception"),
|
("cranelift-object", "Apache-2.0 WITH LLVM-exception"),
|
||||||
("mach", "BSD-2-Clause"),
|
("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"),
|
("target-lexicon", "Apache-2.0 WITH LLVM-exception"),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -258,10 +259,12 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[
|
||||||
];
|
];
|
||||||
|
|
||||||
const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[
|
const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[
|
||||||
|
"ahash",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"ar",
|
"ar",
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
|
"byteorder",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"cranelift-bforest",
|
"cranelift-bforest",
|
||||||
"cranelift-codegen",
|
"cranelift-codegen",
|
||||||
|
@ -269,11 +272,14 @@ const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[
|
||||||
"cranelift-codegen-shared",
|
"cranelift-codegen-shared",
|
||||||
"cranelift-entity",
|
"cranelift-entity",
|
||||||
"cranelift-frontend",
|
"cranelift-frontend",
|
||||||
|
"cranelift-isle",
|
||||||
"cranelift-jit",
|
"cranelift-jit",
|
||||||
"cranelift-module",
|
"cranelift-module",
|
||||||
"cranelift-native",
|
"cranelift-native",
|
||||||
"cranelift-object",
|
"cranelift-object",
|
||||||
"crc32fast",
|
"crc32fast",
|
||||||
|
"fxhash",
|
||||||
|
"getrandom",
|
||||||
"gimli",
|
"gimli",
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
|
@ -284,11 +290,13 @@ const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[
|
||||||
"memchr",
|
"memchr",
|
||||||
"object",
|
"object",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"regalloc",
|
"regalloc2",
|
||||||
"region",
|
"region",
|
||||||
"rustc-hash",
|
"slice-group-by",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"target-lexicon",
|
"target-lexicon",
|
||||||
|
"version_check",
|
||||||
|
"wasi",
|
||||||
"winapi",
|
"winapi",
|
||||||
"winapi-i686-pc-windows-gnu",
|
"winapi-i686-pc-windows-gnu",
|
||||||
"winapi-x86_64-pc-windows-gnu",
|
"winapi-x86_64-pc-windows-gnu",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue