Skip to content

Rollup of 7 pull requests #99745

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 112 commits into from
Jul 26, 2022
Merged
Changes from all commits
Commits
Show all changes
112 commits
Select commit Hold shift + click to select a range
d9025ce
Merge commit '63734fcdd718cca089f84c42f3a42c0096cfd431' into sync_cg_…
bjorn3 May 15, 2022
715533e
Merge branch 'sync_from_rust'
bjorn3 May 15, 2022
01ab51b
Rustup to rustc 1.63.0-nightly (c52b9c10b 2022-05-16)
bjorn3 May 17, 2022
7a10059
Fix symbol tables in case of multiple object files with the same name
bjorn3 May 18, 2022
6c9a06e
Update Cranelift and object
bjorn3 May 20, 2022
814ed4f
Rustup to rustc 1.63.0-nightly (c06728704 2022-05-19)
bjorn3 May 20, 2022
e97e40d
Update rust-analyzer configuration
bjorn3 May 22, 2022
5011ae4
Refactor call terminator to always hold a destination place
JakobDegen Apr 16, 2022
d27ec6c
Add flag for stricter checks on uninit/zeroed
5225225 May 23, 2022
e2f90f7
Add support for emitting functions with `coldcc` in LLVM
scottmcm May 29, 2022
4ee48c0
Use CallConv::Cold in cranelift for extern "rust-cold"
scottmcm May 29, 2022
e600875
Add a pointer to address cast kind
tmiasko May 31, 2022
722c724
rename PointerAddress → PointerExposeAddress
RalfJung Jun 1, 2022
ede985e
add cast kind of from_exposed_addr (int-to-ptr casts)
RalfJung Jun 2, 2022
d628444
Remove workaround for bytecodealliance/wasmtime#3963
bjorn3 Jun 2, 2022
7a8b96f
Make `std::mem::needs_drop` accept `?Sized`
nvzqz Jun 3, 2022
eb5f237
Fix unsized field order
nvzqz Jun 3, 2022
d5cb2be
Rename CodegenUnit::work_product to previous_work_product
bjorn3 May 13, 2022
5a1a111
Avoid an unnecessary clone for copy_cgu_workproduct_to_incr_comp_cach…
bjorn3 May 13, 2022
bbb8509
Factor Option out of copy_cgu_workproduct_to_incr_comp_cache_dir call
bjorn3 May 13, 2022
3d8e854
Make saved_file field of WorkProduct non-optional
bjorn3 May 15, 2022
d8bd0a9
Auto merge of #97512 - scottmcm:add-coldcc, r=nagisa,lcnr
bors Jun 7, 2022
b867d41
Auto merge of #97825 - Dylan-DPC:rollup-ya51k1k, r=Dylan-DPC
bors Jun 7, 2022
74f3916
Sync from rust be16c6166f08f9b26d854783bbd4ce8d006c8f6f
bjorn3 Jun 9, 2022
875ffa1
Rustup to rustc 1.63.0-nightly (7466d5492 2022-06-08)
bjorn3 Jun 9, 2022
a298c69
Mark extern rust-cold calls as cold
bjorn3 Jun 9, 2022
ec841f5
Fix running rustc tests
bjorn3 Jun 9, 2022
ce2b3a9
Rename the `ConstS::val` field as `kind`.
nnethercote Jun 10, 2022
c431540
Rustup to rustc 1.63.0-nightly (ca122c7eb 2022-06-13)
bjorn3 Jun 14, 2022
9096b3e
implement valtrees as the type-system representation for constant values
b-naber Feb 16, 2022
fc0c753
Remove src_files and remove_file
bjorn3 Jun 14, 2022
6d8c450
Move/rename `lazy::Sync{OnceCell,Lazy}` to `sync::{Once,Lazy}Lock`
WaffleLapkin Jun 16, 2022
449b309
Rollup merge of #97675 - nvzqz:unsized-needs-drop, r=dtolnay
JohnTitor Jun 16, 2022
5543d22
Rollup merge of #98165 - WaffleLapkin:once_things_renamings, r=m-ou-se
matthiaskrgr Jun 18, 2022
abb9b60
Fix "Remove src_files and remove_file"
bjorn3 Jun 18, 2022
73b3ae0
Remove the source archive functionality of ArchiveWriter
bjorn3 Jun 14, 2022
92749f0
Auto merge of #98098 - bjorn3:archive_refactor, r=michaelwoerister
bors Jun 21, 2022
473e80e
Sync from rust 10f4ce324baf7cfb7ce2b2096662b82b79204944
bjorn3 Jun 23, 2022
c58a11e
Rustup to rustc 1.63.0-nightly (10f4ce324 2022-06-22)
bjorn3 Jun 23, 2022
6d5e8f3
Adopt for "Remove dereferencing of Box from codegen"
bjorn3 Jun 23, 2022
7c5fbac
Update Cranelift to 0.85.0
bjorn3 Jun 23, 2022
439c323
Disable DWARF debuginfo on Windows
bjorn3 Aug 16, 2021
8a4557e
Update for changes to the rustc test suite
bjorn3 Jun 23, 2022
f516ba2
Update `smallvec` to 1.8.1.
nnethercote Jun 26, 2022
f060ae9
Update to Cranelift 0.85.1
bjorn3 Jun 28, 2022
56c5c09
Run regalloc checker on CI
bjorn3 Jun 28, 2022
c1ac2df
Allow building the sysroot with --emit llvm-ir
bjorn3 Jun 28, 2022
45b6cd6
Fix a crash for 11 single byte fields passed through the C abi
bjorn3 Jun 28, 2022
846eecb
Change enum->int casts to not go through MIR casts.
oli-obk Jun 29, 2022
a71e691
Recover when failing to normalize closure signature.
cjgillot Feb 4, 2022
14b2f8f
Add code to print clif ir on panics during define_function
bjorn3 Jul 2, 2022
b344691
Sync from rust f99f9e48ed77a99747c6d07b42fdfe500f1a7de0
bjorn3 Jul 3, 2022
8720683
Rustup to rustc 1.64.0-nightly (f2d93935f 2022-07-02)
bjorn3 Jul 3, 2022
b8aab37
Update for changes to the rustc test suite
bjorn3 Jul 3, 2022
96bdb39
Auto merge of #96862 - oli-obk:enum_cast_mir, r=RalfJung
bors Jul 5, 2022
44c2558
Update TypeVisitor paths
eggyal Jun 17, 2022
69d0c1e
incr: cache dwarf objects in work products
davidtwco Jul 4, 2022
c413617
Update integer_atomics tracking issue
tamird Jul 8, 2022
e151a09
Rollup merge of #99070 - tamird:update-tracking-issue, r=RalfJung
Dylan-DPC Jul 9, 2022
e9442b6
fix cranelift and gcc backends
RalfJung Jul 5, 2022
f44d5fe
review feedback
RalfJung Jul 5, 2022
c78b438
tweak names and output and bless
RalfJung Jul 6, 2022
743cee6
Partially stabilize const_slice_from_raw_parts
LunaBorowska May 29, 2022
a7347a9
Keep unstable target features for asm feature checking
Amanieu Jul 11, 2022
9efccc9
add new rval, pull deref early
ouz-a Jun 13, 2022
38c321a
Rollup merge of #99155 - Amanieu:unstable-target-features, r=davidtwco
Dylan-DPC Jul 13, 2022
4338881
Auto merge of #99210 - Dylan-DPC:rollup-879cp1t, r=Dylan-DPC
bors Jul 13, 2022
b2ae24e
Rename `debugging_opts` to `unstable_opts`
jyn514 Jul 6, 2022
5a81bf7
Use constant eval to do strict validity checks
5225225 Jul 14, 2022
9ea9c09
Introduce opaque type to hidden type projection
oli-obk Jun 22, 2022
f750d8b
Upgrade indexmap and thorin-dwp to use hashbrown 0.12
cuviper Jul 14, 2022
ec46952
Upgrade hashbrown to 0.12.3
Amanieu Jul 17, 2022
33b297a
Auto merge of #99033 - 5225225:interpreter-validity-checks, r=oli-obk
bors Jul 17, 2022
cff5eed
Sync from rust 880416180b0a9ee1141c07d4d17667edb77daebd
bjorn3 Jul 18, 2022
bc061fa
Rustup to rustc 1.64.0-nightly (263edd43c 2022-07-17)
bjorn3 Jul 18, 2022
5fcedf6
Update for changes to the rustc test suite
bjorn3 Jul 18, 2022
22a0a2e
Revert "Rollup merge of #98582 - oli-obk:unconstrained_opaque_type, r…
oli-obk Jul 20, 2022
1c77e2b
add a Vtable kind of symbolic allocations
RalfJung Jul 17, 2022
b5cce74
rename get_global_alloc to try_get_global_alloc
RalfJung Jul 17, 2022
a1b1722
consistently use VTable over Vtable (matching stable stdlib API RawWa…
RalfJung Jul 19, 2022
6c9abfa
slightly cleaner, if more verbose, vtable handling in codegen backends
RalfJung Jul 20, 2022
f8feed7
Implement vtable_size and vtable_align intrinsics for cg_clif
bjorn3 Jul 20, 2022
d07ed02
various nits from review
RalfJung Jul 20, 2022
cd96988
Don't crash when local variables are too big to store on the stack
bjorn3 Jul 22, 2022
a6b602d
Fix inline asm codegen for empty template
bjorn3 Jul 22, 2022
3207c9f
Report an error on incompatible symbol definitions
bjorn3 Jul 22, 2022
745193d
Auto merge of #99251 - cuviper:hashbrown-0.12, r=Mark-Simulacrum
bors Jul 24, 2022
6bb7581
Slightly improve mismatched GAT where clause error
compiler-errors Jul 16, 2022
2bbcdc7
Handle additional lifetime bounds on GATs like on methods
compiler-errors Jul 24, 2022
3bbe95c
Combine redundant obligation cause codes
compiler-errors Jul 24, 2022
f85f375
suggest removing the tuple struct field for the unwrapped value
TaKO8Ki Jul 22, 2022
39ee14d
Error when trying to define variadic functions
bjorn3 Jul 25, 2022
5f40a4f
Remove reachable coverage without counters
tmiasko Jul 25, 2022
7ef2ba8
Fix size_of_val and min_align_of_val for truly unsized types
bjorn3 Jul 25, 2022
fd2669d
Fix -Zpolymorphize
bjorn3 Jul 25, 2022
bf1a5e7
remove `is_local_span` as it is no longer used
TaKO8Ki Jul 25, 2022
051e98b
avoid `&str`/`Symbol` to `String` conversions
TaKO8Ki Jul 25, 2022
722733c
Merge pull request #1247 from bjorn3/melt_some_ice
bjorn3 Jul 25, 2022
d7fc563
Update Cranelift to 0.85.3
bjorn3 Jul 25, 2022
4e1155f
Sync from rust 2f320a224e827b400be25966755a621779f797cc
bjorn3 Jul 25, 2022
c19edfd
Rustup to rustc 1.64.0-nightly (7fe022f5a 2022-07-24)
bjorn3 Jul 25, 2022
7a3ed23
Merge commit 'c19edfd71a1d0ddef86c2c67fdb40718d40a72b4' into sync_cg_…
bjorn3 Jul 25, 2022
9dc4ed8
Update list of allowed dependencies
bjorn3 Jul 25, 2022
e39b44a
Implement `fs::get_path` for FreeBSD.
devnexen Jun 17, 2022
aaa9989
Remove some explicit self.infcx for fcx, which derefs into infcx
compiler-errors Jul 22, 2022
d3acd00
Rollup merge of #98211 - devnexen:get_path_freebsd, r=Mark-Simulacrum
JohnTitor Jul 26, 2022
2944454
Rollup merge of #99353 - compiler-errors:gat-where-clause-mismatch, r…
JohnTitor Jul 26, 2022
d89e99a
Rollup merge of #99593 - TaKO8Ki:suggest-removing-tuple-struct-field,…
JohnTitor Jul 26, 2022
2744c0e
Rollup merge of #99615 - compiler-errors:remove-some-explicit-infcx, …
JohnTitor Jul 26, 2022
3c1eef2
Rollup merge of #99711 - tmiasko:coverage, r=wesleywiser
JohnTitor Jul 26, 2022
85afb90
Rollup merge of #99718 - TaKO8Ki:avoid-&str-symbol-to-string-conversi…
JohnTitor Jul 26, 2022
a572f06
Rollup merge of #99720 - bjorn3:sync_cg_clif-2022-07-25, r=bjorn3
JohnTitor Jul 26, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions compiler/rustc_borrowck/src/diagnostics/region_errors.rs
Original file line number Diff line number Diff line change
@@ -850,13 +850,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
debug!("trait spans found: {:?}", traits);
for span in &traits {
let mut multi_span: MultiSpan = vec![*span].into();
multi_span.push_span_label(
*span,
"this has an implicit `'static` lifetime requirement".to_string(),
);
multi_span
.push_span_label(*span, "this has an implicit `'static` lifetime requirement");
multi_span.push_span_label(
ident.span,
"calling this method introduces the `impl`'s 'static` requirement".to_string(),
"calling this method introduces the `impl`'s 'static` requirement",
);
err.span_note(multi_span, "the used `impl` has a `'static` requirement");
err.span_suggestion_verbose(
7 changes: 3 additions & 4 deletions compiler/rustc_codegen_cranelift/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
{
// source for rustc_* is not included in the rust-src component; disable the errors about this
"rust-analyzer.diagnostics.disabled": ["unresolved-extern-crate", "unresolved-macro-call"],
"rust-analyzer.assist.importGranularity": "module",
"rust-analyzer.assist.importEnforceGranularity": true,
"rust-analyzer.assist.importPrefix": "crate",
"rust-analyzer.cargo.runBuildScripts": true,
"rust-analyzer.imports.granularity.enforce": true,
"rust-analyzer.imports.granularity.group": "module",
"rust-analyzer.imports.prefix": "crate",
"rust-analyzer.cargo.features": ["unstable-features"],
"rust-analyzer.linkedProjects": [
"./Cargo.toml",
139 changes: 103 additions & 36 deletions compiler/rustc_codegen_cranelift/Cargo.lock
Original file line number Diff line number Diff line change
@@ -2,6 +2,17 @@
# It is not intended for manual editing.
version = 3

[[package]]
name = "ahash"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
dependencies = [
"getrandom",
"once_cell",
"version_check",
]

[[package]]
name = "anyhow"
version = "1.0.56"
@@ -25,6 +36,12 @@ version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"

[[package]]
name = "byteorder"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"

[[package]]
name = "cfg-if"
version = "1.0.0"
@@ -33,68 +50,75 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"

[[package]]
name = "cranelift-bforest"
version = "0.83.0"
version = "0.85.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed44413e7e2fe3260d0ed73e6956ab188b69c10ee92b892e401e0f4f6808c68b"
checksum = "749d0d6022c9038dccf480bdde2a38d435937335bf2bb0f14e815d94517cdce8"
dependencies = [
"cranelift-entity",
]

[[package]]
name = "cranelift-codegen"
version = "0.83.0"
version = "0.85.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b5d83f0f26bf213f971f45589d17e5b65e4861f9ed22392b0cbb6eaa5bd329c"
checksum = "e94370cc7b37bf652ccd8bb8f09bd900997f7ccf97520edfc75554bb5c4abbea"
dependencies = [
"cranelift-bforest",
"cranelift-codegen-meta",
"cranelift-codegen-shared",
"cranelift-entity",
"cranelift-isle",
"gimli",
"log",
"regalloc",
"regalloc2",
"smallvec",
"target-lexicon",
]

[[package]]
name = "cranelift-codegen-meta"
version = "0.83.0"
version = "0.85.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6800dc386177df6ecc5a32680607ed8ba1fa0d31a2a59c8c61fbf44826b8191d"
checksum = "e0a3cea8fdab90e44018c5b9a1dfd460d8ee265ac354337150222a354628bdb6"
dependencies = [
"cranelift-codegen-shared",
]

[[package]]
name = "cranelift-codegen-shared"
version = "0.83.0"
version = "0.85.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c961f85070985ebc8fcdb81b838a5cf842294d1e6ed4852446161c7e246fd455"
checksum = "5ac72f76f2698598951ab26d8c96eaa854810e693e7dd52523958b5909fde6b2"

[[package]]
name = "cranelift-entity"
version = "0.83.0"
version = "0.85.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2347b2b8d1d5429213668f2a8e36c85ee3c73984a2f6a79007e365d3e575e7ed"
checksum = "09eaeacfcd2356fe0e66b295e8f9d59fdd1ac3ace53ba50de14d628ec902f72d"

[[package]]
name = "cranelift-frontend"
version = "0.83.0"
version = "0.85.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cbcdbf7bed29e363568b778649b69dabc3d727256d5d25236096ef693757654"
checksum = "dba69c9980d5ffd62c18a2bde927855fcd7c8dc92f29feaf8636052662cbd99c"
dependencies = [
"cranelift-codegen",
"log",
"smallvec",
"target-lexicon",
]

[[package]]
name = "cranelift-isle"
version = "0.85.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2920dc1e05cac40304456ed3301fde2c09bd6a9b0210bcfa2f101398d628d5b"

[[package]]
name = "cranelift-jit"
version = "0.83.0"
version = "0.85.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c769d4e0d76f59c8b2a3bf0477d89ee149bb0731b53fbb245ee081d49063095"
checksum = "1c3c5ed067f2c81577e431f3039148a9c187b33cc79e0d1731fede27d801ec56"
dependencies = [
"anyhow",
"cranelift-codegen",
@@ -110,19 +134,19 @@ dependencies = [

[[package]]
name = "cranelift-module"
version = "0.83.0"
version = "0.85.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ab57d399a2401074bb0cc40b3031e420f3d66d46ec0cf21eeae53ac04bd73e2"
checksum = "eee6784303bf9af235237a4885f7417e09a35df896d38ea969a0081064b3ede4"
dependencies = [
"anyhow",
"cranelift-codegen",
]

[[package]]
name = "cranelift-native"
version = "0.83.0"
version = "0.85.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f4cdf93552e5ceb2e3c042829ebb4de4378492705f769eadc6a7c6c5251624c"
checksum = "f04dfa45f9b2a6f587c564d6b63388e00cd6589d2df6ea2758cf79e1a13285e6"
dependencies = [
"cranelift-codegen",
"libc",
@@ -131,9 +155,9 @@ dependencies = [

[[package]]
name = "cranelift-object"
version = "0.83.0"
version = "0.85.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf8e65f4839c26e6237fc0744911d79b0a2ac5e76b4e4eebd14db2b8d849fd31"
checksum = "0bf38b2c505db749276793116c0cb30bd096206c7810e471677a453134881881"
dependencies = [
"anyhow",
"cranelift-codegen",
@@ -152,6 +176,26 @@ dependencies = [
"cfg-if",
]

[[package]]
name = "fxhash"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
dependencies = [
"byteorder",
]

[[package]]
name = "getrandom"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad"
dependencies = [
"cfg-if",
"libc",
"wasi",
]

[[package]]
name = "gimli"
version = "0.26.1"
@@ -161,6 +205,15 @@ dependencies = [
"indexmap",
]

[[package]]
name = "hashbrown"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
dependencies = [
"ahash",
]

[[package]]
name = "hashbrown"
version = "0.12.3"
@@ -174,14 +227,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
dependencies = [
"autocfg",
"hashbrown",
"hashbrown 0.12.3",
]

[[package]]
name = "libc"
version = "0.2.119"
version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4"
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"

[[package]]
name = "libloading"
@@ -219,11 +272,12 @@ checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"

[[package]]
name = "object"
version = "0.27.1"
version = "0.28.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67ac1d3f9a1d3616fd9a60c8d74296f22406a238b6a72f5cc1e6f314df4ffbf9"
checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424"
dependencies = [
"crc32fast",
"hashbrown 0.11.2",
"indexmap",
"memchr",
]
@@ -235,13 +289,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"

[[package]]
name = "regalloc"
version = "0.0.34"
name = "regalloc2"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62446b1d3ebf980bdc68837700af1d77b37bc430e524bf95319c6eada2a4cc02"
checksum = "4a8d23b35d7177df3b9d31ed8a9ab4bf625c668be77a319d4f5efd4a5257701c"
dependencies = [
"fxhash",
"log",
"rustc-hash",
"slice-group-by",
"smallvec",
]

@@ -257,12 +312,6 @@ dependencies = [
"winapi",
]

[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"

[[package]]
name = "rustc_codegen_cranelift"
version = "0.1.0"
@@ -283,6 +332,12 @@ dependencies = [
"target-lexicon",
]

[[package]]
name = "slice-group-by"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03b634d87b960ab1a38c4fe143b508576f075e7c978bfad18217645ebfdfa2ec"

[[package]]
name = "smallvec"
version = "1.8.1"
@@ -295,6 +350,18 @@ version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7fa7e55043acb85fca6b3c01485a2eeb6b69c5d21002e273c79e465f43b7ac1"

[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"

[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"

[[package]]
name = "winapi"
version = "0.3.9"
14 changes: 7 additions & 7 deletions compiler/rustc_codegen_cranelift/Cargo.toml
Original file line number Diff line number Diff line change
@@ -8,15 +8,15 @@ crate-type = ["dylib"]

[dependencies]
# These have to be in sync with each other
cranelift-codegen = { version = "0.83.0", features = ["unwind", "all-arch"] }
cranelift-frontend = "0.83.0"
cranelift-module = "0.83.0"
cranelift-native = "0.83.0"
cranelift-jit = { version = "0.83.0", optional = true }
cranelift-object = "0.83.0"
cranelift-codegen = { version = "0.85.3", features = ["unwind", "all-arch"] }
cranelift-frontend = "0.85.3"
cranelift-module = "0.85.3"
cranelift-native = "0.85.3"
cranelift-jit = { version = "0.85.3", optional = true }
cranelift-object = "0.85.3"
target-lexicon = "0.12.0"
gimli = { version = "0.26.0", default-features = false, features = ["write"]}
object = { version = "0.27.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
object = { version = "0.28.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }

ar = { git = "https://github.com/bjorn3/rust-ar.git", branch = "do_not_remove_cg_clif_ranlib" }
indexmap = "1.9.1"
17 changes: 9 additions & 8 deletions compiler/rustc_codegen_cranelift/build_sysroot/Cargo.lock
Original file line number Diff line number Diff line change
@@ -205,7 +205,7 @@ fn build_clif_sysroot_for_triple(
{
let entry = entry.unwrap();
if let Some(ext) = entry.path().extension() {
if ext == "rmeta" || ext == "d" || ext == "dSYM" {
if ext == "rmeta" || ext == "d" || ext == "dSYM" || ext == "clif" {
continue;
}
} else {
6 changes: 3 additions & 3 deletions compiler/rustc_codegen_cranelift/example/mini_core.rs
Original file line number Diff line number Diff line change
@@ -458,7 +458,7 @@ pub trait FnMut<Args>: FnOnce<Args> {

#[lang = "panic"]
#[track_caller]
pub fn panic(_msg: &str) -> ! {
pub fn panic(_msg: &'static str) -> ! {
unsafe {
libc::puts("Panicking\n\0" as *const str as *const i8);
intrinsics::abort();
@@ -497,7 +497,7 @@ pub trait Deref {
#[repr(transparent)]
#[rustc_layout_scalar_valid_range_start(1)]
#[rustc_nonnull_optimization_guaranteed]
pub struct NonNull<T: ?Sized>(pub *mut T);
pub struct NonNull<T: ?Sized>(pub *const T);

impl<T: ?Sized, U: ?Sized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> {}
impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NonNull<U>> for NonNull<T> where T: Unsize<U> {}
@@ -521,7 +521,7 @@ impl<T: ?Sized> Drop for Box<T> {
}
}

impl<T> Deref for Box<T> {
impl<T: ?Sized> Deref for Box<T> {
type Target = T;

fn deref(&self) -> &Self::Target {
42 changes: 42 additions & 0 deletions compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs
Original file line number Diff line number Diff line change
@@ -124,6 +124,23 @@ fn call_return_u128_pair() {
return_u128_pair();
}

#[repr(C)]
pub struct bool_11 {
field0: bool,
field1: bool,
field2: bool,
field3: bool,
field4: bool,
field5: bool,
field6: bool,
field7: bool,
field8: bool,
field9: bool,
field10: bool,
}

extern "C" fn bool_struct_in_11(arg0: bool_11) {}

#[allow(unreachable_code)] // FIXME false positive
fn main() {
take_unique(Unique {
@@ -134,6 +151,20 @@ fn main() {

call_return_u128_pair();

bool_struct_in_11(bool_11 {
field0: true,
field1: true,
field2: true,
field3: true,
field4: true,
field5: true,
field6: true,
field7: true,
field8: true,
field9: true,
field10: true,
});

let slice = &[0, 1] as &[i32];
let slice_ptr = slice as *const [i32] as *const i32;

@@ -299,6 +330,17 @@ fn main() {
static REF1: &u8 = &42;
static REF2: &u8 = REF1;
assert_eq!(*REF1, *REF2);

extern "C" {
type A;
}

fn main() {
let x: &A = unsafe { &*(1usize as *const A) };

assert_eq!(unsafe { intrinsics::size_of_val(x) }, 0);
assert_eq!(unsafe { intrinsics::min_align_of_val(x) }, 1);
}
}

#[cfg(all(not(jit), target_arch = "x86_64", target_os = "linux"))]
19 changes: 19 additions & 0 deletions compiler/rustc_codegen_cranelift/example/std_example.rs
Original file line number Diff line number Diff line change
@@ -128,6 +128,25 @@ fn main() {
0 => loop {},
v => panic(v),
};

if black_box(false) {
// Based on https://github.com/rust-lang/rust/blob/2f320a224e827b400be25966755a621779f797cc/src/test/ui/debuginfo/debuginfo_with_uninhabitable_field_and_unsized.rs
let _ = Foo::<dyn Send>::new();

#[allow(dead_code)]
struct Foo<T: ?Sized> {
base: Never,
value: T,
}

impl<T: ?Sized> Foo<T> {
pub fn new() -> Box<Foo<T>> {
todo!()
}
}

enum Never {}
}
}

fn panic(_: u128) {
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_cranelift/rust-toolchain
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[toolchain]
channel = "nightly-2022-05-15"
channel = "nightly-2022-07-25"
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]
10 changes: 7 additions & 3 deletions compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh
Original file line number Diff line number Diff line change
@@ -29,14 +29,15 @@ diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/ru
index 8431aa7b818..a3ff7e68ce5 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -3489,11 +3489,7 @@ fn normalize_output(&self, output: &str, custom_rules: &[(String, String)]) -> S
.join("library");
normalize_path(&src_dir, "$(echo '$SRC_DIR')");
@@ -3489,12 +3489,7 @@ fn normalize_output(&self, output: &str, custom_rules: &[(String, String)]) -> S
let compiler_src_dir = base_dir.join("compiler");
normalize_path(&compiler_src_dir, "$(echo '$COMPILER_DIR')");
- if let Some(virtual_rust_source_base_dir) =
- option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR").map(PathBuf::from)
- {
- normalize_path(&virtual_rust_source_base_dir.join("library"), "$(echo '$SRC_DIR')");
- normalize_path(&virtual_rust_source_base_dir.join("compiler"), "$(echo '$COMPILER_DIR')");
- }
+ normalize_path(&Path::new("$(cd ../build_sysroot/sysroot_src/library; pwd)"), "$(echo '$SRC_DIR')");
@@ -62,3 +63,6 @@ deny-warnings = false
verbose-tests = false
EOF
popd

# FIXME remove once inline asm is fully supported
export RUSTFLAGS="$RUSTFLAGS --cfg=rustix_use_libc"
12 changes: 8 additions & 4 deletions compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh
Original file line number Diff line number Diff line change
@@ -33,6 +33,7 @@ rm src/test/ui/test-attrs/test-fn-signature-verification-for-explicit-return-typ
rm src/test/ui/async-await/async-fn-size-moved-locals.rs # -Cpanic=abort shrinks some generator by one byte
rm src/test/ui/async-await/async-fn-size-uninit-locals.rs # same
rm src/test/ui/generator/size-moved-locals.rs # same
rm -r src/test/ui/macros/rfc-2011-nicer-assert-messages/

# vendor intrinsics
rm src/test/ui/sse2.rs # cpuid not supported, so sse2 not detected
@@ -65,11 +66,13 @@ rm src/test/ui/intrinsics/intrinsic-nearby.rs # unimplemented nearbyintf32 and n
rm src/test/ui/target-feature/missing-plusminus.rs # error not implemented
rm src/test/ui/fn/dyn-fn-alignment.rs # wants a 256 byte alignment
rm -r src/test/run-make/emit-named-files # requires full --emit support
rm src/test/ui/abi/stack-probes.rs # stack probes not yet implemented

# optimization tests
# ==================
rm src/test/ui/issues/issue-28950.rs # depends on stack size optimizations
rm src/test/ui/codegen/issue-28950.rs # depends on stack size optimizations
rm src/test/ui/codegen/init-large-type.rs # same
rm src/test/ui/issues/issue-40883.rs # same
rm -r src/test/run-make/fmt-write-bloat/ # tests an optimization

# backend specific tests
@@ -89,14 +92,13 @@ rm src/test/ui/consts/issue-33537.rs # same
rm -r src/test/run-make/emit-shared-files # requires the rustdoc executable in build/bin/
rm -r src/test/run-make/unstable-flag-required # same
rm -r src/test/run-make/rustdoc-* # same
rm -r src/test/run-make/issue-88756-default-output # same
rm -r src/test/run-make/remap-path-prefix-dwarf # requires llvm-dwarfdump

# genuine bugs
# ============
rm src/test/ui/allocator/no_std-alloc-error-handler-default.rs # missing rust_oom definition

rm -r src/test/ui/polymorphization/ # polymorphization not yet supported
rm src/test/codegen-units/polymorphization/unused_type_parameters.rs # same

rm src/test/incremental/spike-neg1.rs # errors out for some reason
rm src/test/incremental/spike-neg2.rs # same
rm src/test/ui/issues/issue-74564-if-expr-stack-overflow.rs # gives a stackoverflow before the backend runs
@@ -111,6 +113,8 @@ rm src/test/ui/backtrace.rs # TODO warning
rm src/test/ui/empty_global_asm.rs # TODO add needs-asm-support
rm src/test/ui/simple_global_asm.rs # TODO add needs-asm-support
rm src/test/ui/test-attrs/test-type.rs # TODO panic message on stderr. correct stdout
# not sure if this is actually a bug in the test suite, but the symbol list shows the function without leading _ for some reason
rm -r src/test/run-make/native-link-modifier-bundle

echo "[TEST] rustc test suite"
RUST_TEST_NOCAPTURE=1 COMPILETEST_FORCE_STAGE0=1 ./x.py test --stage 0 src/test/{codegen-units,run-make,run-pass-valgrind,ui,incremental}
34 changes: 30 additions & 4 deletions compiler/rustc_codegen_cranelift/src/abi/mod.rs
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@ mod comments;
mod pass_mode;
mod returning;

use cranelift_module::ModuleError;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::ty::layout::FnAbiOf;
use rustc_target::abi::call::{Conv, FnAbi};
@@ -69,7 +70,17 @@ pub(crate) fn import_function<'tcx>(
) -> FuncId {
let name = tcx.symbol_name(inst).name;
let sig = get_function_sig(tcx, module.isa().triple(), inst);
module.declare_function(name, Linkage::Import, &sig).unwrap()
match module.declare_function(name, Linkage::Import, &sig) {
Ok(func_id) => func_id,
Err(ModuleError::IncompatibleDeclaration(_)) => tcx.sess.fatal(&format!(
"attempt to declare `{name}` as function, but it was already declared as static"
)),
Err(ModuleError::IncompatibleSignature(_, prev_sig, new_sig)) => tcx.sess.fatal(&format!(
"attempt to declare `{name}` with signature {new_sig:?}, \
but it was already declared with signature {prev_sig:?}"
)),
Err(err) => Err::<_, _>(err).unwrap(),
}
}

impl<'tcx> FunctionCx<'_, '_, 'tcx> {
@@ -182,6 +193,15 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_
}

let fn_abi = fx.fn_abi.take().unwrap();

// FIXME implement variadics in cranelift
if fn_abi.c_variadic {
fx.tcx.sess.span_fatal(
fx.mir.span,
"Defining variadic functions is not yet supported by Cranelift",
);
}

let mut arg_abis_iter = fn_abi.args.iter();

let func_params = fx
@@ -376,9 +396,15 @@ pub(crate) fn codegen_terminator_call<'tcx>(
RevealAllLayoutCx(fx.tcx).fn_abi_of_fn_ptr(fn_ty.fn_sig(fx.tcx), extra_args)
};

let is_cold = instance
.map(|inst| fx.tcx.codegen_fn_attrs(inst.def_id()).flags.contains(CodegenFnAttrFlags::COLD))
.unwrap_or(false);
let is_cold = if fn_sig.abi == Abi::RustCold {
true
} else {
instance
.map(|inst| {
fx.tcx.codegen_fn_attrs(inst.def_id()).flags.contains(CodegenFnAttrFlags::COLD)
})
.unwrap_or(false)
};
if is_cold {
fx.bcx.set_cold_block(fx.bcx.current_block().unwrap());
if let Some(destination_block) = target {
28 changes: 7 additions & 21 deletions compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs
Original file line number Diff line number Diff line change
@@ -18,9 +18,9 @@ fn reg_to_abi_param(reg: Reg) -> AbiParam {
let clif_ty = match (reg.kind, reg.size.bytes()) {
(RegKind::Integer, 1) => types::I8,
(RegKind::Integer, 2) => types::I16,
(RegKind::Integer, 4) => types::I32,
(RegKind::Integer, 8) => types::I64,
(RegKind::Integer, 16) => types::I128,
(RegKind::Integer, 3..=4) => types::I32,
(RegKind::Integer, 5..=8) => types::I64,
(RegKind::Integer, 9..=16) => types::I128,
(RegKind::Float, 4) => types::F32,
(RegKind::Float, 8) => types::F64,
(RegKind::Vector, size) => types::I8.by(u16::try_from(size).unwrap()).unwrap(),
@@ -48,23 +48,9 @@ fn cast_target_to_abi_params(cast: CastTarget) -> SmallVec<[AbiParam; 2]> {
)
};

if cast.prefix.iter().all(|x| x.is_none()) {
// Simplify to a single unit when there is no prefix and size <= unit size
if cast.rest.total <= cast.rest.unit.size {
let clif_ty = match (cast.rest.unit.kind, cast.rest.unit.size.bytes()) {
(RegKind::Integer, 1) => types::I8,
(RegKind::Integer, 2) => types::I16,
(RegKind::Integer, 3..=4) => types::I32,
(RegKind::Integer, 5..=8) => types::I64,
(RegKind::Integer, 9..=16) => types::I128,
(RegKind::Float, 4) => types::F32,
(RegKind::Float, 8) => types::F64,
(RegKind::Vector, size) => types::I8.by(u16::try_from(size).unwrap()).unwrap(),
_ => unreachable!("{:?}", cast.rest.unit),
};
return smallvec![AbiParam::new(clif_ty)];
}
}
// Note: Unlike the LLVM equivalent of this code we don't have separate branches for when there
// is no prefix as a single unit, an array and a heterogeneous struct are not represented using
// different types in Cranelift IR. Instead a single array of primitive types is used.

// Create list of fields in the main structure
let mut args = cast
@@ -230,7 +216,7 @@ pub(super) fn adjust_arg_for_abi<'tcx>(
arg_abi: &ArgAbi<'tcx, Ty<'tcx>>,
is_owned: bool,
) -> SmallVec<[Value; 2]> {
assert_assignable(fx, arg.layout().ty, arg_abi.layout.ty);
assert_assignable(fx, arg.layout().ty, arg_abi.layout.ty, 16);
match arg_abi.mode {
PassMode::Ignore => smallvec![],
PassMode::Direct(_) => smallvec![arg.load_scalar(fx)],
19 changes: 18 additions & 1 deletion compiler/rustc_codegen_cranelift/src/archive.rs
Original file line number Diff line number Diff line change
@@ -86,7 +86,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {

let mut entries = Vec::new();

for (entry_name, entry) in self.entries {
for (mut entry_name, entry) in self.entries {
// FIXME only read the symbol table of the object files to avoid having to keep all
// object files in memory at once, or read them twice.
let data = match entry {
@@ -109,6 +109,23 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
};

if !self.no_builtin_ranlib {
if symbol_table.contains_key(&entry_name) {
// The ar crate can't handle creating a symbol table in case of multiple archive
// members with the same name. Work around this by prepending a number until we
// get a unique name.
for i in 1.. {
let new_name = format!("{}_", i)
.into_bytes()
.into_iter()
.chain(entry_name.iter().copied())
.collect::<Vec<_>>();
if !symbol_table.contains_key(&new_name) {
entry_name = new_name;
break;
}
}
}

match object::File::parse(&*data) {
Ok(object) => {
symbol_table.insert(
39 changes: 29 additions & 10 deletions compiler/rustc_codegen_cranelift/src/base.rs
Original file line number Diff line number Diff line change
@@ -175,10 +175,37 @@ fn compile_fn<'tcx>(
);
});

#[cfg(any())] // This is never true
let _clif_guard = {
use std::fmt::Write;

let func_clone = context.func.clone();
let clif_comments_clone = clif_comments.clone();
let mut clif = String::new();
for flag in module.isa().flags().iter() {
writeln!(clif, "set {}", flag).unwrap();
}
write!(clif, "target {}", module.isa().triple().architecture.to_string()).unwrap();
for isa_flag in module.isa().isa_flags().iter() {
write!(clif, " {}", isa_flag).unwrap();
}
writeln!(clif, "\n").unwrap();
crate::PrintOnPanic(move || {
let mut clif = clif.clone();
::cranelift_codegen::write::decorate_function(
&mut &clif_comments_clone,
&mut clif,
&func_clone,
)
.unwrap();
clif
})
};

// Define function
tcx.sess.time("define function", || {
context.want_disasm = crate::pretty_clif::should_write_ir(tcx);
module.define_function(func_id, context).unwrap()
module.define_function(func_id, context).unwrap();
});

// Write optimized function to file for debugging
@@ -815,15 +842,7 @@ pub(crate) fn codegen_place<'tcx>(
for elem in place.projection {
match elem {
PlaceElem::Deref => {
if cplace.layout().ty.is_box() {
cplace = cplace
.place_field(fx, Field::new(0)) // Box<T> -> Unique<T>
.place_field(fx, Field::new(0)) // Unique<T> -> NonNull<T>
.place_field(fx, Field::new(0)) // NonNull<T> -> *mut T
.place_deref(fx);
} else {
cplace = cplace.place_deref(fx);
}
cplace = cplace.place_deref(fx);
}
PlaceElem::Field(field, _ty) => {
cplace = cplace.place_field(fx, field);
13 changes: 2 additions & 11 deletions compiler/rustc_codegen_cranelift/src/cast.rs
Original file line number Diff line number Diff line change
@@ -149,17 +149,8 @@ pub(crate) fn clif_int_or_float_cast(
}

let is_not_nan = fx.bcx.ins().fcmp(FloatCC::Equal, from, from);
if to_ty == types::I128 {
// FIXME(bytecodealliance/wasmtime#3963): select.i128 on fcmp eq miscompiles
let (lsb, msb) = fx.bcx.ins().isplit(val);
let zero = fx.bcx.ins().iconst(types::I64, 0);
let lsb = fx.bcx.ins().select(is_not_nan, lsb, zero);
let msb = fx.bcx.ins().select(is_not_nan, msb, zero);
fx.bcx.ins().iconcat(lsb, msb)
} else {
let zero = fx.bcx.ins().iconst(to_ty, 0);
fx.bcx.ins().select(is_not_nan, val, zero)
}
let zero = fx.bcx.ins().iconst(to_ty, 0);
fx.bcx.ins().select(is_not_nan, val, zero)
} else if from_ty.is_float() && to_ty.is_float() {
// float -> float
match (from_ty, to_ty) {
23 changes: 14 additions & 9 deletions compiler/rustc_codegen_cranelift/src/constant.rs
Original file line number Diff line number Diff line change
@@ -328,14 +328,18 @@ fn data_id_for_static(

let attrs = tcx.codegen_fn_attrs(def_id);

let data_id = module
.declare_data(
&*symbol_name,
linkage,
is_mutable,
attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL),
)
.unwrap();
let data_id = match module.declare_data(
&*symbol_name,
linkage,
is_mutable,
attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL),
) {
Ok(data_id) => data_id,
Err(ModuleError::IncompatibleDeclaration(_)) => tcx.sess.fatal(&format!(
"attempt to declare `{symbol_name}` as static, but it was already declared as function"
)),
Err(err) => Err::<_, _>(err).unwrap(),
};

if rlinkage.is_some() {
// Comment copied from https://github.com/rust-lang/rust/blob/45060c2a66dfd667f88bd8b94261b28a58d85bd5/src/librustc_codegen_llvm/consts.rs#L141
@@ -441,7 +445,8 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
let data_id = match reloc_target_alloc {
GlobalAlloc::Function(instance) => {
assert_eq!(addend, 0);
let func_id = crate::abi::import_function(tcx, module, instance);
let func_id =
crate::abi::import_function(tcx, module, instance.polymorphize(tcx));
let local_func_id = module.declare_func_in_data(func_id, &mut data_ctx);
data_ctx.write_function_addr(offset.bytes() as u32, local_func_id);
continue;
170 changes: 90 additions & 80 deletions compiler/rustc_codegen_cranelift/src/inline_asm.rs
Original file line number Diff line number Diff line change
@@ -18,86 +18,96 @@ pub(crate) fn codegen_inline_asm<'tcx>(
) {
// FIXME add .eh_frame unwind info directives

if template[0] == InlineAsmTemplatePiece::String("int $$0x29".to_string()) {
let true_ = fx.bcx.ins().iconst(types::I32, 1);
fx.bcx.ins().trapnz(true_, TrapCode::User(1));
return;
} else if template[0] == InlineAsmTemplatePiece::String("movq %rbx, ".to_string())
&& matches!(
template[1],
InlineAsmTemplatePiece::Placeholder { operand_idx: 0, modifier: Some('r'), span: _ }
)
&& template[2] == InlineAsmTemplatePiece::String("\n".to_string())
&& template[3] == InlineAsmTemplatePiece::String("cpuid".to_string())
&& template[4] == InlineAsmTemplatePiece::String("\n".to_string())
&& template[5] == InlineAsmTemplatePiece::String("xchgq %rbx, ".to_string())
&& matches!(
template[6],
InlineAsmTemplatePiece::Placeholder { operand_idx: 0, modifier: Some('r'), span: _ }
)
{
assert_eq!(operands.len(), 4);
let (leaf, eax_place) = match operands[1] {
InlineAsmOperand::InOut { reg, late: true, ref in_value, out_place } => {
assert_eq!(
reg,
InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::ax))
);
(
crate::base::codegen_operand(fx, in_value).load_scalar(fx),
crate::base::codegen_place(fx, out_place.unwrap()),
)
}
_ => unreachable!(),
};
let ebx_place = match operands[0] {
InlineAsmOperand::Out { reg, late: true, place } => {
assert_eq!(
reg,
InlineAsmRegOrRegClass::RegClass(InlineAsmRegClass::X86(
X86InlineAsmRegClass::reg
))
);
crate::base::codegen_place(fx, place.unwrap())
}
_ => unreachable!(),
};
let (sub_leaf, ecx_place) = match operands[2] {
InlineAsmOperand::InOut { reg, late: true, ref in_value, out_place } => {
assert_eq!(
reg,
InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::cx))
);
(
crate::base::codegen_operand(fx, in_value).load_scalar(fx),
crate::base::codegen_place(fx, out_place.unwrap()),
)
}
_ => unreachable!(),
};
let edx_place = match operands[3] {
InlineAsmOperand::Out { reg, late: true, place } => {
assert_eq!(
reg,
InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::dx))
);
crate::base::codegen_place(fx, place.unwrap())
}
_ => unreachable!(),
};

let (eax, ebx, ecx, edx) = crate::intrinsics::codegen_cpuid_call(fx, leaf, sub_leaf);

eax_place.write_cvalue(fx, CValue::by_val(eax, fx.layout_of(fx.tcx.types.u32)));
ebx_place.write_cvalue(fx, CValue::by_val(ebx, fx.layout_of(fx.tcx.types.u32)));
ecx_place.write_cvalue(fx, CValue::by_val(ecx, fx.layout_of(fx.tcx.types.u32)));
edx_place.write_cvalue(fx, CValue::by_val(edx, fx.layout_of(fx.tcx.types.u32)));
return;
} else if fx.tcx.symbol_name(fx.instance).name.starts_with("___chkstk") {
// ___chkstk, ___chkstk_ms and __alloca are only used on Windows
crate::trap::trap_unimplemented(fx, "Stack probes are not supported");
} else if fx.tcx.symbol_name(fx.instance).name == "__alloca" {
crate::trap::trap_unimplemented(fx, "Alloca is not supported");
if !template.is_empty() {
if template[0] == InlineAsmTemplatePiece::String("int $$0x29".to_string()) {
let true_ = fx.bcx.ins().iconst(types::I32, 1);
fx.bcx.ins().trapnz(true_, TrapCode::User(1));
return;
} else if template[0] == InlineAsmTemplatePiece::String("movq %rbx, ".to_string())
&& matches!(
template[1],
InlineAsmTemplatePiece::Placeholder {
operand_idx: 0,
modifier: Some('r'),
span: _
}
)
&& template[2] == InlineAsmTemplatePiece::String("\n".to_string())
&& template[3] == InlineAsmTemplatePiece::String("cpuid".to_string())
&& template[4] == InlineAsmTemplatePiece::String("\n".to_string())
&& template[5] == InlineAsmTemplatePiece::String("xchgq %rbx, ".to_string())
&& matches!(
template[6],
InlineAsmTemplatePiece::Placeholder {
operand_idx: 0,
modifier: Some('r'),
span: _
}
)
{
assert_eq!(operands.len(), 4);
let (leaf, eax_place) = match operands[1] {
InlineAsmOperand::InOut { reg, late: true, ref in_value, out_place } => {
assert_eq!(
reg,
InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::ax))
);
(
crate::base::codegen_operand(fx, in_value).load_scalar(fx),
crate::base::codegen_place(fx, out_place.unwrap()),
)
}
_ => unreachable!(),
};
let ebx_place = match operands[0] {
InlineAsmOperand::Out { reg, late: true, place } => {
assert_eq!(
reg,
InlineAsmRegOrRegClass::RegClass(InlineAsmRegClass::X86(
X86InlineAsmRegClass::reg
))
);
crate::base::codegen_place(fx, place.unwrap())
}
_ => unreachable!(),
};
let (sub_leaf, ecx_place) = match operands[2] {
InlineAsmOperand::InOut { reg, late: true, ref in_value, out_place } => {
assert_eq!(
reg,
InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::cx))
);
(
crate::base::codegen_operand(fx, in_value).load_scalar(fx),
crate::base::codegen_place(fx, out_place.unwrap()),
)
}
_ => unreachable!(),
};
let edx_place = match operands[3] {
InlineAsmOperand::Out { reg, late: true, place } => {
assert_eq!(
reg,
InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::dx))
);
crate::base::codegen_place(fx, place.unwrap())
}
_ => unreachable!(),
};

let (eax, ebx, ecx, edx) = crate::intrinsics::codegen_cpuid_call(fx, leaf, sub_leaf);

eax_place.write_cvalue(fx, CValue::by_val(eax, fx.layout_of(fx.tcx.types.u32)));
ebx_place.write_cvalue(fx, CValue::by_val(ebx, fx.layout_of(fx.tcx.types.u32)));
ecx_place.write_cvalue(fx, CValue::by_val(ecx, fx.layout_of(fx.tcx.types.u32)));
edx_place.write_cvalue(fx, CValue::by_val(edx, fx.layout_of(fx.tcx.types.u32)));
return;
} else if fx.tcx.symbol_name(fx.instance).name.starts_with("___chkstk") {
// ___chkstk, ___chkstk_ms and __alloca are only used on Windows
crate::trap::trap_unimplemented(fx, "Stack probes are not supported");
} else if fx.tcx.symbol_name(fx.instance).name == "__alloca" {
crate::trap::trap_unimplemented(fx, "Alloca is not supported");
}
}

let mut inputs = Vec::new();
22 changes: 20 additions & 2 deletions compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
Original file line number Diff line number Diff line change
@@ -404,7 +404,9 @@ fn codegen_regular_intrinsic_call<'tcx>(
};
size_of_val, (c ptr) {
let layout = fx.layout_of(substs.type_at(0));
let size = if layout.is_unsized() {
// Note: Can't use is_unsized here as truly unsized types need to take the fixed size
// branch
let size = if let Abi::ScalarPair(_, _) = ptr.layout().abi {
let (_ptr, info) = ptr.load_scalar_pair(fx);
let (size, _align) = crate::unsize::size_and_align_of_dst(fx, layout, info);
size
@@ -418,7 +420,9 @@ fn codegen_regular_intrinsic_call<'tcx>(
};
min_align_of_val, (c ptr) {
let layout = fx.layout_of(substs.type_at(0));
let align = if layout.is_unsized() {
// Note: Can't use is_unsized here as truly unsized types need to take the fixed size
// branch
let align = if let Abi::ScalarPair(_, _) = ptr.layout().abi {
let (_ptr, info) = ptr.load_scalar_pair(fx);
let (_size, align) = crate::unsize::size_and_align_of_dst(fx, layout, info);
align
@@ -1145,6 +1149,20 @@ fn codegen_regular_intrinsic_call<'tcx>(
// FIXME implement black_box semantics
ret.write_cvalue(fx, a);
};

// FIXME implement variadics in cranelift
va_copy, (o _dest, o _src) {
fx.tcx.sess.span_fatal(
source_info.span,
"Defining variadic functions is not yet supported by Cranelift",
);
};
va_arg | va_end, (o _valist) {
fx.tcx.sess.span_fatal(
source_info.span,
"Defining variadic functions is not yet supported by Cranelift",
);
};
}

let ret_block = fx.get_block(destination.unwrap());
7 changes: 6 additions & 1 deletion compiler/rustc_codegen_cranelift/src/lib.rs
Original file line number Diff line number Diff line change
@@ -141,7 +141,11 @@ impl<'tcx> CodegenCx<'tcx> {

let unwind_context =
UnwindContext::new(isa, matches!(backend_config.codegen_mode, CodegenMode::Aot));
let debug_context = if debug_info { Some(DebugContext::new(tcx, isa)) } else { None };
let debug_context = if debug_info && !tcx.sess.target.options.is_like_windows {
Some(DebugContext::new(tcx, isa))
} else {
None
};
CodegenCx {
tcx,
global_asm: String::new(),
@@ -243,6 +247,7 @@ fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Box<dyn isa::Tar
flags_builder.set("enable_probestack", "false").unwrap(); // __cranelift_probestack is not provided
let enable_verifier = if backend_config.enable_verifier { "true" } else { "false" };
flags_builder.set("enable_verifier", enable_verifier).unwrap();
flags_builder.set("regalloc_checker", enable_verifier).unwrap();

let tls_model = match target_triple.binary_format {
BinaryFormat::Elf => "elf_gd",
3 changes: 2 additions & 1 deletion compiler/rustc_codegen_cranelift/src/main_shim.rs
Original file line number Diff line number Diff line change
@@ -109,7 +109,8 @@ pub(crate) fn maybe_create_entry_wrapper(
tcx.mk_substs([GenericArg::from(main_ret_ty)].iter()),
)
.unwrap()
.unwrap();
.unwrap()
.polymorphize(tcx);

let report_name = tcx.symbol_name(report).name;
let report_sig = get_function_sig(tcx, m.isa().triple(), report);
3 changes: 2 additions & 1 deletion compiler/rustc_codegen_cranelift/src/pretty_clif.rs
Original file line number Diff line number Diff line change
@@ -66,7 +66,7 @@ use rustc_session::config::OutputType;

use crate::prelude::*;

#[derive(Debug)]
#[derive(Clone, Debug)]
pub(crate) struct CommentWriter {
enabled: bool,
global_comments: Vec<String>,
@@ -237,6 +237,7 @@ pub(crate) fn write_clif_file<'tcx>(
func: &cranelift_codegen::ir::Function,
mut clif_comments: &CommentWriter,
) {
// FIXME work around filename too long errors
write_ir_file(
tcx,
|| format!("{}.{}.clif", tcx.symbol_name(instance).name, postfix),
6 changes: 1 addition & 5 deletions compiler/rustc_codegen_cranelift/src/unsize.rs
Original file line number Diff line number Diff line change
@@ -153,11 +153,7 @@ pub(crate) fn size_and_align_of_dst<'tcx>(
layout: TyAndLayout<'tcx>,
info: Value,
) -> (Value, Value) {
if !layout.is_unsized() {
let size = fx.bcx.ins().iconst(fx.pointer_type, layout.size.bytes() as i64);
let align = fx.bcx.ins().iconst(fx.pointer_type, layout.align.abi.bytes() as i64);
return (size, align);
}
assert!(layout.is_unsized() || layout.abi == Abi::Uninhabited);
match layout.ty.kind() {
ty::Dynamic(..) => {
// load size/align from vtable
57 changes: 50 additions & 7 deletions compiler/rustc_codegen_cranelift/src/value_and_place.rs
Original file line number Diff line number Diff line change
@@ -324,6 +324,12 @@ impl<'tcx> CPlace<'tcx> {
};
}

if layout.size.bytes() >= u64::from(u32::MAX - 16) {
fx.tcx
.sess
.fatal(&format!("values of type {} are too big to store on the stack", layout.ty));
}

let stack_slot = fx.bcx.create_stack_slot(StackSlotData {
kind: StackSlotKind::ExplicitSlot,
// FIXME Don't force the size to a multiple of 16 bytes once Cranelift gets a way to
@@ -420,7 +426,7 @@ impl<'tcx> CPlace<'tcx> {
}

pub(crate) fn write_cvalue(self, fx: &mut FunctionCx<'_, '_, 'tcx>, from: CValue<'tcx>) {
assert_assignable(fx, from.layout().ty, self.layout().ty);
assert_assignable(fx, from.layout().ty, self.layout().ty, 16);

self.write_cvalue_maybe_transmute(fx, from, "write_cvalue");
}
@@ -774,18 +780,25 @@ pub(crate) fn assert_assignable<'tcx>(
fx: &FunctionCx<'_, '_, 'tcx>,
from_ty: Ty<'tcx>,
to_ty: Ty<'tcx>,
limit: usize,
) {
if limit == 0 {
// assert_assignable exists solely to catch bugs in cg_clif. it isn't necessary for
// soundness. don't attempt to check deep types to avoid exponential behavior in certain
// cases.
return;
}
match (from_ty.kind(), to_ty.kind()) {
(ty::Ref(_, a, _), ty::Ref(_, b, _))
| (
ty::RawPtr(TypeAndMut { ty: a, mutbl: _ }),
ty::RawPtr(TypeAndMut { ty: b, mutbl: _ }),
) => {
assert_assignable(fx, *a, *b);
assert_assignable(fx, *a, *b, limit - 1);
}
(ty::Ref(_, a, _), ty::RawPtr(TypeAndMut { ty: b, mutbl: _ }))
| (ty::RawPtr(TypeAndMut { ty: a, mutbl: _ }), ty::Ref(_, b, _)) => {
assert_assignable(fx, *a, *b);
assert_assignable(fx, *a, *b, limit - 1);
}
(ty::FnPtr(_), ty::FnPtr(_)) => {
let from_sig = fx.tcx.normalize_erasing_late_bound_regions(
@@ -815,25 +828,55 @@ pub(crate) fn assert_assignable<'tcx>(
}
// dyn for<'r> Trait<'r> -> dyn Trait<'_> is allowed
}
(&ty::Tuple(types_a), &ty::Tuple(types_b)) => {
let mut types_a = types_a.iter();
let mut types_b = types_b.iter();
loop {
match (types_a.next(), types_b.next()) {
(Some(a), Some(b)) => assert_assignable(fx, a, b, limit - 1),
(None, None) => return,
(Some(_), None) | (None, Some(_)) => panic!("{:#?}/{:#?}", from_ty, to_ty),
}
}
}
(&ty::Adt(adt_def_a, substs_a), &ty::Adt(adt_def_b, substs_b))
if adt_def_a.did() == adt_def_b.did() =>
{
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),
(Some(a), Some(b)) => assert_assignable(fx, a, b, limit - 1),
(None, None) => return,
(Some(_), None) | (None, Some(_)) => panic!("{:#?}/{:#?}", from_ty, to_ty),
}
}
}
(ty::Array(a, _), ty::Array(b, _)) => assert_assignable(fx, *a, *b),
(ty::Array(a, _), ty::Array(b, _)) => assert_assignable(fx, *a, *b, limit - 1),
(&ty::Closure(def_id_a, substs_a), &ty::Closure(def_id_b, substs_b))
if def_id_a == def_id_b =>
{
let mut types_a = substs_a.types();
let mut types_b = substs_b.types();
loop {
match (types_a.next(), types_b.next()) {
(Some(a), Some(b)) => assert_assignable(fx, a, b, limit - 1),
(None, None) => return,
(Some(_), None) | (None, Some(_)) => panic!("{:#?}/{:#?}", from_ty, to_ty),
}
}
}
(ty::Param(_), _) | (_, ty::Param(_)) if fx.tcx.sess.opts.unstable_opts.polymorphize => {
// No way to check if it is correct or not with polymorphization enabled
}
_ => {
assert_eq!(
from_ty, to_ty,
from_ty,
to_ty,
"Can't write value with incompatible type {:?} to place with type {:?}\n\n{:#?}",
from_ty, to_ty, fx,
from_ty.kind(),
to_ty.kind(),
fx,
);
}
}
26 changes: 20 additions & 6 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
@@ -1883,7 +1883,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
exp_span, exp_found.expected, exp_found.found,
);

if let ObligationCauseCode::CompareImplMethodObligation { .. } = cause.code() {
if let ObligationCauseCode::CompareImplItemObligation { .. } = cause.code() {
return;
}

@@ -2351,7 +2351,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
GenericKind::Projection(ref p) => format!("the associated type `{}`", p),
};

if let Some(SubregionOrigin::CompareImplMethodObligation {
if let Some(SubregionOrigin::CompareImplItemObligation {
span,
impl_item_def_id,
trait_item_def_id,
@@ -2788,8 +2788,15 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
use self::FailureCode::*;
use crate::traits::ObligationCauseCode::*;
match self.code() {
CompareImplMethodObligation { .. } => Error0308("method not compatible with trait"),
CompareImplTypeObligation { .. } => Error0308("type not compatible with trait"),
CompareImplItemObligation { kind: ty::AssocKind::Fn, .. } => {
Error0308("method not compatible with trait")
}
CompareImplItemObligation { kind: ty::AssocKind::Type, .. } => {
Error0308("type not compatible with trait")
}
CompareImplItemObligation { kind: ty::AssocKind::Const, .. } => {
Error0308("const not compatible with trait")
}
MatchExpressionArm(box MatchExpressionArmCause { source, .. }) => {
Error0308(match source {
hir::MatchSource::TryDesugar => "`?` operator has incompatible types",
@@ -2823,8 +2830,15 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
fn as_requirement_str(&self) -> &'static str {
use crate::traits::ObligationCauseCode::*;
match self.code() {
CompareImplMethodObligation { .. } => "method type is compatible with trait",
CompareImplTypeObligation { .. } => "associated type is compatible with trait",
CompareImplItemObligation { kind: ty::AssocKind::Fn, .. } => {
"method type is compatible with trait"
}
CompareImplItemObligation { kind: ty::AssocKind::Type, .. } => {
"associated type is compatible with trait"
}
CompareImplItemObligation { kind: ty::AssocKind::Const, .. } => {
"const is compatible with trait"
}
ExprAssignable => "expression is assignable",
IfExpression { .. } => "`if` and `else` have incompatible types",
IfExpressionWithNoElse => "`if` missing an `else` returns `()`",
Original file line number Diff line number Diff line change
@@ -2,17 +2,17 @@
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
use crate::infer::lexical_region_resolve::RegionResolutionError;
use crate::infer::{SubregionOrigin, Subtype};
use crate::traits::ObligationCauseCode::CompareImplMethodObligation;
use crate::infer::Subtype;
use crate::traits::ObligationCauseCode::CompareImplItemObligation;
use rustc_errors::{ErrorGuaranteed, MultiSpan};
use rustc_hir as hir;
use rustc_hir::def::Res;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::Visitor;
use rustc_middle::hir::nested_filter;
use rustc_middle::ty::print::RegionHighlightMode;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor};
use rustc_span::{Span, Symbol};
use rustc_span::Span;

use std::ops::ControlFlow;

@@ -22,38 +22,22 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
let error = self.error.as_ref()?;
debug!("try_report_impl_not_conforming_to_trait {:?}", error);
if let RegionResolutionError::SubSupConflict(
_, var_origin, sub_origin, _sub, sup_origin, _sup, _,
_,
var_origin,
sub_origin,
_sub,
sup_origin,
_sup,
_,
) = error.clone()
&& let (&Subtype(ref sup_trace), &Subtype(ref sub_trace)) = (&sup_origin, &sub_origin)
&& let (
sub_expected_found @ Some((sub_expected, sub_found)),
sup_expected_found @ Some(_),
CompareImplMethodObligation { trait_item_def_id, .. },
) = (sub_trace.values.ty(), sup_trace.values.ty(), sub_trace.cause.code())
&& let (Subtype(sup_trace), Subtype(sub_trace)) = (&sup_origin, &sub_origin)
&& let sub_expected_found @ Some((sub_expected, sub_found)) = sub_trace.values.ty()
&& let sup_expected_found @ Some(_) = sup_trace.values.ty()
&& let CompareImplItemObligation { trait_item_def_id, .. } = sub_trace.cause.code()
&& sup_expected_found == sub_expected_found
{
let guar = self.emit_err(
var_origin.span(),
sub_expected,
sub_found,
*trait_item_def_id,
);
return Some(guar);
}
if let RegionResolutionError::ConcreteFailure(origin, _, _)
| RegionResolutionError::GenericBoundFailure(origin, _, _) = error.clone()
&& let SubregionOrigin::CompareImplTypeObligation {
span,
impl_item_def_id,
trait_item_def_id,
} = origin
{
let guar = self.emit_associated_type_err(
span,
self.infcx.tcx.item_name(impl_item_def_id.to_def_id()),
impl_item_def_id,
trait_item_def_id,
);
let guar =
self.emit_err(var_origin.span(), sub_expected, sub_found, *trait_item_def_id);
return Some(guar);
}
None
@@ -147,25 +131,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
}
err.emit()
}

fn emit_associated_type_err(
&self,
span: Span,
item_name: Symbol,
impl_item_def_id: LocalDefId,
trait_item_def_id: DefId,
) -> ErrorGuaranteed {
let impl_sp = self.tcx().def_span(impl_item_def_id);
let trait_sp = self.tcx().def_span(trait_item_def_id);
let mut err = self
.tcx()
.sess
.struct_span_err(span, &format!("`impl` associated type signature for `{}` doesn't match `trait` associated type signature", item_name));
err.span_label(impl_sp, "found");
err.span_label(trait_sp, "expected");

err.emit()
}
}

struct TypeParamSpanVisitor<'tcx> {
18 changes: 2 additions & 16 deletions compiler/rustc_infer/src/infer/error_reporting/note.rs
Original file line number Diff line number Diff line change
@@ -86,13 +86,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
"...so that the declared lifetime parameter bounds are satisfied",
);
}
infer::CompareImplMethodObligation { span, .. } => {
label_or_note(
span,
"...so that the definition in impl matches the definition from the trait",
);
}
infer::CompareImplTypeObligation { span, .. } => {
infer::CompareImplItemObligation { span, .. } => {
label_or_note(
span,
"...so that the definition in impl matches the definition from the trait",
@@ -329,15 +323,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
);
err
}
infer::CompareImplMethodObligation { span, impl_item_def_id, trait_item_def_id } => {
self.report_extra_impl_obligation(
span,
impl_item_def_id,
trait_item_def_id,
&format!("`{}: {}`", sup, sub),
)
}
infer::CompareImplTypeObligation { span, impl_item_def_id, trait_item_def_id } => self
infer::CompareImplItemObligation { span, impl_item_def_id, trait_item_def_id } => self
.report_extra_impl_obligation(
span,
impl_item_def_id,
27 changes: 5 additions & 22 deletions compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
@@ -405,15 +405,7 @@ pub enum SubregionOrigin<'tcx> {

/// Comparing the signature and requirements of an impl method against
/// the containing trait.
CompareImplMethodObligation {
span: Span,
impl_item_def_id: LocalDefId,
trait_item_def_id: DefId,
},

/// Comparing the signature and requirements of an impl associated type
/// against the containing trait
CompareImplTypeObligation { span: Span, impl_item_def_id: LocalDefId, trait_item_def_id: DefId },
CompareImplItemObligation { span: Span, impl_item_def_id: LocalDefId, trait_item_def_id: DefId },

/// Checking that the bounds of a trait's associated type hold for a given impl
CheckAssociatedTypeBounds {
@@ -1945,8 +1937,7 @@ impl<'tcx> SubregionOrigin<'tcx> {
ReborrowUpvar(a, _) => a,
DataBorrowed(_, a) => a,
ReferenceOutlivesReferent(_, a) => a,
CompareImplMethodObligation { span, .. } => span,
CompareImplTypeObligation { span, .. } => span,
CompareImplItemObligation { span, .. } => span,
CheckAssociatedTypeBounds { ref parent, .. } => parent.span(),
}
}
@@ -1960,19 +1951,11 @@ impl<'tcx> SubregionOrigin<'tcx> {
SubregionOrigin::ReferenceOutlivesReferent(ref_type, cause.span)
}

traits::ObligationCauseCode::CompareImplMethodObligation {
impl_item_def_id,
trait_item_def_id,
} => SubregionOrigin::CompareImplMethodObligation {
span: cause.span,
impl_item_def_id,
trait_item_def_id,
},

traits::ObligationCauseCode::CompareImplTypeObligation {
traits::ObligationCauseCode::CompareImplItemObligation {
impl_item_def_id,
trait_item_def_id,
} => SubregionOrigin::CompareImplTypeObligation {
kind: _,
} => SubregionOrigin::CompareImplItemObligation {
span: cause.span,
impl_item_def_id,
trait_item_def_id,
12 changes: 2 additions & 10 deletions compiler/rustc_middle/src/traits/mod.rs
Original file line number Diff line number Diff line change
@@ -311,18 +311,10 @@ pub enum ObligationCauseCode<'tcx> {
},

/// Error derived when matching traits/impls; see ObligationCause for more details
CompareImplConstObligation,

/// Error derived when matching traits/impls; see ObligationCause for more details
CompareImplMethodObligation {
impl_item_def_id: LocalDefId,
trait_item_def_id: DefId,
},

/// Error derived when matching traits/impls; see ObligationCause for more details
CompareImplTypeObligation {
CompareImplItemObligation {
impl_item_def_id: LocalDefId,
trait_item_def_id: DefId,
kind: ty::AssocKind,
},

/// Checking that the bounds of a trait's associated type hold for a given impl
10 changes: 10 additions & 0 deletions compiler/rustc_middle/src/ty/assoc.rs
Original file line number Diff line number Diff line change
@@ -105,6 +105,16 @@ impl AssocKind {
}
}

impl std::fmt::Display for AssocKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
AssocKind::Fn => write!(f, "method"),
AssocKind::Const => write!(f, "associated const"),
AssocKind::Type => write!(f, "associated type"),
}
}
}

/// A list of `ty::AssocItem`s in definition order that allows for efficient lookup by name.
///
/// When doing lookup by name, we try to postpone hygienic comparison for as long as possible since
8 changes: 2 additions & 6 deletions compiler/rustc_middle/src/ty/error.rs
Original file line number Diff line number Diff line change
@@ -660,12 +660,8 @@ impl<T> Trait<T> for X {
| hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(..), .. }),
)
);
let impl_comparison = matches!(
cause_code,
ObligationCauseCode::CompareImplMethodObligation { .. }
| ObligationCauseCode::CompareImplTypeObligation { .. }
| ObligationCauseCode::CompareImplConstObligation
);
let impl_comparison =
matches!(cause_code, ObligationCauseCode::CompareImplItemObligation { .. });
let assoc = self.associated_item(proj_ty.item_def_id);
if !callable_scope || impl_comparison {
// We do not want to suggest calling functions when the reason of the
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/ty/structural_impls.rs
Original file line number Diff line number Diff line change
@@ -224,6 +224,7 @@ TrivialTypeTraversalAndLiftImpls! {
// general `Region`.
crate::ty::BoundRegionKind,
crate::ty::AssocItem,
crate::ty::AssocKind,
crate::ty::Placeholder<crate::ty::BoundRegionKind>,
crate::ty::ClosureKind,
crate::ty::FreeRegion,
2 changes: 1 addition & 1 deletion compiler/rustc_mir_build/src/thir/pattern/check_match.rs
Original file line number Diff line number Diff line change
@@ -951,7 +951,7 @@ fn adt_defined_here<'p, 'tcx>(
let mut span: MultiSpan =
if spans.is_empty() { def_span.into() } else { spans.clone().into() };

span.push_span_label(def_span, String::new());
span.push_span_label(def_span, "");
for pat in spans {
span.push_span_label(pat, "not covered");
}
12 changes: 11 additions & 1 deletion compiler/rustc_mir_transform/src/simplify.rs
Original file line number Diff line number Diff line change
@@ -315,7 +315,7 @@ pub fn remove_dead_blocks<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
/// with `0` executions.
///
/// If there are no live `Counter` `Coverage` statements remaining, we remove
/// dead `Coverage` statements along with the dead blocks. Since at least one
/// `Coverage` statements along with the dead blocks. Since at least one
/// counter per function is required by LLVM (and necessary, to add the
/// `function_hash` to the counter's call to the LLVM intrinsic
/// `instrprof.increment()`).
@@ -342,6 +342,16 @@ fn save_unreachable_coverage(
}
}

for block in &mut basic_blocks.raw[..first_dead_block] {
for statement in &mut block.statements {
let StatementKind::Coverage(_) = &statement.kind else { continue };
let instance = statement.source_info.scope.inlined_instance(source_scopes);
if !live.contains(&instance) {
statement.make_nop();
}
}
}

if live.is_empty() {
return;
}
3 changes: 1 addition & 2 deletions compiler/rustc_resolve/src/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -565,8 +565,7 @@ impl<'a> Resolver<'a> {
} else if let Some(sp) = sm.generate_fn_name_span(span) {
err.span_label(
sp,
"try adding a local generic parameter in this method instead"
.to_string(),
"try adding a local generic parameter in this method instead",
);
} else {
err.help("try using a local generic parameter instead");
11 changes: 0 additions & 11 deletions compiler/rustc_span/src/source_map.rs
Original file line number Diff line number Diff line change
@@ -586,17 +586,6 @@ impl SourceMap {
}
}

/// Returns whether or not this span points into a file
/// in the current crate. This may be `false` for spans
/// produced by a macro expansion, or for spans associated
/// with the definition of an item in a foreign crate
pub fn is_local_span(&self, sp: Span) -> bool {
let local_begin = self.lookup_byte_offset(sp.lo());
let local_end = self.lookup_byte_offset(sp.hi());
// This might be a weird span that covers multiple files
local_begin.sf.src.is_some() && local_end.sf.src.is_some()
}

pub fn is_span_accessible(&self, sp: Span) -> bool {
self.span_to_source(sp, |src, start_index, end_index| {
Ok(src.get(start_index..end_index).is_some())
Original file line number Diff line number Diff line change
@@ -301,13 +301,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
span = obligation.cause.span;
}
}
if let ObligationCauseCode::CompareImplMethodObligation {
impl_item_def_id,
trait_item_def_id,
}
| ObligationCauseCode::CompareImplTypeObligation {
if let ObligationCauseCode::CompareImplItemObligation {
impl_item_def_id,
trait_item_def_id,
kind: _,
} = *obligation.cause.code()
{
self.report_extra_impl_obligation(
Original file line number Diff line number Diff line change
@@ -2682,11 +2682,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
)
});
}
ObligationCauseCode::CompareImplMethodObligation { trait_item_def_id, .. } => {
ObligationCauseCode::CompareImplItemObligation { trait_item_def_id, kind, .. } => {
let item_name = self.tcx.item_name(trait_item_def_id);
let msg = format!(
"the requirement `{}` appears on the impl method `{}` but not on the \
corresponding trait method",
"the requirement `{}` appears on the `impl`'s {kind} `{}` but not on the \
corresponding trait's {kind}",
predicate, item_name,
);
let sp = self
@@ -2697,7 +2697,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
let mut assoc_span: MultiSpan = sp.into();
assoc_span.push_span_label(
sp,
format!("this trait method doesn't have the requirement `{}`", predicate),
format!("this trait's {kind} doesn't have the requirement `{}`", predicate),
);
if let Some(ident) = self
.tcx
@@ -2708,38 +2708,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
}
err.span_note(assoc_span, &msg);
}
ObligationCauseCode::CompareImplTypeObligation { trait_item_def_id, .. } => {
let item_name = self.tcx.item_name(trait_item_def_id);
let msg = format!(
"the requirement `{}` appears on the associated impl type `{}` but not on the \
corresponding associated trait type",
predicate, item_name,
);
let sp = self.tcx.def_span(trait_item_def_id);
let mut assoc_span: MultiSpan = sp.into();
assoc_span.push_span_label(
sp,
format!(
"this trait associated type doesn't have the requirement `{}`",
predicate,
),
);
if let Some(ident) = self
.tcx
.opt_associated_item(trait_item_def_id)
.and_then(|i| self.tcx.opt_item_ident(i.container.id()))
{
assoc_span.push_span_label(ident.span, "in this trait");
}
err.span_note(assoc_span, &msg);
}
ObligationCauseCode::CompareImplConstObligation => {
err.note(&format!(
"the requirement `{}` appears on the associated impl constant \
but not on the corresponding associated trait constant",
predicate
));
}
ObligationCauseCode::TrivialBound => {
err.help("see issue #48214");
if tcx.sess.opts.unstable_features.is_nightly_build() {
4 changes: 2 additions & 2 deletions compiler/rustc_typeck/src/astconv/errors.rs
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ use rustc_middle::ty;
use rustc_session::parse::feature_err;
use rustc_span::lev_distance::find_best_match_for_name;
use rustc_span::symbol::{sym, Ident};
use rustc_span::{Span, DUMMY_SP};
use rustc_span::{Span, Symbol, DUMMY_SP};

use std::collections::BTreeSet;

@@ -17,7 +17,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
/// the type parameter's name as a placeholder.
pub(crate) fn complain_about_missing_type_params(
&self,
missing_type_params: Vec<String>,
missing_type_params: Vec<Symbol>,
def_id: DefId,
span: Span,
empty_generic_args: bool,
13 changes: 4 additions & 9 deletions compiler/rustc_typeck/src/astconv/mod.rs
Original file line number Diff line number Diff line change
@@ -382,7 +382,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
def_id: DefId,
generic_args: &'a GenericArgs<'a>,
span: Span,
missing_type_params: Vec<String>,
missing_type_params: Vec<Symbol>,
inferred_params: Vec<Span>,
infer_args: bool,
is_object: bool,
@@ -514,7 +514,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// defaults. This will lead to an ICE if we are not
// careful!
if self.default_needs_object_self(param) {
self.missing_type_params.push(param.name.to_string());
self.missing_type_params.push(param.name);
tcx.ty_error().into()
} else {
// This is a default type parameter.
@@ -1150,17 +1150,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
.expect("missing associated type");

if !assoc_item.vis.is_accessible_from(def_scope, tcx) {
let kind = match assoc_item.kind {
ty::AssocKind::Type => "type",
ty::AssocKind::Const => "const",
_ => unreachable!(),
};
tcx.sess
.struct_span_err(
binding.span,
&format!("associated {kind} `{}` is private", binding.item_name),
&format!("{} `{}` is private", assoc_item.kind, binding.item_name),
)
.span_label(binding.span, &format!("private associated {kind}"))
.span_label(binding.span, &format!("private {}", assoc_item.kind))
.emit();
}
tcx.check_stability(assoc_item.def_id, Some(hir_ref_id), binding.span, None);
6 changes: 3 additions & 3 deletions compiler/rustc_typeck/src/check/_match.rs
Original file line number Diff line number Diff line change
@@ -488,17 +488,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ty::Binder::dummy(ty::PredicateKind::Trait(ty::TraitPredicate {
trait_ref: ty::TraitRef {
def_id: t.def_id(),
substs: self.infcx.tcx.mk_substs_trait(outer_ty, &[]),
substs: self.tcx.mk_substs_trait(outer_ty, &[]),
},
constness: t.constness,
polarity: t.polarity,
}));
let obl = Obligation::new(
o.cause.clone(),
self.param_env,
pred.to_predicate(self.infcx.tcx),
pred.to_predicate(self.tcx),
);
suggest_box &= self.infcx.predicate_must_hold_modulo_regions(&obl);
suggest_box &= self.predicate_must_hold_modulo_regions(&obl);
if !suggest_box {
// We've encountered some obligation that didn't hold, so the
// return expression can't just be boxed. We don't need to
2 changes: 1 addition & 1 deletion compiler/rustc_typeck/src/check/callee.rs
Original file line number Diff line number Diff line change
@@ -376,7 +376,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.param_env,
*predicate,
);
let result = self.infcx.evaluate_obligation(&obligation);
let result = self.evaluate_obligation(&obligation);
self.tcx
.sess
.struct_span_err(
10 changes: 5 additions & 5 deletions compiler/rustc_typeck/src/check/closure.rs
Original file line number Diff line number Diff line change
@@ -96,7 +96,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.tcx.typeck_root_def_id(expr_def_id.to_def_id()),
);

let tupled_upvars_ty = self.infcx.next_ty_var(TypeVariableOrigin {
let tupled_upvars_ty = self.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::ClosureSynthetic,
span: self.tcx.hir().span(expr.hir_id),
});
@@ -141,7 +141,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

// Create a type variable (for now) to represent the closure kind.
// It will be unified during the upvar inference phase (`upvar.rs`)
None => self.infcx.next_ty_var(TypeVariableOrigin {
None => self.next_ty_var(TypeVariableOrigin {
// FIXME(eddyb) distinguish closure kind inference variables from the rest.
kind: TypeVariableOriginKind::ClosureSynthetic,
span: expr.span,
@@ -531,7 +531,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
//
// [c1]: https://github.com/rust-lang/rust/pull/45072#issuecomment-341089706
// [c2]: https://github.com/rust-lang/rust/pull/45072#issuecomment-341096796
self.infcx.commit_if_ok(|_| {
self.commit_if_ok(|_| {
let mut all_obligations = vec![];

// The liberated version of this signature should be a subtype
@@ -544,7 +544,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expected_sigs.liberated_sig.inputs(), // `liberated_sig` is E'.
) {
// Instantiate (this part of..) S to S', i.e., with fresh variables.
let supplied_ty = self.infcx.replace_bound_vars_with_fresh_vars(
let supplied_ty = self.replace_bound_vars_with_fresh_vars(
hir_ty.span,
LateBoundRegionConversionTime::FnCall,
supplied_sig.inputs().rebind(supplied_ty),
@@ -557,7 +557,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
all_obligations.extend(obligations);
}

let supplied_output_ty = self.infcx.replace_bound_vars_with_fresh_vars(
let supplied_output_ty = self.replace_bound_vars_with_fresh_vars(
decl.output.span(),
LateBoundRegionConversionTime::FnCall,
supplied_sig.output(),
8 changes: 4 additions & 4 deletions compiler/rustc_typeck/src/check/coercion.rs
Original file line number Diff line number Diff line change
@@ -241,13 +241,13 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
make_adjustments: impl FnOnce(Ty<'tcx>) -> Vec<Adjustment<'tcx>>,
) -> CoerceResult<'tcx> {
debug!("coerce_from_inference_variable(a={:?}, b={:?})", a, b);
assert!(a.is_ty_var() && self.infcx.shallow_resolve(a) == a);
assert!(self.infcx.shallow_resolve(b) == b);
assert!(a.is_ty_var() && self.shallow_resolve(a) == a);
assert!(self.shallow_resolve(b) == b);

if b.is_ty_var() {
// Two unresolved type variables: create a `Coerce` predicate.
let target_ty = if self.use_lub {
self.infcx.next_ty_var(TypeVariableOrigin {
self.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::LatticeVariable,
span: self.cause.span,
})
@@ -991,7 +991,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.autoderef(rustc_span::DUMMY_SP, expr_ty).nth(1).and_then(|(deref_ty, _)| {
self.infcx
.type_implements_trait(
self.infcx.tcx.lang_items().deref_mut_trait()?,
self.tcx.lang_items().deref_mut_trait()?,
expr_ty,
ty::List::empty(),
self.param_env,
42 changes: 26 additions & 16 deletions compiler/rustc_typeck/src/check/compare_method.rs
Original file line number Diff line number Diff line change
@@ -90,9 +90,10 @@ fn compare_predicate_entailment<'tcx>(
let mut cause = ObligationCause::new(
impl_m_span,
impl_m_hir_id,
ObligationCauseCode::CompareImplMethodObligation {
ObligationCauseCode::CompareImplItemObligation {
impl_item_def_id: impl_m.def_id.expect_local(),
trait_item_def_id: trait_m.def_id,
kind: impl_m.kind,
},
);

@@ -223,9 +224,10 @@ fn compare_predicate_entailment<'tcx>(
let cause = ObligationCause::new(
span,
impl_m_hir_id,
ObligationCauseCode::CompareImplMethodObligation {
ObligationCauseCode::CompareImplItemObligation {
impl_item_def_id: impl_m.def_id.expect_local(),
trait_item_def_id: trait_m.def_id,
kind: impl_m.kind,
},
);
ocx.register_obligation(traits::Obligation::new(cause, param_env, predicate));
@@ -1079,7 +1081,11 @@ pub(crate) fn compare_const_impl<'tcx>(
let mut cause = ObligationCause::new(
impl_c_span,
impl_c_hir_id,
ObligationCauseCode::CompareImplConstObligation,
ObligationCauseCode::CompareImplItemObligation {
impl_item_def_id: impl_c.def_id.expect_local(),
trait_item_def_id: trait_c.def_id,
kind: impl_c.kind,
},
);

// There is no "body" here, so just pass dummy id.
@@ -1212,15 +1218,6 @@ fn compare_type_predicate_entailment<'tcx>(
// `ObligationCause` (and the `FnCtxt`). This is what
// `regionck_item` expects.
let impl_ty_hir_id = tcx.hir().local_def_id_to_hir_id(impl_ty.def_id.expect_local());
let cause = ObligationCause::new(
impl_ty_span,
impl_ty_hir_id,
ObligationCauseCode::CompareImplTypeObligation {
impl_item_def_id: impl_ty.def_id.expect_local(),
trait_item_def_id: trait_ty.def_id,
},
);

debug!("compare_type_predicate_entailment: trait_to_impl_substs={:?}", trait_to_impl_substs);

// The predicates declared by the impl definition, the trait and the
@@ -1239,20 +1236,33 @@ fn compare_type_predicate_entailment<'tcx>(
Reveal::UserFacing,
hir::Constness::NotConst,
);
let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause.clone());
let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause);
tcx.infer_ctxt().enter(|infcx| {
let ocx = ObligationCtxt::new(&infcx);

debug!("compare_type_predicate_entailment: caller_bounds={:?}", param_env.caller_bounds());

let mut selcx = traits::SelectionContext::new(&infcx);

for predicate in impl_ty_own_bounds.predicates {
assert_eq!(impl_ty_own_bounds.predicates.len(), impl_ty_own_bounds.spans.len());
for (span, predicate) in
std::iter::zip(impl_ty_own_bounds.spans, impl_ty_own_bounds.predicates)
{
let cause = ObligationCause::misc(span, impl_ty_hir_id);
let traits::Normalized { value: predicate, obligations } =
traits::normalize(&mut selcx, param_env, normalize_cause.clone(), predicate);
traits::normalize(&mut selcx, param_env, cause, predicate);

let cause = ObligationCause::new(
span,
impl_ty_hir_id,
ObligationCauseCode::CompareImplItemObligation {
impl_item_def_id: impl_ty.def_id.expect_local(),
trait_item_def_id: trait_ty.def_id,
kind: impl_ty.kind,
},
);
ocx.register_obligations(obligations);
ocx.register_obligation(traits::Obligation::new(cause.clone(), param_env, predicate));
ocx.register_obligation(traits::Obligation::new(cause, param_env, predicate));
}

// Check that all obligations are satisfied by the implementation's
19 changes: 17 additions & 2 deletions compiler/rustc_typeck/src/check/demand.rs
Original file line number Diff line number Diff line change
@@ -287,6 +287,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expr_ty: Ty<'tcx>,
) {
if let ty::Adt(expected_adt, substs) = expected.kind() {
if let hir::ExprKind::Field(base, ident) = expr.kind {
let base_ty = self.typeck_results.borrow().expr_ty(base);
if self.can_eq(self.param_env, base_ty, expected).is_ok()
&& let Some(base_span) = base.span.find_ancestor_inside(expr.span)
{
err.span_suggestion_verbose(
expr.span.with_lo(base_span.hi()),
format!("consider removing the tuple struct field `{ident}`"),
"",
Applicability::MaybeIncorrect,
);
return
}
}

// If the expression is of type () and it's the return expression of a block,
// we suggest adding a separate return expression instead.
// (To avoid things like suggesting `Ok(while .. { .. })`.)
@@ -815,7 +830,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
hir::ExprKind::AddrOf(hir::BorrowKind::Ref, _, ref expr),
_,
&ty::Ref(_, checked, _),
) if self.infcx.can_sub(self.param_env, checked, expected).is_ok() => {
) if self.can_sub(self.param_env, checked, expected).is_ok() => {
// We have `&T`, check if what was expected was `T`. If so,
// we may want to suggest removing a `&`.
if sm.is_imported(expr.span) {
@@ -959,7 +974,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

// For this suggestion to make sense, the type would need to be `Copy`,
// or we have to be moving out of a `Box<T>`
if self.infcx.type_is_copy_modulo_regions(self.param_env, expected, sp)
if self.type_is_copy_modulo_regions(self.param_env, expected, sp)
// FIXME(compiler-errors): We can actually do this if the checked_ty is
// `steps` layers of boxes, not just one, but this is easier and most likely.
|| (checked_ty.is_box() && steps == 1)
2 changes: 1 addition & 1 deletion compiler/rustc_typeck/src/check/expr.rs
Original file line number Diff line number Diff line change
@@ -2235,7 +2235,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
base: &'tcx hir::Expr<'tcx>,
ty: Ty<'tcx>,
) {
let output_ty = match self.infcx.get_impl_future_output_ty(ty) {
let output_ty = match self.get_impl_future_output_ty(ty) {
Some(output_ty) => self.resolve_vars_if_possible(output_ty),
_ => return,
};
16 changes: 8 additions & 8 deletions compiler/rustc_typeck/src/check/fallback.rs
Original file line number Diff line number Diff line change
@@ -218,9 +218,9 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
.diverging_type_vars
.borrow()
.iter()
.map(|&ty| self.infcx.shallow_resolve(ty))
.map(|&ty| self.shallow_resolve(ty))
.filter_map(|ty| ty.ty_vid())
.map(|vid| self.infcx.root_var(vid))
.map(|vid| self.root_var(vid))
.collect();
debug!(
"calculate_diverging_fallback: diverging_type_vars={:?}",
@@ -236,7 +236,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
let mut diverging_vids = vec![];
let mut non_diverging_vids = vec![];
for unsolved_vid in unsolved_vids {
let root_vid = self.infcx.root_var(unsolved_vid);
let root_vid = self.root_var(unsolved_vid);
debug!(
"calculate_diverging_fallback: unsolved_vid={:?} root_vid={:?} diverges={:?}",
unsolved_vid,
@@ -271,7 +271,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
// variables. (Note that this set consists of "root variables".)
let mut roots_reachable_from_non_diverging = DepthFirstSearch::new(&coercion_graph);
for &non_diverging_vid in &non_diverging_vids {
let root_vid = self.infcx.root_var(non_diverging_vid);
let root_vid = self.root_var(non_diverging_vid);
if roots_reachable_from_diverging.visited(root_vid) {
continue;
}
@@ -294,15 +294,15 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
diverging_fallback.reserve(diverging_vids.len());
for &diverging_vid in &diverging_vids {
let diverging_ty = self.tcx.mk_ty_var(diverging_vid);
let root_vid = self.infcx.root_var(diverging_vid);
let root_vid = self.root_var(diverging_vid);
let can_reach_non_diverging = coercion_graph
.depth_first_search(root_vid)
.any(|n| roots_reachable_from_non_diverging.visited(n));

let mut relationship = ty::FoundRelationships { self_in_trait: false, output: false };

for (vid, rel) in relationships.iter() {
if self.infcx.root_var(*vid) == root_vid {
if self.root_var(*vid) == root_vid {
relationship.self_in_trait |= rel.self_in_trait;
relationship.output |= rel.output;
}
@@ -387,12 +387,12 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
})
.collect();
debug!("create_coercion_graph: coercion_edges={:?}", coercion_edges);
let num_ty_vars = self.infcx.num_ty_vars();
let num_ty_vars = self.num_ty_vars();
VecGraph::new(num_ty_vars, coercion_edges)
}

/// If `ty` is an unresolved type variable, returns its root vid.
fn root_vid(&self, ty: Ty<'tcx>) -> Option<ty::TyVid> {
Some(self.infcx.root_var(self.infcx.shallow_resolve(ty).ty_vid()?))
Some(self.root_var(self.shallow_resolve(ty).ty_vid()?))
}
}
14 changes: 7 additions & 7 deletions compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
@@ -185,20 +185,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if !method.substs.is_empty() {
let method_generics = self.tcx.generics_of(method.def_id);
if !method_generics.params.is_empty() {
let user_type_annotation = self.infcx.probe(|_| {
let user_type_annotation = self.probe(|_| {
let user_substs = UserSubsts {
substs: InternalSubsts::for_item(self.tcx, method.def_id, |param, _| {
let i = param.index as usize;
if i < method_generics.parent_count {
self.infcx.var_for_def(DUMMY_SP, param)
self.var_for_def(DUMMY_SP, param)
} else {
method.substs[i]
}
}),
user_self_ty: None, // not relevant here
};

self.infcx.canonicalize_user_type_annotation(UserType::TypeOf(
self.canonicalize_user_type_annotation(UserType::TypeOf(
method.def_id,
user_substs,
))
@@ -236,7 +236,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
debug!("fcx {}", self.tag());

if Self::can_contain_user_lifetime_bounds((substs, user_self_ty)) {
let canonicalized = self.infcx.canonicalize_user_type_annotation(UserType::TypeOf(
let canonicalized = self.canonicalize_user_type_annotation(UserType::TypeOf(
def_id,
UserSubsts { substs, user_self_ty },
));
@@ -480,7 +480,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
debug!("to_ty_saving_user_provided_ty: ty={:?}", ty);

if Self::can_contain_user_lifetime_bounds(ty) {
let c_ty = self.infcx.canonicalize_response(UserType::Ty(ty));
let c_ty = self.canonicalize_response(UserType::Ty(ty));
debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty);
self.typeck_results.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty);
}
@@ -764,7 +764,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if let ty::subst::GenericArgKind::Type(ty) = ty.unpack()
&& let ty::Opaque(def_id, _) = *ty.kind()
&& let Some(def_id) = def_id.as_local()
&& self.infcx.opaque_type_origin(def_id, DUMMY_SP).is_some() {
&& self.opaque_type_origin(def_id, DUMMY_SP).is_some() {
return None;
}
}
@@ -826,7 +826,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} else {
self.tcx.bound_type_of(def_id)
};
let substs = self.infcx.fresh_substs_for_item(span, def_id);
let substs = self.fresh_substs_for_item(span, def_id);
let ty = item_ty.subst(self.tcx, substs);

self.write_resolution(hir_id, Ok((def_kind, def_id)));
22 changes: 7 additions & 15 deletions compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
@@ -1520,21 +1520,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// ```
fn get_expr_coercion_span(&self, expr: &hir::Expr<'_>) -> rustc_span::Span {
let check_in_progress = |elem: &hir::Expr<'_>| {
self.in_progress_typeck_results
.and_then(|typeck_results| typeck_results.borrow().node_type_opt(elem.hir_id))
.and_then(|ty| {
if ty.is_never() {
None
} else {
Some(match elem.kind {
// Point at the tail expression when possible.
hir::ExprKind::Block(block, _) => {
block.expr.map_or(block.span, |e| e.span)
}
_ => elem.span,
})
}
})
self.typeck_results.borrow().node_type_opt(elem.hir_id).filter(|ty| !ty.is_never()).map(
|_| match elem.kind {
// Point at the tail expression when possible.
hir::ExprKind::Block(block, _) => block.expr.map_or(block.span, |e| e.span),
_ => elem.span,
},
)
};

if let hir::ExprKind::If(_, _, Some(el)) = expr.kind {
4 changes: 2 additions & 2 deletions compiler/rustc_typeck/src/check/method/probe.rs
Original file line number Diff line number Diff line change
@@ -343,15 +343,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
OP: FnOnce(ProbeContext<'a, 'tcx>) -> Result<R, MethodError<'tcx>>,
{
let mut orig_values = OriginalQueryValues::default();
let param_env_and_self_ty = self.infcx.canonicalize_query(
let param_env_and_self_ty = self.canonicalize_query(
ParamEnvAnd { param_env: self.param_env, value: self_ty },
&mut orig_values,
);

let steps = if mode == Mode::MethodCall {
self.tcx.method_autoderef_steps(param_env_and_self_ty)
} else {
self.infcx.probe(|_| {
self.probe(|_| {
// Mode::Path - the deref steps is "trivial". This turns
// our CanonicalQuery into a "trivial" QueryResponse. This
// is a bit inefficient, but I don't think that writing
43 changes: 21 additions & 22 deletions compiler/rustc_typeck/src/check/method/suggest.rs
Original file line number Diff line number Diff line change
@@ -865,27 +865,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.join("\n");
let actual_prefix = actual.prefix_string(self.tcx);
info!("unimplemented_traits.len() == {}", unimplemented_traits.len());
let (primary_message, label) = if unimplemented_traits.len() == 1
&& unimplemented_traits_only
{
unimplemented_traits
.into_iter()
.next()
.map(|(_, (trait_ref, obligation))| {
if trait_ref.self_ty().references_error()
|| actual.references_error()
{
// Avoid crashing.
return (None, None);
}
let OnUnimplementedNote { message, label, .. } =
self.infcx.on_unimplemented_note(trait_ref, &obligation);
(message, label)
})
.unwrap_or((None, None))
} else {
(None, None)
};
let (primary_message, label) =
if unimplemented_traits.len() == 1 && unimplemented_traits_only {
unimplemented_traits
.into_iter()
.next()
.map(|(_, (trait_ref, obligation))| {
if trait_ref.self_ty().references_error()
|| actual.references_error()
{
// Avoid crashing.
return (None, None);
}
let OnUnimplementedNote { message, label, .. } =
self.on_unimplemented_note(trait_ref, &obligation);
(message, label)
})
.unwrap_or((None, None))
} else {
(None, None)
};
let primary_message = primary_message.unwrap_or_else(|| format!(
"the {item_kind} `{item_name}` exists for {actual_prefix} `{ty_str}`, but its trait bounds were not satisfied"
));
@@ -1648,7 +1647,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
call: &hir::Expr<'_>,
span: Span,
) {
let output_ty = match self.infcx.get_impl_future_output_ty(ty) {
let output_ty = match self.get_impl_future_output_ty(ty) {
Some(output_ty) => self.resolve_vars_if_possible(output_ty).skip_binder(),
_ => return,
};
6 changes: 3 additions & 3 deletions compiler/rustc_typeck/src/check/op.rs
Original file line number Diff line number Diff line change
@@ -475,7 +475,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
suggest_deref_binop(lhs_deref_ty);
} else if is_assign == IsAssign::No
&& let Ref(_, lhs_deref_ty, _) = lhs_ty.kind() {
if self.infcx.type_is_copy_modulo_regions(self.param_env, *lhs_deref_ty, lhs_expr.span) {
if self.type_is_copy_modulo_regions(self.param_env, *lhs_deref_ty, lhs_expr.span) {
suggest_deref_binop(*lhs_deref_ty);
}
}
@@ -523,7 +523,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
_ => None,
};

self.infcx.suggest_restricting_param_bound(
self.suggest_restricting_param_bound(
&mut err,
trait_pred,
proj_pred,
@@ -740,7 +740,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
error.obligation.predicate.to_opt_poly_trait_pred()
});
for pred in predicates {
self.infcx.suggest_restricting_param_bound(
self.suggest_restricting_param_bound(
&mut err,
pred,
None,
4 changes: 2 additions & 2 deletions compiler/rustc_typeck/src/check/upvar.rs
Original file line number Diff line number Diff line change
@@ -948,7 +948,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

let root_var_min_capture_list = min_captures.and_then(|m| m.get(&var_hir_id))?;

let ty = self.infcx.resolve_vars_if_possible(self.node_ty(var_hir_id));
let ty = self.resolve_vars_if_possible(self.node_ty(var_hir_id));

let ty = match closure_clause {
hir::CaptureBy::Value => ty, // For move closure the capture kind should be by value
@@ -1064,7 +1064,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
closure_clause: hir::CaptureBy,
var_hir_id: hir::HirId,
) -> Option<FxHashSet<UpvarMigrationInfo>> {
let ty = self.infcx.resolve_vars_if_possible(self.node_ty(var_hir_id));
let ty = self.resolve_vars_if_possible(self.node_ty(var_hir_id));

if !ty.has_significant_drop(self.tcx, self.tcx.param_env(closure_def_id.expect_local())) {
debug!("does not have significant drop");
4 changes: 2 additions & 2 deletions compiler/rustc_typeck/src/check/writeback.rs
Original file line number Diff line number Diff line change
@@ -748,7 +748,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> {
// (e.g. keep `for<'a>` named `for<'a>`).
// This allows NLL to generate error messages that
// refer to the higher-ranked lifetime names written by the user.
EraseEarlyRegions { tcx: self.infcx.tcx }.fold_ty(t)
EraseEarlyRegions { tcx: self.tcx }.fold_ty(t)
}
Err(_) => {
debug!("Resolver::fold_ty: input type `{:?}` not fully resolvable", t);
@@ -766,7 +766,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> {

fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
match self.infcx.fully_resolve(ct) {
Ok(ct) => self.infcx.tcx.erase_regions(ct),
Ok(ct) => self.tcx.erase_regions(ct),
Err(_) => {
debug!("Resolver::fold_const: input const `{:?}` not fully resolvable", ct);
self.report_const_error(ct);
12 changes: 10 additions & 2 deletions compiler/rustc_typeck/src/errors.rs
Original file line number Diff line number Diff line change
@@ -244,7 +244,7 @@ pub struct UnconstrainedOpaqueType {
pub struct MissingTypeParams {
pub span: Span,
pub def_span: Span,
pub missing_type_params: Vec<String>,
pub missing_type_params: Vec<Symbol>,
pub empty_generic_args: bool,
}

@@ -285,7 +285,15 @@ impl<'a> SessionDiagnostic<'a> for MissingTypeParams {
err.span_suggestion(
self.span,
rustc_errors::fluent::typeck::suggestion,
format!("{}<{}>", snippet, self.missing_type_params.join(", ")),
format!(
"{}<{}>",
snippet,
self.missing_type_params
.iter()
.map(|n| n.to_string())
.collect::<Vec<_>>()
.join(", ")
),
Applicability::HasPlaceholders,
);
suggested = true;
14 changes: 14 additions & 0 deletions library/std/src/sys/unix/fs.rs
Original file line number Diff line number Diff line change
@@ -1126,6 +1126,19 @@ impl fmt::Debug for File {
Some(PathBuf::from(OsString::from_vec(buf)))
}

#[cfg(all(target_os = "freebsd", target_arch = "x86_64"))]
fn get_path(fd: c_int) -> Option<PathBuf> {
let info = Box::<libc::kinfo_file>::new_zeroed();
let mut info = unsafe { info.assume_init() };
info.kf_structsize = mem::size_of::<libc::kinfo_file>() as libc::c_int;
let n = unsafe { libc::fcntl(fd, libc::F_KINFO, &mut *info) };
if n == -1 {
return None;
}
let buf = unsafe { CStr::from_ptr(info.kf_path.as_mut_ptr()).to_bytes().to_vec() };
Some(PathBuf::from(OsString::from_vec(buf)))
}

#[cfg(target_os = "vxworks")]
fn get_path(fd: c_int) -> Option<PathBuf> {
let mut buf = vec![0; libc::PATH_MAX as usize];
@@ -1142,6 +1155,7 @@ impl fmt::Debug for File {
target_os = "linux",
target_os = "macos",
target_os = "vxworks",
all(target_os = "freebsd", target_arch = "x86_64"),
target_os = "netbsd"
)))]
fn get_path(_fd: c_int) -> Option<PathBuf> {
Original file line number Diff line number Diff line change
@@ -1,21 +1,28 @@
1| |// Regression test for issue #98833.
2| |// compile-flags: -Zinline-mir
2| |// compile-flags: -Zinline-mir -Cdebug-assertions=off
3| |
4| 1|fn main() {
5| 1| println!("{}", live::<false>());
6| 1|}
7| |
8| |#[inline]
9| 1|fn live<const B: bool>() -> u32 {
10| 1| if B {
11| 0| dead()
12| | } else {
13| 1| 0
14| | }
15| 1|}
16| |
17| |#[inline]
18| 0|fn dead() -> u32 {
19| 0| 42
20| 0|}
6| 1|
7| 1| let f = |x: bool| {
8| | debug_assert!(
9| | x
10| | );
11| 1| };
12| 1| f(false);
13| 1|}
14| |
15| |#[inline]
16| 1|fn live<const B: bool>() -> u32 {
17| 1| if B {
18| 0| dead()
19| | } else {
20| 1| 0
21| | }
22| 1|}
23| |
24| |#[inline]
25| 0|fn dead() -> u32 {
26| 0| 42
27| 0|}

9 changes: 8 additions & 1 deletion src/test/run-make-fulldeps/coverage/inline-dead.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
// Regression test for issue #98833.
// compile-flags: -Zinline-mir
// compile-flags: -Zinline-mir -Cdebug-assertions=off

fn main() {
println!("{}", live::<false>());

let f = |x: bool| {
debug_assert!(
x
);
};
f(false);
}

#[inline]
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ trait Foo {

impl<'a> Foo for &'a () {
const NAME: &'a str = "unit";
//~^ ERROR mismatched types [E0308]
//~^ ERROR const not compatible with trait
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0308]: mismatched types
error[E0308]: const not compatible with trait
--> $DIR/associated-const-impl-wrong-lifetime.rs:7:5
|
LL | const NAME: &'a str = "unit";
Original file line number Diff line number Diff line change
@@ -11,13 +11,13 @@ LL | type Assoc2<T: std::fmt::Display> = Vec<T>;
| +++++++++++++++++++

error[E0276]: impl has stricter requirements than trait
--> $DIR/generic-associated-types-where.rs:22:5
--> $DIR/generic-associated-types-where.rs:22:38
|
LL | type Assoc3<T>;
| -------------- definition of `Assoc3` from trait
...
LL | type Assoc3<T> = Vec<T> where T: Iterator;
| ^^^^^^^^^^^^^^ impl has extra requirement `T: Iterator`
| ^^^^^^^^ impl has extra requirement `T: Iterator`

error: aborting due to 2 previous errors

4 changes: 2 additions & 2 deletions src/test/ui/generic-associated-types/impl_bounds.rs
Original file line number Diff line number Diff line change
@@ -13,9 +13,9 @@ struct Fooy<T>(T);

impl<T> Foo for Fooy<T> {
type A<'a> = (&'a ()) where Self: 'static;
//~^ ERROR `impl` associated type
//~^ ERROR impl has stricter requirements than trait
type B<'a, 'b> = (&'a(), &'b ()) where 'b: 'a;
//~^ ERROR `impl` associated type
//~^ ERROR impl has stricter requirements than trait
//~| ERROR lifetime bound not satisfied
type C = String where Self: Copy;
//~^ ERROR the trait bound `T: Copy` is not satisfied
34 changes: 17 additions & 17 deletions src/test/ui/generic-associated-types/impl_bounds.stderr
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
error: `impl` associated type signature for `A` doesn't match `trait` associated type signature
--> $DIR/impl_bounds.rs:15:5
error[E0276]: impl has stricter requirements than trait
--> $DIR/impl_bounds.rs:15:39
|
LL | type A<'a> where Self: 'a;
| ---------- expected
| ---------- definition of `A` from trait
...
LL | type A<'a> = (&'a ()) where Self: 'static;
| ^^^^^^^^^^ found
| ^^^^^^^ impl has extra requirement `T: 'static`

error: `impl` associated type signature for `B` doesn't match `trait` associated type signature
--> $DIR/impl_bounds.rs:17:5
error[E0276]: impl has stricter requirements than trait
--> $DIR/impl_bounds.rs:17:48
|
LL | type B<'a, 'b> where 'a: 'b;
| -------------- expected
| -------------- definition of `B` from trait
...
LL | type B<'a, 'b> = (&'a(), &'b ()) where 'b: 'a;
| ^^^^^^^^^^^^^^ found
| ^^ impl has extra requirement `'b: 'a`

error[E0478]: lifetime bound not satisfied
--> $DIR/impl_bounds.rs:17:22
@@ -37,24 +37,24 @@ LL | type B<'a, 'b> = (&'a(), &'b ()) where 'b: 'a;
| ^^

error[E0277]: the trait bound `T: Copy` is not satisfied
--> $DIR/impl_bounds.rs:20:5
--> $DIR/impl_bounds.rs:20:33
|
LL | type C = String where Self: Copy;
| ^^^^^^ the trait `Copy` is not implemented for `T`
| ^^^^ the trait `Copy` is not implemented for `T`
|
note: required because of the requirements on the impl of `Copy` for `Fooy<T>`
--> $DIR/impl_bounds.rs:11:10
|
LL | #[derive(Copy, Clone)]
| ^^^^
note: the requirement `Fooy<T>: Copy` appears on the associated impl type `C` but not on the corresponding associated trait type
--> $DIR/impl_bounds.rs:7:5
note: the requirement `Fooy<T>: Copy` appears on the `impl`'s associated type `C` but not on the corresponding trait's associated type
--> $DIR/impl_bounds.rs:7:10
|
LL | trait Foo {
| --- in this trait
...
LL | type C where Self: Clone;
| ^^^^^^ this trait associated type doesn't have the requirement `Fooy<T>: Copy`
| ^ this trait's associated type doesn't have the requirement `Fooy<T>: Copy`
= note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider restricting type parameter `T`
|
@@ -72,14 +72,14 @@ note: required because of the requirements on the impl of `Copy` for `Fooy<T>`
|
LL | #[derive(Copy, Clone)]
| ^^^^
note: the requirement `Fooy<T>: Copy` appears on the impl method `d` but not on the corresponding trait method
note: the requirement `Fooy<T>: Copy` appears on the `impl`'s method `d` but not on the corresponding trait's method
--> $DIR/impl_bounds.rs:8:8
|
LL | trait Foo {
| --- in this trait
...
LL | fn d() where Self: Clone;
| ^ this trait method doesn't have the requirement `Fooy<T>: Copy`
| ^ this trait's method doesn't have the requirement `Fooy<T>: Copy`
= note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider restricting type parameter `T`
|
@@ -88,5 +88,5 @@ LL | impl<T: std::marker::Copy> Foo for Fooy<T> {

error: aborting due to 5 previous errors

Some errors have detailed explanations: E0277, E0478.
For more information about an error, try `rustc --explain E0277`.
Some errors have detailed explanations: E0276, E0277, E0478.
For more information about an error, try `rustc --explain E0276`.
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
error[E0276]: impl has stricter requirements than trait
--> $DIR/issue-47206-where-clause.rs:12:5
--> $DIR/issue-47206-where-clause.rs:12:38
|
LL | type Assoc3<T>;
| -------------- definition of `Assoc3` from trait
...
LL | type Assoc3<T> = Vec<T> where T: Iterator;
| ^^^^^^^^^^^^^^ impl has extra requirement `T: Iterator`
| ^^^^^^^^ impl has extra requirement `T: Iterator`

error: aborting due to previous error

Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@ trait Foo {
}
impl Foo for () {
type Assoc<'a, 'b> = () where 'a: 'b;
//~^ `impl` associated type
//~^ impl has stricter requirements than trait
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
error: `impl` associated type signature for `Assoc` doesn't match `trait` associated type signature
--> $DIR/missing-where-clause-on-trait.rs:9:5
error[E0276]: impl has stricter requirements than trait
--> $DIR/missing-where-clause-on-trait.rs:9:39
|
LL | type Assoc<'a, 'b>;
| ------------------ expected
| ------------------ definition of `Assoc` from trait
...
LL | type Assoc<'a, 'b> = () where 'a: 'b;
| ^^^^^^^^^^^^^^^^^^ found
| ^^ impl has extra requirement `'a: 'b`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0276`.
Original file line number Diff line number Diff line change
@@ -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);
}
Original file line number Diff line number Diff line change
@@ -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);
}
Original file line number Diff line number Diff line change
@@ -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`.
2 changes: 1 addition & 1 deletion src/test/ui/nll/trait-associated-constant.rs
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@ struct FailStruct { }

impl<'a: 'b, 'b, 'c> Anything<'a, 'b> for FailStruct {
const AC: Option<&'c str> = None;
//~^ ERROR: mismatched types
//~^ ERROR: const not compatible with trait
}

struct OKStruct2 { }
2 changes: 1 addition & 1 deletion src/test/ui/nll/trait-associated-constant.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0308]: mismatched types
error[E0308]: const not compatible with trait
--> $DIR/trait-associated-constant.rs:21:5
|
LL | const AC: Option<&'c str> = None;
14 changes: 11 additions & 3 deletions src/tools/tidy/src/deps.rs
Original file line number Diff line number Diff line change
@@ -55,12 +55,13 @@ const EXCEPTIONS_CRANELIFT: &[(&str, &str)] = &[
("cranelift-codegen-shared", "Apache-2.0 WITH LLVM-exception"),
("cranelift-entity", "Apache-2.0 WITH LLVM-exception"),
("cranelift-frontend", "Apache-2.0 WITH LLVM-exception"),
("cranelift-isle", "Apache-2.0 WITH LLVM-exception"),
("cranelift-jit", "Apache-2.0 WITH LLVM-exception"),
("cranelift-module", "Apache-2.0 WITH LLVM-exception"),
("cranelift-native", "Apache-2.0 WITH LLVM-exception"),
("cranelift-object", "Apache-2.0 WITH LLVM-exception"),
("mach", "BSD-2-Clause"),
("regalloc", "Apache-2.0 WITH LLVM-exception"),
("regalloc2", "Apache-2.0 WITH LLVM-exception"),
("target-lexicon", "Apache-2.0 WITH LLVM-exception"),
];

@@ -258,22 +259,27 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[
];

const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[
"ahash",
"anyhow",
"ar",
"autocfg",
"bitflags",
"byteorder",
"cfg-if",
"cranelift-bforest",
"cranelift-codegen",
"cranelift-codegen-meta",
"cranelift-codegen-shared",
"cranelift-entity",
"cranelift-frontend",
"cranelift-isle",
"cranelift-jit",
"cranelift-module",
"cranelift-native",
"cranelift-object",
"crc32fast",
"fxhash",
"getrandom",
"gimli",
"hashbrown",
"indexmap",
@@ -284,11 +290,13 @@ const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[
"memchr",
"object",
"once_cell",
"regalloc",
"regalloc2",
"region",
"rustc-hash",
"slice-group-by",
"smallvec",
"target-lexicon",
"version_check",
"wasi",
"winapi",
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",